--- /dev/null
+version: 2.1
+
+parameters:
+ run_downstream_tests:
+ type: boolean
+ default: false
+
+# CircleCI doesn't handle large file sets properly for local builds
+# https://github.com/CircleCI-Public/circleci-cli/issues/281#issuecomment-472808051
+localCheckout: &localCheckout
+ run: |-
+ git config --global --add safe.directory /tmp/_circleci_local_build_repo
+ PROJECT_PATH=$(cd ${CIRCLE_WORKING_DIRECTORY}; pwd)
+ mkdir -p ${PROJECT_PATH}
+ cd /tmp/_circleci_local_build_repo
+ git ls-files -z | xargs -0 -s 2090860 tar -c | tar -x -C ${PROJECT_PATH}
+ cp -a /tmp/_circleci_local_build_repo/.git ${PROJECT_PATH}
+jobs:
+ ubuntu:
+ description: A template for running OQS-OpenSSL tests on x64 Ubuntu Docker VMs
+ parameters:
+ IMAGE:
+ description: "docker image to use."
+ type: string
+ CMAKE_ARGS:
+ description: "Arguments to pass to CMake."
+ type: string
+ OPENSSL_PREINSTALL:
+ description: "OpenSSL version preinstalled."
+ type: string
+ OQS_PROVIDER_BUILD_STATIC:
+ description: "Build oqsprovider as a static library"
+ type: boolean
+ default: false
+ docker:
+ - image: << parameters.IMAGE >>
+ steps:
+ - setup_remote_docker
+ - checkout # change this from "checkout" to "*localCheckout" when running CircleCI locally
+ - run:
+ name: Clone and build liboqs (<< parameters.CMAKE_ARGS >>)
+ command: |
+ git clone --depth 1 --branch main https://github.com/open-quantum-safe/liboqs.git &&
+ cd liboqs && mkdir _build && cd _build &&
+ cmake -GNinja << parameters.CMAKE_ARGS >> -DCMAKE_INSTALL_PREFIX=$(pwd)/../../.local .. && ninja install &&
+ cd .. && cd .. && pwd
+ - when:
+ condition:
+ not:
+ equal: [ openssl@3, << parameters.OPENSSL_PREINSTALL >> ]
+ steps:
+ - run:
+ name: Clone and build OpenSSL(3)
+ command: |
+ git clone --branch master git://git.openssl.org/openssl.git openssl &&
+ cd openssl && ./config --prefix=$(echo $(pwd)/../.local) && make -j 18 && make install_sw && cd ..
+ - run:
+ name: Build OQS-OpenSSL provider (<< parameters.CMAKE_ARGS >> with QSC encoding support)
+ command: |
+ mkdir _build && cd _build && cmake -GNinja << parameters.CMAKE_ARGS >> -DUSE_ENCODING_LIB=ON -DOPENSSL_ROOT_DIR=$(pwd)/../.local -DCMAKE_PREFIX_PATH=$(pwd)/../.local .. && ninja && cd ..
+ - when:
+ condition:
+ equal: [ openssl@3, << parameters.OPENSSL_PREINSTALL >> ]
+ steps:
+ - run:
+ name: Build OQS-OpenSSL provider (<< parameters.CMAKE_ARGS >> with QSC encoding support)
+ command: |
+ oqsprovider_cmake_args="<< parameters.CMAKE_ARGS >>"
+ if << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ oqsprovider_cmake_args="${oqsprovider_cmake_args} -DOQS_PROVIDER_BUILD_STATIC=ON"
+ fi
+ mkdir _build && cd _build && cmake -GNinja ${oqsprovider_cmake_args} -DUSE_ENCODING_LIB=ON -DCMAKE_PREFIX_PATH=$(pwd)/../.local .. && ninja && cd ..
+ - run:
+ name: Run tests
+ command: |
+ if << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ ctest --test-dir _build/
+ else
+ ./scripts/runtests.sh -V
+ fi
+ - run:
+ name: Run tests (with encodings, positive and negative test)
+ command: |
+ if ! << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ ./scripts/runtests_encodings.sh -V > log
+ if [ grep "Skipping testing of buggy OpenSSL" -eq 1 ]; then
+ cat log
+ ! OQS_ENCODING_DILITHIUM2=foo OQS_ENCODING_DILITHIUM2_ALGNAME=bar ./scripts/runtests.sh -V
+ else
+ cat log
+ fi
+ fi
+ - run:
+ name: Build OQS-OpenSSL provider (<< parameters.CMAKE_ARGS >>) with NOPUBKEY_IN_PRIVKEY and QSC encoding support
+ command: |
+ rm -rf _build && mkdir _build && cd _build && cmake -GNinja << parameters.CMAKE_ARGS >> -DNOPUBKEY_IN_PRIVKEY=ON -DUSE_ENCODING_LIB=ON -DOPENSSL_ROOT_DIR=$(pwd)/../.local -DCMAKE_PREFIX_PATH=$(pwd)/../.local .. && ninja
+ - run:
+ name: Run tests (-DNOPUBKEY_IN_PRIVKEY=ON)
+ command: |
+ if << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ ctest --test-dir _build/
+ else
+ ./scripts/runtests.sh -V
+ fi
+ - run:
+ name: Run tests (-DNOPUBKEY_IN_PRIVKEY=ON, with encodings, positive and negative test)
+ command: |
+ if ! << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ ./scripts/runtests_encodings.sh -V
+ if [ grep "Skipping testing of buggy OpenSSL" -eq 1 ]; then
+ cat log
+ ! OQS_ENCODING_DILITHIUM2=foo OQS_ENCODING_DILITHIUM2_ALGNAME=bar ./scripts/runtests.sh -V
+ else
+ cat log
+ fi
+ fi
+
+ macOS:
+ description: A template for running tests on macOS
+ parameters:
+ CMAKE_ARGS:
+ description: "Arguments to pass to CMake."
+ type: string
+ OPENSSL_PREINSTALL:
+ description: "OpenSSL version preinstalled."
+ type: string
+ OQS_PROVIDER_BUILD_STATIC:
+ description: "Build oqsprovider as a static library"
+ type: boolean
+ default: false
+ macos:
+ xcode: "13.2.1"
+ steps:
+ - checkout # change this from "checkout" to "*localCheckout" when running CircleCI locally
+ - run:
+ name: Install dependencies
+ command: brew install cmake ninja << parameters.OPENSSL_PREINSTALL >>
+ - run:
+ name: Get system information
+ command: sysctl -a | grep machdep.cpu && cc --version
+ - run:
+ name: Clone and build liboqs
+ command: |
+ git clone --depth 1 --branch main https://github.com/open-quantum-safe/liboqs.git &&
+ export LIBOQS_INSTALLPATH=$(pwd)/.local && cd liboqs && mkdir _build && cd _build &&
+ export OPENSSL_INSTALL="$(brew --prefix << parameters.OPENSSL_PREINSTALL >> || echo "")"
+ cmake -GNinja -DOPENSSL_ROOT_DIR="${OPENSSL_INSTALL}" -DCMAKE_INSTALL_PREFIX=$LIBOQS_INSTALLPATH << parameters.CMAKE_ARGS >> .. && ninja install &&
+ cd .. && cd .. && echo "export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$LIBOQS_INSTALLPATH/lib" >> "$BASH_ENV"
+ - when:
+ condition:
+ not:
+ equal: [ openssl@3.1, << parameters.OPENSSL_PREINSTALL >> ]
+ steps:
+ - run:
+ name: Clone and build OpenSSL(3) master
+ command: |
+ git clone --branch master git://git.openssl.org/openssl.git openssl &&
+ cd openssl && ./config --prefix=$(echo $(pwd)/../.local) && make -j 18 && make install_sw && cd ..
+ - run:
+ name: Build OQS-OpenSSL provider
+ command: |
+ oqsprovider_cmake_args="<< parameters.CMAKE_ARGS >>"
+ if << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ oqsprovider_cmake_args="${oqsprovider_cmake_args} -DOQS_PROVIDER_BUILD_STATIC=ON"
+ fi
+ export OPENSSL_INSTALL=$(pwd)/.local && mkdir _build && cd _build && cmake -GNinja -DOPENSSL_ROOT_DIR=$OPENSSL_INSTALL -DCMAKE_PREFIX_PATH=$(pwd)/../.local ${oqsprovider_cmake_args} .. && ninja && echo "export OPENSSL_INSTALL=$OPENSSL_INSTALL" >> "$BASH_ENV"
+ - when:
+ condition:
+ equal: [ openssl@3.1, << parameters.OPENSSL_PREINSTALL >> ]
+ steps:
+ - run:
+ name: Build OQS-OpenSSL provider
+ command: |
+ export OPENSSL_INSTALL="$(brew --prefix << parameters.OPENSSL_PREINSTALL >>)"
+ mkdir _build && cd _build && liboqs_DIR=`pwd`/../.local cmake -GNinja -DOPENSSL_ROOT_DIR="${OPENSSL_INSTALL}" .. && ninja && echo "export OPENSSL_INSTALL=$OPENSSL_INSTALL" >> "$BASH_ENV" && cd .. && echo "export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:$OPENSSL_INSTALL/lib" >> "$BASH_ENV"
+ - run:
+ name: Run tests
+ command: |
+ if << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ ctest --test-dir _build/ --output-on-failure
+ else
+ ./scripts/runtests.sh -V
+ fi
+ - run:
+ name: Build OQS-OpenSSL provider with QSC encoding support
+ command: |
+ oqsprovider_cmake_args="<< parameters.CMAKE_ARGS >>"
+ if << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ oqsprovider_cmake_args="${oqsprovider_cmake_args} -DOQS_PROVIDER_BUILD_STATIC=ON"
+ fi
+ rm -rf _build && mkdir _build && cd _build && cmake -GNinja -DUSE_ENCODING_LIB=ON -DOPENSSL_ROOT_DIR=$OPENSSL_INSTALL -DCMAKE_PREFIX_PATH=$(pwd)/../.local ${oqsprovider_cmake_args} .. && ninja
+ - run:
+ name: Run tests
+ command: |
+ if << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ ctest --test-dir _build/ --output-on-failure
+ else
+ ./scripts/runtests.sh -V
+ fi
+ - run:
+ name: Run tests (with encodings)
+ command: |
+ if ! << parameters.OQS_PROVIDER_BUILD_STATIC >> ; then
+ ./scripts/runtests_encodings.sh -V > log
+ if [ grep "Skipping testing of buggy OpenSSL" -eq 1 ]; then
+ cat log
+ ! OQS_ENCODING_DILITHIUM2=foo OQS_ENCODING_DILITHIUM2_ALGNAME=bar ./scripts/runtests.sh -V
+ else
+ cat log
+ fi
+ fi
+
+ trigger-downstream-ci:
+ docker:
+ - image: cimg/base:2020.01
+# Re-enable iff docker enforces rate limitations without auth:
+# auth:
+# username: $DOCKER_LOGIN
+# password: $DOCKER_PASSWORD
+ steps:
+ - run:
+ name: Trigger oqs-demos CI
+ command: |
+ curl --silent \
+ --write-out "\n%{response_code}\n" \
+ --user ${BUILD_TRIGGER_TOKEN}: \
+ --request POST \
+ --header "Content-Type: application/json" \
+ -d '{ "branch": "main", "parameters": { "new_openssl_commit": true } }' \
+ https://circleci.com/api/v2/project/gh/open-quantum-safe/oqs-demos/pipeline | tee curl_out \
+ && grep -q "201" curl_out
+
+workflows:
+ version: 2.1
+ build:
+ jobs:
+ - ubuntu:
+ name: ubuntu-focal
+ context: openquantumsafe
+ IMAGE: openquantumsafe/ci-ubuntu-focal-x86_64:latest
+ CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=OFF
+ OPENSSL_PREINSTALL: openssl@1
+ - ubuntu:
+ name: ubuntu-jammy
+ context: openquantumsafe
+ IMAGE: openquantumsafe/ci-ubuntu-jammy:latest
+ CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_ALGS_ENABLED=STD
+ OPENSSL_PREINSTALL: openssl@3
+ - ubuntu:
+ name: ubuntu-jammy-static
+ context: openquantumsafe
+ IMAGE: openquantumsafe/ci-ubuntu-jammy:latest
+ OQS_PROVIDER_BUILD_STATIC: true
+ CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_ALGS_ENABLED=STD
+ OPENSSL_PREINSTALL: openssl@3
+ - macOS:
+ name: macOS-noopenssl
+ CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_USE_OPENSSL=OFF
+ OPENSSL_PREINSTALL: openssl
+ - macOS:
+ name: macOS-shared
+ CMAKE_ARGS: -DBUILD_SHARED_LIBS=ON -DOQS_DIST_BUILD=OFF -DOQS_ENABLE_KEM_CLASSIC_MCELIECE=OFF
+ OPENSSL_PREINSTALL: openssl@3.1
+ - macOS:
+ name: macOS-static
+ OQS_PROVIDER_BUILD_STATIC: true
+ CMAKE_ARGS: -DOQS_DIST_BUILD=OFF -DOQS_ENABLE_KEM_CLASSIC_MCELIECE=OFF
+ OPENSSL_PREINSTALL: openssl@3.1
+ on-main-branch:
+ when:
+ or:
+ - equal: [ main , << pipeline.git.branch >> ]
+ - equal: [ true , << pipeline.parameters.run_downstream_tests >> ]
+ jobs:
+ - trigger-downstream-ci:
+ context: openquantumsafe
+
--- /dev/null
+# https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
+
+* @baentsch
--- /dev/null
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Environment (please complete the following information):**
+ - OS: [e.g. Ubuntu 20]
+ - OpenSSL version [e.g., 3.2.0-dev]
+ - oqsprovider version [e.g. 0.4.0]
+
+Please run the following commands to obtain the version information:
+ - For OpenSSL: `openssl version`
+ - For oqsprovider: `openssl list -providers`
+
+If `oqsprovider` is not listed as active, be sure to first follow all
+[USAGE guidance](https://github.com/open-quantum-safe/oqs-provider/blob/main/USAGE.md).
+
+**Additional context**
+Add any other context about the problem here.
+
+**Hints**
+To exclude a build/setup error, please consider running your test
+commands to reproduce the problem in our [pre-build docker image](https://hub.docker.com/repository/docker/openquantumsafe/oqs-ossl3/general),
+e.g. as such: `docker run -it openquantumsafe/oqs-ossl3` and
+provide full command input and output traces in the bug report.
+
--- /dev/null
+<!-- Please give a brief explanation of the purpose of this pull request. -->
+
+<!-- Does this PR resolve any issue? If so, please reference it using automatic-closing keywords like "Fixes #123." -->
+
+<!-- Once your pull request is ready for review and passing continuous integration tests, please convert from a draft PR to a normal PR, and request a review from one of the OQS core team members. -->
--- /dev/null
+name: Linux tests
+
+on:
+ push:
+ branches: [ '*' ]
+ pull_request:
+ branches: [ "main" ]
+
+jobs:
+
+ linux_intel:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ ossl-branch: [openssl-3.1.0, master]
+ include:
+ - name: alpine
+ container: openquantumsafe/ci-alpine-amd64:latest
+# focal test done on CircleCI - save the compute cycles here until CCI is dropped
+# - name: focal
+# container: openquantumsafe/ci-ubuntu-focal-x86_64:latest
+ - name: jammy
+ container: openquantumsafe/ci-ubuntu-jammy:latest
+ container:
+ image: ${{ matrix.container }}
+ env:
+ MAKE_PARAMS: "-j 18"
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+ - name: Full build
+ run: OPENSSL_BRANCH=${{ matrix.ossl-branch }} ./scripts/fullbuild.sh
+ - name: Enable sibling oqsprovider for testing
+ run: cd _build/lib && ln -s oqsprovider.so oqsprovider2.so
+ - name: Test
+ run: ./scripts/runtests.sh -V
+ - name: Verify nothing changes on re-generate code
+ run: |
+ git config --global user.name "ciuser" && \
+ git config --global user.email "ci@openquantumsafe.org" && \
+ git config --global --add safe.directory `pwd` && \
+ export LIBOQS_SRC_DIR=`pwd`/liboqs && \
+ ! pip3 install -r oqs-template/requirements.txt 2>&1 | grep ERROR && \
+ python3 oqs-template/generate.py && \
+ ! git status | grep modified
+ - name: Build .deb install package
+ run: cpack
+ working-directory: _build
+ - name: Retain .deb installer
+ uses: actions/upload-artifact@v3
+ with:
+ name: oqsprovider-x64
+ path: _build/*.deb
+
+
--- /dev/null
+name: MacOS tests
+
+on: [pull_request, push]
+
+permissions:
+ contents: read
+
+jobs:
+ macos:
+# Run a job for each of the specified os configs:
+ strategy:
+ matrix:
+ os:
+ - macos-13
+ - macos-12
+ - macos-11
+# eventually build for other alg sets, if CCI use is discontinued
+ params:
+ - oqsconfig: -DOQS_ALGS_ENABLED=STD
+ runs-on: ${{matrix.os}}
+ env:
+# Don't overwhelm github CI VMs:
+ MAKE_PARAMS: -j 4
+ steps:
+ - name: Checkout provider
+ uses: actions/checkout@v3
+ - name: Checkout openssl
+ uses: actions/checkout@v3
+ with:
+ set-safe-directory: true
+ repository: openssl/openssl
+ path: openssl
+ - name: checkout liboqs
+ uses: actions/checkout@v3
+ with:
+ set-safe-directory: true
+ repository: open-quantum-safe/liboqs
+ ref: main
+ path: liboqs
+ - name: Retrieve OpenSSL32 from cache
+ id: cache-openssl32
+ uses: actions/cache@v3
+ with:
+ path: .localopenssl32
+ key: ${{ runner.os }}-openssl32
+ - name: Build openssl3 if not cached
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ run: pwd && ./config --prefix=`pwd`/../.localopenssl32 && make $MAKE_PARAMS && make install_sw install_ssldirs
+ working-directory: openssl
+ - name: Save OpenSSL
+ id: cache-openssl-save
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ .localopenssl32
+ key: ${{ runner.os }}-openssl32
+ - name: build liboqs
+ run: |
+ cmake -DOPENSSL_ROOT_DIR=../.localopenssl32 -DCMAKE_INSTALL_PREFIX=../.localliboqs ${{ matrix.params.oqsconfig }} -S . -B _build
+ cmake --build _build
+ cmake --install _build
+ working-directory: liboqs
+ - name: build oqs-provider
+ run: liboqs_DIR=.localliboqs cmake -DOPENSSL_ROOT_DIR=.localopenssl32 -S . -B _build && cmake --build _build
+ - name: Check Openssl providers
+ run: OPENSSL_MODULES=_build/lib .localopenssl32/bin/openssl list -providers -provider oqsprovider -provider default
+ - name: Run tests
+ run: PATH=../.localopenssl32/bin:$PATH ctest -V
+ working-directory: _build
+ # Try brew install of head: If error message below appears, build and test passed successfully
+ - name: brew install test
+ run: brew install --HEAD --formula -s oqsprovider.rb 2>&1 | grep "Empty installation"
+ working-directory: scripts
+ - name: Retain oqsprovider.dylib
+ uses: actions/upload-artifact@v3
+ with:
+ name: oqs-provider-${{matrix.os}}-x64
+ path: _build/lib/oqsprovider.dylib
--- /dev/null
+name: Tests using distributions with OpenSSL3 binaries
+
+on:
+ push:
+ branches: [ '*' ]
+ pull_request:
+ branches: [ "main" ]
+
+jobs:
+
+ macos_intel:
+ runs-on: macos-13
+ strategy:
+ fail-fast: false
+ steps:
+ - name: Install prerequisites
+ run: brew install liboqs
+ - name: Checkout oqsprovider code
+ uses: actions/checkout@v2
+ - name: Build oqsprovider
+ run: cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -S . -B _build && cmake --build _build
+ - name: Test oqsprovider
+ run: ctest --parallel 5 --test-dir _build
+
+ linux_intel:
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: jammy
+ container: ubuntu:latest
+ container:
+ image: ${{ matrix.container }}
+ env:
+ MAKE_PARAMS: "-j 18"
+ steps:
+ - name: Update container
+ run: apt update && apt install -y cmake ninja-build gcc libssl-dev git
+ - name: Checkout code
+ uses: actions/checkout@v2
+ - name: Full build
+ run: ./scripts/fullbuild.sh
+ - name: Test
+ run: ./scripts/runtests.sh -V
+
--- /dev/null
+name: Windows tests
+
+on: [pull_request, push]
+
+permissions:
+ contents: read
+
+jobs:
+ cygwin:
+# Run a job for each of the specified target architectures:
+ strategy:
+ matrix:
+ os:
+ - windows-2019
+# - windows-2022
+ platform:
+ - arch: win64
+ oqsconfig: -DOQS_ALGS_ENABLED=STD
+# - arch: win32
+# config: --strict-warnings no-fips enable-quic
+ runs-on: ${{matrix.os}}
+ env:
+ CYGWIN_NOWINPATH: 1
+ SHELLOPTS: igncr
+# Don't overwhelm github CI VMs:
+ MAKE_PARAMS: -j 4
+ steps:
+ - name: Checkout provider
+ uses: actions/checkout@v3
+ - name: Checkout openssl
+ uses: actions/checkout@v3
+ with:
+ set-safe-directory: true
+ repository: openssl/openssl
+ path: openssl
+ - name: checkout liboqs
+ uses: actions/checkout@v3
+ with:
+ set-safe-directory: true
+ repository: open-quantum-safe/liboqs
+ ref: main
+ path: liboqs
+ - name: Install cygwin
+ uses: cygwin/cygwin-install-action@master
+ with:
+ packages: perl git ninja gcc-core cmake make
+ - name: Retrieve OpenSSL32 from cache
+ id: cache-openssl32
+ uses: actions/cache@v3
+ with:
+ path: c:\cygwin\opt\openssl32
+ key: ${{ runner.os }}-cygwinopenssl32
+ - name: Set installpath
+ run: |
+ echo "IP=$(cygpath -u $PWD)/.local" >> "$env:GITHUB_ENV"
+ - name: build liboqs
+ run: |
+ which cmake
+ cmake --version
+ gcc --version
+ mkdir _build
+ cd _build
+ cmake -GNinja -DOPENSSL_ROOT_DIR=/opt/openssl32 -DCMAKE_INSTALL_PREFIX="${{ env.IP }}" ${{ matrix.platform.oqsconfig }} -DCMAKE_C_COMPILER=gcc ..
+ ninja
+ ninja install
+ working-directory: liboqs
+ - name: Build openssl3 if not cached
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ run: bash -c "./config --prefix=/opt/openssl32 ${{ matrix.platform.config }} && perl configdata.pm --dump && make $MAKE_PARAMS && make install_sw"
+ working-directory: openssl
+ - name: Check OpenSSL install3
+ run: dir c:\cygwin\opt\openssl32
+ - name: Save OpenSSL
+ id: cache-openssl-save
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ c:\cygwin\opt\openssl32
+ key: ${{ runner.os }}-cygwinopenssl32
+ - name: build oqs-provider
+ run: bash -c "git config --global --add safe.directory $(cygpath -u $PWD) && liboqs_DIR='${{ env.IP }}' cmake -GNinja -DCMAKE_C_COMPILER=gcc -DOPENSSL_ROOT_DIR=/opt/openssl32 -S . -B _build && cd _build && ninja && cd .."
+ - name: Check Openssl providers
+ run: bash -c "OPENSSL_MODULES=_build/lib /opt/openssl32/bin/openssl list -providers -provider oqsprovider -provider default"
+ - name: Run tests
+ run: bash -c "echo $PATH && PATH=/opt/openssl32/bin:/usr/bin ctest -V"
+ working-directory: _build
+ - name: Retain oqsprovider.dll
+ uses: actions/upload-artifact@v3
+ with:
+ name: oqs-provider-cygwin
+ path: D:/a/oqs-provider/oqs-provider/_build/bin/oqsprovider.dll
+
+ msvc:
+# Run a job for each of the specified target architectures:
+ strategy:
+ matrix:
+ os:
+ - windows-2019
+# - windows-2022
+ platform:
+ - arch: win64
+ oqsconfig: -DOQS_ALGS_ENABLED=STD
+ osslconfig: no-shared no-fips VC-WIN64A-masm
+# - arch: win32
+# oqsconfig: -DOQS_ALGS_ENABLED=STD
+# osslconfig: --strict-warnings no-fips enable-quic
+ runs-on: ${{matrix.os}}
+ steps:
+ - name: Restore OpenSSL32 cache
+ id: cache-openssl32
+ uses: actions/cache@v3
+ with:
+ path: c:\openssl32
+ key: ${{ runner.os }}-msvcopenssl32
+ - uses: actions/checkout@v3
+ - name: Checkout OpenSSL master
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ uses: actions/checkout@v3
+ with:
+ set-safe-directory: true
+ repository: openssl/openssl
+ path: openssl
+ - uses: actions/checkout@v3
+ with:
+ set-safe-directory: true
+ repository: open-quantum-safe/liboqs
+ path: liboqs
+ - uses: ilammy/msvc-dev-cmd@v1
+ with:
+ arch: ${{ matrix.platform.arch }}
+ - name: Setup nasm for OpenSSL build
+ uses: ilammy/setup-nasm@v1
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ with:
+ platform: ${{ matrix.platform.arch }}
+ - name: Setup perl for OpenSSl build
+ uses: shogo82148/actions-setup-perl@v1
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+# OQS_USE_OPENSSL=OFF by default on Win32
+# if cmake --build fails, try explicit
+# cd _build && msbuild ALL_BUILD.vcxproj -p:Configuration=Release
+# fails: cmake -DCMAKE_C_FLAGS="/wd5105" -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_INSTALL_PREFIX="c:\liboqs" ${{ matrix.platform.oqsconfig }} -S . -B _build
+# cd _build && msbuild ALL_BUILD.vcxproj -p:Configuration=Release && cd ..
+# cmake --install _build
+ - name: build liboqs
+ run: |
+ cmake --version
+ mkdir build
+ cd build
+ cmake -GNinja -DCMAKE_C_FLAGS="/wd5105" -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_INSTALL_PREFIX="c:\liboqs" ${{ matrix.platform.oqsconfig }} -DOQS_DIST_BUILD=ON ..
+ ninja
+ ninja install
+ working-directory: liboqs
+ - name: prepare the OpenSSL build directory
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ run: mkdir _build
+ working-directory: openssl
+ - name: OpenSSL config
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ working-directory: openssl\_build
+ run: |
+ perl ..\Configure --banner=Configured --prefix=c:\openssl32 no-makedepend ${{ matrix.platform.osslconfig }}
+ perl configdata.pm --dump
+ - name: OpenSSL build
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ working-directory: openssl\_build
+ run: nmake /S
+# Skip testing openssl for now
+# - name: test
+# working-directory: openssl\_build
+# run: nmake test VERBOSE_FAILURE=yes TESTS=-test_fuzz* HARNESS_JOBS=4
+ - name: OpenSSL install
+ # Run on 64 bit only as 32 bit is slow enough already
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ run: |
+ mkdir c:\openssl32
+ nmake install_sw
+ working-directory: openssl\_build
+ - name: Save OpenSSL
+ id: cache-openssl-save
+ if: steps.cache-openssl32.outputs.cache-hit != 'true'
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ c:\openssl32
+ key: ${{ runner.os }}-msvcopenssl32
+ - name: build oqs-provider
+ run: |
+ cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="/wd5105" -DOPENSSL_ROOT_DIR="c:\openssl32" -Dliboqs_DIR="c:\liboqs\lib\cmake\liboqs" -S . -B _build
+ cd _build
+ ninja
+ - name: Run tests
+ run: |
+ ctest -V --test-dir _build
+ - name: Retain oqsprovider.dll
+ uses: actions/upload-artifact@v3
+ with:
+ name: oqs-provider-msvc
+ path: D:/a/oqs-provider/oqs-provider/_build/lib/oqsprovider.dll
+
--- /dev/null
+# checked out OSSL variants
+openssl*/*
+openssl
+# checked out liboqs
+liboqs
+# installed SW
+.local
+# build directory
+_build
+# generated from openssl src:
+test/ssltestlib.c
+test/ssltestlib.h
+test/oqs_test_groups
+# test artifacts
+tmp
+interop.log
+# pycache
+oqs-template/__pycache__
+
+# Visual Studio Code
+.vscode
+
+# Jetbrains IDEs
+.idea
+
+# MacOS
+.DS_Store
+
--- /dev/null
+Algorithms supported
+====================
+
+This page lists all quantum-safe algorithms supported by oqs-provider.
+
+Some algorithms by default may not be enabled for use in the master code-generator template file.
+
+As standardization for these algorithms within TLS is not done, all TLS code points/IDs can be changed from their default values to values set by environment variables. This facilitates interoperability testing with TLS1.3 implementations that use different IDs.
+
+# Code points / algorithm IDs
+
+<!--- OQS_TEMPLATE_FRAGMENT_IDS_START -->
+|Algorithm name | default ID | enabled | environment variable |
+|---------------|:----------:|:-------:|----------------------|
+| frodo640aes | 0x0200 | Yes | OQS_CODEPOINT_FRODO640AES |
+| p256_frodo640aes | 0x2F00 | Yes | OQS_CODEPOINT_P256_FRODO640AES |
+| x25519_frodo640aes | 0x2F80 | Yes | OQS_CODEPOINT_X25519_FRODO640AES |
+| frodo640shake | 0x0201 | Yes | OQS_CODEPOINT_FRODO640SHAKE |
+| p256_frodo640shake | 0x2F01 | Yes | OQS_CODEPOINT_P256_FRODO640SHAKE |
+| x25519_frodo640shake | 0x2F81 | Yes | OQS_CODEPOINT_X25519_FRODO640SHAKE |
+| frodo976aes | 0x0202 | Yes | OQS_CODEPOINT_FRODO976AES |
+| p384_frodo976aes | 0x2F02 | Yes | OQS_CODEPOINT_P384_FRODO976AES |
+| x448_frodo976aes | 0x2F82 | Yes | OQS_CODEPOINT_X448_FRODO976AES |
+| frodo976shake | 0x0203 | Yes | OQS_CODEPOINT_FRODO976SHAKE |
+| p384_frodo976shake | 0x2F03 | Yes | OQS_CODEPOINT_P384_FRODO976SHAKE |
+| x448_frodo976shake | 0x2F83 | Yes | OQS_CODEPOINT_X448_FRODO976SHAKE |
+| frodo1344aes | 0x0204 | Yes | OQS_CODEPOINT_FRODO1344AES |
+| p521_frodo1344aes | 0x2F04 | Yes | OQS_CODEPOINT_P521_FRODO1344AES |
+| frodo1344shake | 0x0205 | Yes | OQS_CODEPOINT_FRODO1344SHAKE |
+| p521_frodo1344shake | 0x2F05 | Yes | OQS_CODEPOINT_P521_FRODO1344SHAKE |
+| kyber512 | 0x023A | Yes | OQS_CODEPOINT_KYBER512 |
+| p256_kyber512 | 0x2F3A | Yes | OQS_CODEPOINT_P256_KYBER512 |
+| x25519_kyber512 | 0x2F39 | Yes | OQS_CODEPOINT_X25519_KYBER512 |
+| kyber768 | 0x023C | Yes | OQS_CODEPOINT_KYBER768 |
+| p384_kyber768 | 0x2F3C | Yes | OQS_CODEPOINT_P384_KYBER768 |
+| x448_kyber768 | 0x2F90 | Yes | OQS_CODEPOINT_X448_KYBER768 |
+| x25519_kyber768 | 0x6399 | Yes | OQS_CODEPOINT_X25519_KYBER768 |
+| p256_kyber768 | 0x639A | Yes | OQS_CODEPOINT_P256_KYBER768 |
+| kyber1024 | 0x023D | Yes | OQS_CODEPOINT_KYBER1024 |
+| p521_kyber1024 | 0x2F3D | Yes | OQS_CODEPOINT_P521_KYBER1024 |
+| bikel1 | 0x0241 | Yes | OQS_CODEPOINT_BIKEL1 |
+| p256_bikel1 | 0x2F41 | Yes | OQS_CODEPOINT_P256_BIKEL1 |
+| x25519_bikel1 | 0x2FAE | Yes | OQS_CODEPOINT_X25519_BIKEL1 |
+| bikel3 | 0x0242 | Yes | OQS_CODEPOINT_BIKEL3 |
+| p384_bikel3 | 0x2F42 | Yes | OQS_CODEPOINT_P384_BIKEL3 |
+| x448_bikel3 | 0x2FAF | Yes | OQS_CODEPOINT_X448_BIKEL3 |
+| bikel5 | 0x0243 | Yes | OQS_CODEPOINT_BIKEL5 |
+| p521_bikel5 | 0x2F43 | Yes | OQS_CODEPOINT_P521_BIKEL5 |
+| hqc128 | 0x022C | Yes | OQS_CODEPOINT_HQC128 |
+| p256_hqc128 | 0x2F2C | Yes | OQS_CODEPOINT_P256_HQC128 |
+| x25519_hqc128 | 0x2FAC | Yes | OQS_CODEPOINT_X25519_HQC128 |
+| hqc192 | 0x022D | Yes | OQS_CODEPOINT_HQC192 |
+| p384_hqc192 | 0x2F2D | Yes | OQS_CODEPOINT_P384_HQC192 |
+| x448_hqc192 | 0x2FAD | Yes | OQS_CODEPOINT_X448_HQC192 |
+| hqc256 | 0x022E | Yes | OQS_CODEPOINT_HQC256 |
+| p521_hqc256 | 0x2F2E | Yes | OQS_CODEPOINT_P521_HQC256 |
+| dilithium2 | 0xfea0 |Yes| OQS_CODEPOINT_DILITHIUM2
+| p256_dilithium2 | 0xfea1 |Yes| OQS_CODEPOINT_P256_DILITHIUM2
+| rsa3072_dilithium2 | 0xfea2 |Yes| OQS_CODEPOINT_RSA3072_DILITHIUM2
+| dilithium3 | 0xfea3 |Yes| OQS_CODEPOINT_DILITHIUM3
+| p384_dilithium3 | 0xfea4 |Yes| OQS_CODEPOINT_P384_DILITHIUM3
+| dilithium5 | 0xfea5 |Yes| OQS_CODEPOINT_DILITHIUM5
+| p521_dilithium5 | 0xfea6 |Yes| OQS_CODEPOINT_P521_DILITHIUM5
+| falcon512 | 0xfeae |Yes| OQS_CODEPOINT_FALCON512
+| p256_falcon512 | 0xfeaf |Yes| OQS_CODEPOINT_P256_FALCON512
+| rsa3072_falcon512 | 0xfeb0 |Yes| OQS_CODEPOINT_RSA3072_FALCON512
+| falcon1024 | 0xfeb1 |Yes| OQS_CODEPOINT_FALCON1024
+| p521_falcon1024 | 0xfeb2 |Yes| OQS_CODEPOINT_P521_FALCON1024
+| sphincssha2128fsimple | 0xfeb3 |Yes| OQS_CODEPOINT_SPHINCSSHA2128FSIMPLE
+| p256_sphincssha2128fsimple | 0xfeb4 |Yes| OQS_CODEPOINT_P256_SPHINCSSHA2128FSIMPLE
+| rsa3072_sphincssha2128fsimple | 0xfeb5 |Yes| OQS_CODEPOINT_RSA3072_SPHINCSSHA2128FSIMPLE
+| sphincssha2128ssimple | 0xfeb6 |Yes| OQS_CODEPOINT_SPHINCSSHA2128SSIMPLE
+| p256_sphincssha2128ssimple | 0xfeb7 |Yes| OQS_CODEPOINT_P256_SPHINCSSHA2128SSIMPLE
+| rsa3072_sphincssha2128ssimple | 0xfeb8 |Yes| OQS_CODEPOINT_RSA3072_SPHINCSSHA2128SSIMPLE
+| sphincssha2192fsimple | 0xfeb9 |Yes| OQS_CODEPOINT_SPHINCSSHA2192FSIMPLE
+| p384_sphincssha2192fsimple | 0xfeba |Yes| OQS_CODEPOINT_P384_SPHINCSSHA2192FSIMPLE
+| sphincssha2192ssimple | 0xfebb |No| OQS_CODEPOINT_SPHINCSSHA2192SSIMPLE
+| p384_sphincssha2192ssimple | 0xfebc |No| OQS_CODEPOINT_P384_SPHINCSSHA2192SSIMPLE
+| sphincssha2256fsimple | 0xfebd |No| OQS_CODEPOINT_SPHINCSSHA2256FSIMPLE
+| p521_sphincssha2256fsimple | 0xfebe |No| OQS_CODEPOINT_P521_SPHINCSSHA2256FSIMPLE
+| sphincssha2256ssimple | 0xfec0 |No| OQS_CODEPOINT_SPHINCSSHA2256SSIMPLE
+| p521_sphincssha2256ssimple | 0xfec1 |No| OQS_CODEPOINT_P521_SPHINCSSHA2256SSIMPLE
+| sphincsshake128fsimple | 0xfec2 |Yes| OQS_CODEPOINT_SPHINCSSHAKE128FSIMPLE
+| p256_sphincsshake128fsimple | 0xfec3 |Yes| OQS_CODEPOINT_P256_SPHINCSSHAKE128FSIMPLE
+| rsa3072_sphincsshake128fsimple | 0xfec4 |Yes| OQS_CODEPOINT_RSA3072_SPHINCSSHAKE128FSIMPLE
+| sphincsshake128ssimple | 0xfec5 |No| OQS_CODEPOINT_SPHINCSSHAKE128SSIMPLE
+| p256_sphincsshake128ssimple | 0xfec6 |No| OQS_CODEPOINT_P256_SPHINCSSHAKE128SSIMPLE
+| rsa3072_sphincsshake128ssimple | 0xfec7 |No| OQS_CODEPOINT_RSA3072_SPHINCSSHAKE128SSIMPLE
+| sphincsshake192fsimple | 0xfec8 |No| OQS_CODEPOINT_SPHINCSSHAKE192FSIMPLE
+| p384_sphincsshake192fsimple | 0xfec9 |No| OQS_CODEPOINT_P384_SPHINCSSHAKE192FSIMPLE
+| sphincsshake192ssimple | 0xfeca |No| OQS_CODEPOINT_SPHINCSSHAKE192SSIMPLE
+| p384_sphincsshake192ssimple | 0xfecb |No| OQS_CODEPOINT_P384_SPHINCSSHAKE192SSIMPLE
+| sphincsshake256fsimple | 0xfecc |No| OQS_CODEPOINT_SPHINCSSHAKE256FSIMPLE
+| p521_sphincsshake256fsimple | 0xfecd |No| OQS_CODEPOINT_P521_SPHINCSSHAKE256FSIMPLE
+| sphincsshake256ssimple | 0xfece |No| OQS_CODEPOINT_SPHINCSSHAKE256SSIMPLE
+| p521_sphincsshake256ssimple | 0xfecf |No| OQS_CODEPOINT_P521_SPHINCSSHAKE256SSIMPLE
+<!--- OQS_TEMPLATE_FRAGMENT_IDS_END -->
+
+Changing code points
+--------------------
+
+In order to dynamically change the code point of any one algorithm, the respective
+environment variable listed above has to be set to the `INT`eger value of the
+desired code point. For example, as Cloudflare has chosen `0xfe30` as the code
+point for their hybrid X25519_kyber512 implementation, the following command
+can be used to successfully confirm interoperability between the oqs-provider
+and the Cloudflare infrastructure using this hybrid classic/quantum-safe algorithm:
+
+```
+OQS_CODEPOINT_X25519_KYBER512=65072 ./openssl/apps/openssl s_client -groups x25519_kyber512 -connect cloudflare.com:443 -provider-path _build/oqsprov -provider oqsprovider -provider default
+```
+
+# OIDs
+
+Along the same lines as the code points, X.509 OIDs may be subject to change
+prior to final standardization. The environment variables below permit
+adapting the OIDs of all supported signature algorithms as per the table below.
+
+<!--- OQS_TEMPLATE_FRAGMENT_OIDS_START -->
+|Algorithm name | default OID | enabled | environment variable |
+|---------------|:-----------------:|:-------:|----------------------|
+| dilithium2 | 1.3.6.1.4.1.2.267.7.4.4 |Yes| OQS_OID_DILITHIUM2
+| p256_dilithium2 | 1.3.9999.2.7.1 |Yes| OQS_OID_P256_DILITHIUM2
+| rsa3072_dilithium2 | 1.3.9999.2.7.2 |Yes| OQS_OID_RSA3072_DILITHIUM2
+| dilithium3 | 1.3.6.1.4.1.2.267.7.6.5 |Yes| OQS_OID_DILITHIUM3
+| p384_dilithium3 | 1.3.9999.2.7.3 |Yes| OQS_OID_P384_DILITHIUM3
+| dilithium5 | 1.3.6.1.4.1.2.267.7.8.7 |Yes| OQS_OID_DILITHIUM5
+| p521_dilithium5 | 1.3.9999.2.7.4 |Yes| OQS_OID_P521_DILITHIUM5
+| falcon512 | 1.3.9999.3.6 |Yes| OQS_OID_FALCON512
+| p256_falcon512 | 1.3.9999.3.7 |Yes| OQS_OID_P256_FALCON512
+| rsa3072_falcon512 | 1.3.9999.3.8 |Yes| OQS_OID_RSA3072_FALCON512
+| falcon1024 | 1.3.9999.3.9 |Yes| OQS_OID_FALCON1024
+| p521_falcon1024 | 1.3.9999.3.10 |Yes| OQS_OID_P521_FALCON1024
+| sphincssha2128fsimple | 1.3.9999.6.4.13 |Yes| OQS_OID_SPHINCSSHA2128FSIMPLE
+| p256_sphincssha2128fsimple | 1.3.9999.6.4.14 |Yes| OQS_OID_P256_SPHINCSSHA2128FSIMPLE
+| rsa3072_sphincssha2128fsimple | 1.3.9999.6.4.15 |Yes| OQS_OID_RSA3072_SPHINCSSHA2128FSIMPLE
+| sphincssha2128ssimple | 1.3.9999.6.4.16 |Yes| OQS_OID_SPHINCSSHA2128SSIMPLE
+| p256_sphincssha2128ssimple | 1.3.9999.6.4.17 |Yes| OQS_OID_P256_SPHINCSSHA2128SSIMPLE
+| rsa3072_sphincssha2128ssimple | 1.3.9999.6.4.18 |Yes| OQS_OID_RSA3072_SPHINCSSHA2128SSIMPLE
+| sphincssha2192fsimple | 1.3.9999.6.5.10 |Yes| OQS_OID_SPHINCSSHA2192FSIMPLE
+| p384_sphincssha2192fsimple | 1.3.9999.6.5.11 |Yes| OQS_OID_P384_SPHINCSSHA2192FSIMPLE
+| sphincssha2192ssimple | 1.3.9999.6.5.12 |No| OQS_OID_SPHINCSSHA2192SSIMPLE
+| p384_sphincssha2192ssimple | 1.3.9999.6.5.13 |No| OQS_OID_P384_SPHINCSSHA2192SSIMPLE
+| sphincssha2256fsimple | 1.3.9999.6.6.10 |No| OQS_OID_SPHINCSSHA2256FSIMPLE
+| p521_sphincssha2256fsimple | 1.3.9999.6.6.11 |No| OQS_OID_P521_SPHINCSSHA2256FSIMPLE
+| sphincssha2256ssimple | 1.3.9999.6.6.12 |No| OQS_OID_SPHINCSSHA2256SSIMPLE
+| p521_sphincssha2256ssimple | 1.3.9999.6.6.13 |No| OQS_OID_P521_SPHINCSSHA2256SSIMPLE
+| sphincsshake128fsimple | 1.3.9999.6.7.13 |Yes| OQS_OID_SPHINCSSHAKE128FSIMPLE
+| p256_sphincsshake128fsimple | 1.3.9999.6.7.14 |Yes| OQS_OID_P256_SPHINCSSHAKE128FSIMPLE
+| rsa3072_sphincsshake128fsimple | 1.3.9999.6.7.15 |Yes| OQS_OID_RSA3072_SPHINCSSHAKE128FSIMPLE
+| sphincsshake128ssimple | 1.3.9999.6.7.16 |No| OQS_OID_SPHINCSSHAKE128SSIMPLE
+| p256_sphincsshake128ssimple | 1.3.9999.6.7.17 |No| OQS_OID_P256_SPHINCSSHAKE128SSIMPLE
+| rsa3072_sphincsshake128ssimple | 1.3.9999.6.7.18 |No| OQS_OID_RSA3072_SPHINCSSHAKE128SSIMPLE
+| sphincsshake192fsimple | 1.3.9999.6.8.10 |No| OQS_OID_SPHINCSSHAKE192FSIMPLE
+| p384_sphincsshake192fsimple | 1.3.9999.6.8.11 |No| OQS_OID_P384_SPHINCSSHAKE192FSIMPLE
+| sphincsshake192ssimple | 1.3.9999.6.8.12 |No| OQS_OID_SPHINCSSHAKE192SSIMPLE
+| p384_sphincsshake192ssimple | 1.3.9999.6.8.13 |No| OQS_OID_P384_SPHINCSSHAKE192SSIMPLE
+| sphincsshake256fsimple | 1.3.9999.6.9.10 |No| OQS_OID_SPHINCSSHAKE256FSIMPLE
+| p521_sphincsshake256fsimple | 1.3.9999.6.9.11 |No| OQS_OID_P521_SPHINCSSHAKE256FSIMPLE
+| sphincsshake256ssimple | 1.3.9999.6.9.12 |No| OQS_OID_SPHINCSSHAKE256SSIMPLE
+| p521_sphincsshake256ssimple | 1.3.9999.6.9.13 |No| OQS_OID_P521_SPHINCSSHAKE256SSIMPLE
+<!--- OQS_TEMPLATE_FRAGMENT_OIDS_END -->
+
+# Key Encodings
+
+By setting environment variables, oqs-provider can be configured to encode keys (subjectPublicKey and and privateKey ASN.1 structures) according to the following IETF drafts:
+
+- https://datatracker.ietf.org/doc/draft-uni-qsckeys-dilithium/00/
+- https://datatracker.ietf.org/doc/draft-uni-qsckeys-falcon/00/
+- https://datatracker.ietf.org/doc/draft-uni-qsckeys-sphincsplus/00/
+
+<!--- OQS_TEMPLATE_FRAGMENT_ENCODINGS_START -->
+|Environment Variable | Permissible Values |
+| --- | --- |
+|`OQS_ENCODING_DILITHIUM2`|`draft-uni-qsckeys-dilithium-00/sk-pk`|
+|`OQS_ENCODING_DILITHIUM3`|`draft-uni-qsckeys-dilithium-00/sk-pk`|
+|`OQS_ENCODING_DILITHIUM5`|`draft-uni-qsckeys-dilithium-00/sk-pk`|
+|`OQS_ENCODING_FALCON512`|`draft-uni-qsckeys-falcon-00/sk-pk`|
+|`OQS_ENCODING_FALCON1024`|`draft-uni-qsckeys-falcon-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHA2128FSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHA2128SSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHA2192FSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHA2192SSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHA2256FSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHA2256SSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHAKE128FSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHAKE128SSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHAKE192FSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHAKE192SSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHAKE256FSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+|`OQS_ENCODING_SPHINCSSHAKE256SSIMPLE`|`draft-uni-qsckeys-sphincsplus-00/sk-pk`|
+<!--- OQS_TEMPLATE_FRAGMENT_ENCODINGS_END -->
+
+By setting `OQS_ENCODING_<ALGORITHM>_ALGNAME` environment variables, the corresponding algorithm names are set. The names are documented in the [`qsc_encoding.h`](https://github.com/Quantum-Safe-Collaboration/qsc-key-encoder/blob/main/include/qsc_encoding.h) header file of the encoder library.
+
+If no environment variable is set, or if an unknown value is set, the default is 'no' encoding, meaning that key serialization uses the 'raw' keys of the crypto implementations. If unknown values are set as environment variables, a run-time error will be raised.
+
+The test script `scripts/runtests_encodings.sh` (instead of `scripts/runtests.sh`) can be used for a test run with all supported encodings activated.
--- /dev/null
+if (WIN32)
+cmake_minimum_required(VERSION 3.20 FATAL_ERROR)
+else()
+cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
+endif()
+project(oqs-provider LANGUAGES C)
+set(OQSPROVIDER_VERSION_TEXT "0.5.1")
+set(CMAKE_C_STANDARD 11)
+set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS ON)
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ message(STATUS "Creating Debug build with OQS-Debug env vars enabled")
+else()
+ message(STATUS "Creating Release build")
+ add_definitions( -DNDEBUG )
+endif()
+
+if(MSVC)
+ set(CMAKE_EXE_LINKER_FLAGS
+ "${CMAKE_EXE_LINKER_FLAGS} /NODEFAULTLIB:LIBCMT")
+ add_definitions(-DOQS_PROVIDER_NOATOMIC)
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+ set(OQS_ADDL_SOCKET_LIBS "ws2_32.lib gdi32.lib crypt32.lib")
+else()
+ add_compile_options(-Wunused-function)
+ set(OQS_ADDL_SOCKET_LIBS "")
+endif()
+
+option(NOPUBKEY_IN_PRIVKEY "Do not include public keys in private key structures/PKCS#8 " OFF)
+if(${NOPUBKEY_IN_PRIVKEY})
+ message(STATUS "Build will not store public keys alongside private keys in PKCS#8 structures")
+ add_compile_definitions( NOPUBKEY_IN_PRIVKEY )
+else()
+ message(STATUS "Build will store public keys in PKCS#8 structures")
+endif()
+option(USE_ENCODING_LIB "Build with external encoding library for SPKI/PKCS#8 " OFF)
+if(${USE_ENCODING_LIB})
+ message(STATUS "Build will include external encoding library for SPKI/PKCS#8")
+ add_compile_definitions( USE_ENCODING_LIB )
+else()
+ message(STATUS "Build will not include external encoding library for SPKI/PKCS#8")
+endif()
+
+option(OQS_PROVIDER_BUILD_STATIC "Build a static library instead of a shared library" OFF)
+if(OQS_PROVIDER_BUILD_STATIC AND BUILD_SHARED_LIBS)
+ message(FATAL_ERROR "`OQS_PROVIDER_BUILD_STATIC` is not compatible with `BUILD_SHARED_LIBS`.")
+endif()
+
+include(CheckLibraryExists)
+include(CheckFunctionExists)
+
+# Add required includes and install locations for openssl
+find_package(OpenSSL 3.0 REQUIRED)
+include_directories(${OPENSSL_INCLUDE_DIR})
+if (WIN32)
+# get_filename_component seems to fail when facing windows paths
+# so use new(er) cmake_path instruction there
+cmake_path(GET OPENSSL_CRYPTO_LIBRARY PARENT_PATH OQS_MODULES_PARENT_PATH)
+cmake_path(APPEND OQS_MODULES_PARENT_PATH "ossl-modules" OUTPUT_VARIABLE OPENSSL_MODULES_PATH)
+else()
+get_filename_component(OPENSSL_LIB_DIR ${OPENSSL_CRYPTO_LIBRARY} DIRECTORY)
+set(OPENSSL_MODULES_PATH ${OPENSSL_LIB_DIR}/ossl-modules)
+endif()
+
+# Add required include for liboqs
+find_package(liboqs REQUIRED)
+get_target_property(LIBOQS_INCLUDE_DIR OQS::oqs INTERFACE_INCLUDE_DIRECTORIES)
+message(STATUS "liboqs found: Include dir at ${LIBOQS_INCLUDE_DIR}")
+include_directories(${LIBOQS_INCLUDE_DIR})
+
+# Hints the compiler on the fact that the provider is being compiled into a static library.
+function(targets_set_static_provider)
+ foreach(target ${ARGN})
+ target_compile_definitions(${target} PRIVATE "OQS_PROVIDER_STATIC")
+ if(NOT target STREQUAL oqsprovider)
+ target_link_libraries(${target} PRIVATE oqsprovider)
+ endif()
+ endforeach()
+endfunction()
+
+# Provider module
+add_subdirectory(oqsprov)
+
+# Testing
+enable_testing()
+add_subdirectory(test)
--- /dev/null
+Configuring oqsprovider
+=======================
+
+This document lists all configuration options for `oqsprovider`.
+
+## Pre-build configuration
+
+Significant parts of this code are generated by the script `oqs-template/generate.py`.
+This script permits integration and activation of all quantum safe
+algorithms made available by [liboqs](https://github.com/open-quantum-safe/liboqs).
+The default configuration is as defined in the [algorithm configuration file](oqs-template/generate.yml).
+
+Any PR changing this default must include all files changed by `generate.py`.
+
+## Build install options
+
+### OPENSSL_ROOT_DIR
+
+Defines a non-standard location for an OpenSSL(v3) installation via `cmake` define.
+By default this value is unset, requiring presence of an OpenSSL3 installation
+in a standard OS deployment location.
+
+### CMAKE_BUILD_TYPE
+
+By setting this `cmake` configuration option to "Release" all debug output is disabled.
+This is the default setting.
+
+### liboqs_DIR
+
+This environment variable must be set to the location of the `liboqs` installation to be
+utilized in the build.
+By default, this is un-set, requiring installation of `liboqs` in a standard
+location for the OS.
+
+### USE_ENCODING_LIB
+
+By setting `-DUSE_ENCODING_LIB=<ON/OFF>` at compile-time, oqs-provider can be
+compiled with with an an external encoding library `qsc-key-encoder`.
+Configuring the encodings is done via environment as described in [ALGORITHMS.md](ALGORITHMS.md).
+The default value is `OFF`.
+
+### NOPUBKEY_IN_PRIVKEY
+
+By setting this to "ON", it can be specified to omit explicitly serializing
+the public key in a `privateKey` structure, e.g., for interoperability testing.
+The default value is `OFF`.
+
+### OQS_PROVIDER_BUILD_STATIC
+
+By setting `-DOQS_PROVIDER_BUILD_STATIC=ON` at compile-time, oqs-provider can be
+compiled as a static library (`oqs-provider.a`).
+When built as a static library, the name of the provider entrypoint is `oqs_provider_init`.
+The provider can be added using the [`OSSL_PROVIDER_add_builtin`](https://www.openssl.org/docs/man3.1/man3/OSSL_PROVIDER_add_builtin.html)
+function:
+
+```c
+#include <openssl/provider.h>
+
+// Entrypoint.
+extern OSSL_provider_init_fn oqs_provider_init;
+
+void load_oqs_provider(OSSL_LIB_CTX *libctx) {
+ int err;
+
+ if (OSSL_PROVIDER_add_builtin(libctx, "oqsprovider", oqs_provider_init) == 1) {
+ if (OSSL_PROVIDER_load(libctx, "oqsprovider") == 1) {
+ fputs("successfully loaded `oqsprovider`.", stderr);
+ } else {
+ fputs("failed to load `oqsprovider`", stderr);
+ }
+ } else {
+ fputs("failed to add the builtin provider `oqsprovider`", stderr);
+ }
+}
+```
+
+> **Warning**
+> `OQS_PROVIDER_BUILD_STATIC` and `BUILD_SHARED_LIBS` are mutually exclusive.
+
+## Convenience build script options
+
+For anyone interested in building the complete software stack
+(`openssl`(v3), `liboqs` and `oqs-provider`) the files `fullbuild.sh`
+and `runtests.sh` in the `scripts` directory cater for that.
+These files can be configured via the following environment variables:
+
+### OPENSSL_INSTALL
+
+Directory of an existing, non-standard OpenSSL binary distribution.
+
+### OPENSSL_BRANCH
+
+Tag of a specific OpenSSL release to be built and used in testing.
+Care is advised setting this to values lower than "3.0.9" due to many known
+code deficiencies related to providers in such old OpenSSL branches.
+
+### LIBOQS_BRANCH
+
+This defines the branch of `liboqs` against which `oqs-provider` is built.
+This can be used, for example, to facilitate a release of `oqsprovider`
+to track an old/stable `liboqs` release.
+Default is "main" (most current code).
+
+### liboqs_DIR
+
+If this environment variable is set, `liboqs` is not being built but
+used from the directory specified in this variable: Both `include`
+and `lib` directories must be present in that location.
+By not setting this variable, `liboqs` is build from source.
+
+### LIBOQS_BRANCH
+
+If set, this environment variable designates the `liboqs` branch to
+be built. If this variable is not set, the "main" branch is built.
+
+### MAKE_PARAMS
+
+This environment variable permits passing parameters to the `make`
+command used to build `openssl`, e.g., "-j 8" to activate 8-fold
+parallel builds to reduce the compilation time on a suitable multicore
+machine.
+
+### OQS_SKIP_TESTS
+
+By setting this tests environment variable, testing of specific
+algorithm families as listed [here](https://github.com/open-quantum-safe/openssl#supported-algorithms)
+can be disabled in testing.
+By default this variable is unset.
+
+Example use:
+
+ OQS_SKIP_TESTS="sphincs" ./scripts/runtests.sh
+
+excludes all algorithms of the "Sphincs" family (speeding up testing significantly).
+
+*Note*: By default, interoperability testing with oqs-openssl111 is no longer
+performed by default but can be manually enabled in the script `scripts/runtests.sh`.
+
+### OPENSSL_CONF
+
+This test environment variable can be used to instruct `openssl` to use a
+configuration file from a non-standard location. Setting this value also
+disables the automation logic built into `runtests.sh`, thus requiring
+knowledge of `openssl` operations when setting it.
+By default this variable is unset.
+
+## LIBOQS configuration options
+
+These are [documented in full here](https://github.com/open-quantum-safe/liboqs/wiki/Customizing-liboqs).
+One option is of particular context here, particularly if building
+`oqs-provider` static, i.e., as a standalone binary not requiring
+presence of `liboqs` during deployment:
+
+### OQS_ALGS_ENABLED
+
+In order to reduce the size of the oqsprovider, it is possible to limit the number
+of algorithms supported, e.g., to the set of NIST standardized algorithms. This is
+facilitated by setting the `liboqs` build option `-DOQS_ALGS_ENABLED=STD` when building
+`liboqs`. The list of algorithms supported by `oqs-provider` is defined by
+the contents of the file `generate.yml` documented in the [pre-build configuration](#pre-build-configuration).
+
+## Runtime options
+
+The `openssl` [property selection mechanism](https://www.openssl.org/docs/manmaster/man7/property.html)
+can be utilized to make run-time algorithm selections.
+
+### oqsprovider.security_bits
+
+It is possible to select only algorithms of a specific bit strength by using
+the openssl property selection mechanism on the key "oqsprovider.security_bits",
+e.g., as such: `openssl list -kem-algorithms -propquery oqsprovider.security_bits=256`.
+The bit strength of hybrid algorithms is always defined by the bit strength
+of the classic algorithm.
+
+
--- /dev/null
+The MIT license, the text of which is below, applies to oqs-provider in general.
+
+Copyright (c) 2016-2021 Open Quantum Safe project
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
--- /dev/null
+UNIX-specific build/install instructions
+========================================
+
+`oqsprovider` is first and foremost being developed and maintained under
+Linux. Therefore, all UNIX-like builds, incl. `cygwin`, should work with
+least problems.
+
+## Dependencies
+
+### OpenSSLv3
+
+OpenSSL (>=3.0.0) is becoming generally available via the various package
+managers and distributions, e.g., via `apt install openssl` or `brew install openssl@3`.
+
+If it is not, please build and install via the instructions [here](https://github.com/openssl/openssl/blob/master/NOTES-UNIX.md).
+
+### liboqs
+
+`liboqs` is available in some select distributions and package managers,
+e.g., via `brew install liboqs` on MacOS, but typically needs to be build
+from source. See instructions [here](https://github.com/open-quantum-safe/liboqs#linuxmacos).
+
+## Build tooling
+
+`oqsprovider` at minimum needs `git` access, `cmake` and a C compiler
+to be present to be build, e.g., via `apt install cmake build-essential git`.
+
+## Build
+
+Standard `cmake` build sequence can be used (assuming prerequisites are installed)
+to build in/install from directory `_build`:
+
+ cmake -S . -B _build && cmake --build _build && cmake --install _build
+
+If `openssl` and/or `liboqs` have not been installed to system standard locations
+use the `cmake` define "-DOPENSSL_ROOT_DIR" and/or the environment variable
+"liboqs_DIR" to utilize those, e.g., like this:
+
+ liboqs_DIR=../liboqs cmake -DOPENSSL_ROOT_DIR=/opt/openssl3 -S . -B _build && cmake --build _build && cmake --install _build
+
+Further configuration options are documented [here](CONFIGURE.md#build-install-options).
+
+## Test
+
+Standard `ctest` can be used to validate correct operation in build directory `_build`, e.g.:
+
+ cd _build && ctest --parallel 5 --rerun-failed --output-on-failure -V
+
+## Packaging
+
+### Debian
+
+A build target to create UNIX .deb packaging is available via the standard
+`package` target, e.g., executing `make package` in the `_build` subdirectory.
+The resultant file can be installed as usual via `dpkg -i ...`.
+
+### MacOS
+
+An ".rb" packaging script for `brew` is available in the `scripts` directory
+and is regularly tested as part of CI.
--- /dev/null
+UNIX-specific build/install instructions
+========================================
+
+`oqsprovider` can also be build on/for Windows using Microsoft Visual
+Studio for C (MSVC) or `cygwin`. For the latter, please check the
+[notes for Unix](NOTES-UNIX.md).
+
+## Dependencies
+
+### OpenSSLv3
+
+OpenSSL (>=3.0.0) is not yet generally available under Windows. It is
+therefore sensible to build it from scratch.
+
+For that, please follow the instructions [here](https://github.com/openssl/openssl/blob/master/NOTES-WINDOWS.md).
+A complete scripted setup is available in the [CI tooling for oqs-provider](https://github.com/open-quantum-safe/oqs-provider/blob/main/.github/workflows/windows.yml).
+
+### liboqs
+
+Instructions for building `liboqs` from source is available
+[here](https://github.com/open-quantum-safe/liboqs#windows).
+
+## Build tooling
+
+`oqsprovider` is best built on Windows when `git` access, `cmake`, `ninja` and
+a C compiler are present, e.g., as in MS Visual Studio 2022.
+
+## Build
+
+A standard `cmake` build sequence can be used (assuming prerequisites are installed)
+to build in/install from directory `_build`:
+
+ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="/wd5105" -GNinja -S . -B _build && cd _build && ninja && ninja install
+
+The specific `CMAKE_C_FLAGS` silence some overly strict warning messages and
+the specific reference to the build type ensures a shared library with
+release symbols, suitable for use with a release-symbol `openssl` build
+is created.
+
+If `openssl` and/or `liboqs` have not been installed to system standard locations
+use the `cmake` defines "-DOPENSSL_ROOT_DIR" and/or "-Dliboqs_DIR" to utilize
+those, e.g., like this:
+
+ cmake -DOPENSSL_ROOT_DIR=c:\opt\openssl3 -Dliboqs_DIR=c:\liboqs -S . -B _build && cmake --build _build && cmake --install _build
+
+Further configuration options are documented [here](CONFIGURE.md#build-install-options).
+
+## Test
+
+Standard `ctest` can be used to validate correct operation in build directory `_build`, e.g.:
+
+ ctest -V --test-dir _build
+
+## Packaging
+
+Packaging the resultant .DLL is not yet implemented. Suggestions which package manager
+to use are welcome.
--- /dev/null
+[![GitHub actions](https://github.com/open-quantum-safe/oqs-provider/actions/workflows/linux.yml/badge.svg)](https://github.com/open-quantum-safe/oqs-provider/actions/workflows/linux.yml)
+[![GitHub actions](https://github.com/open-quantum-safe/oqs-provider/actions/workflows/windows.yml/badge.svg)](https://github.com/open-quantum-safe/oqs-provider/actions/workflows/windows.yml)
+[![GitHub actions](https://github.com/open-quantum-safe/oqs-provider/actions/workflows/macos.yml/badge.svg)](https://github.com/open-quantum-safe/oqs-provider/actions/workflows/macos.yml)
+[![oqs-provider](https://circleci.com/gh/open-quantum-safe/oqs-provider.svg?style=svg)](https://app.circleci.com/pipelines/github/open-quantum-safe/oqs-provider)
+
+oqsprovider - Open Quantum Safe provider for OpenSSL (3.x)
+==========================================================
+
+Purpose
+-------
+
+This repository contains code to enable quantum-safe cryptography (QSC)
+in a standard OpenSSL (3.x) distribution by way of implementing a single
+shared library, the OQS
+[provider](https://www.openssl.org/docs/manmaster/man7/provider.html).
+
+Status
+------
+
+Currently this provider fully enables quantum-safe cryptography for KEM
+key establishment in TLS1.3 including management of such keys via the
+OpenSSL (3.0) provider interface and hybrid KEM schemes. Also, QSC
+signatures including CMS and CMP functionality are available via the OpenSSL
+EVP interface. Key persistence is provided via the encode/decode
+mechanism and X.509 data structures. Starting with OpenSSL 3.2 support for
+TLS1.3 signature functionality is available and final glitches for CMS
+have been resolved.
+
+The standards implemented are documented in the separate file [STANDARDS.md](STANDARDS.md).
+
+Algorithms
+----------
+
+This implementation makes available the following quantum safe algorithms:
+
+<!--- OQS_TEMPLATE_FRAGMENT_ALGS_START -->
+### KEM algorithms
+
+- **BIKE**: `bikel1`, `p256_bikel1`, `x25519_bikel1`, `bikel3`, `p384_bikel3`, `x448_bikel3`, `bikel5`, `p521_bikel5`
+- **CRYSTALS-Kyber**: `kyber512`, `p256_kyber512`, `x25519_kyber512`, `kyber768`, `p384_kyber768`, `x448_kyber768`, `x25519_kyber768`, `p256_kyber768`, `kyber1024`, `p521_kyber1024`
+- **FrodoKEM**: `frodo640aes`, `p256_frodo640aes`, `x25519_frodo640aes`, `frodo640shake`, `p256_frodo640shake`, `x25519_frodo640shake`, `frodo976aes`, `p384_frodo976aes`, `x448_frodo976aes`, `frodo976shake`, `p384_frodo976shake`, `x448_frodo976shake`, `frodo1344aes`, `p521_frodo1344aes`, `frodo1344shake`, `p521_frodo1344shake`
+- **HQC**: `hqc128`, `p256_hqc128`, `x25519_hqc128`, `hqc192`, `p384_hqc192`, `x448_hqc192`, `hqc256`, `p521_hqc256`â€
+
+### Signature algorithms
+
+- **CRYSTALS-Dilithium**:`dilithium2`\*, `p256_dilithium2`\*, `rsa3072_dilithium2`\*, `dilithium3`\*, `p384_dilithium3`\*, `dilithium5`\*, `p521_dilithium5`\*
+- **Falcon**:`falcon512`\*, `p256_falcon512`\*, `rsa3072_falcon512`\*, `falcon1024`\*, `p521_falcon1024`\*
+
+- **SPHINCS-SHA2**:`sphincssha2128fsimple`\*, `p256_sphincssha2128fsimple`\*, `rsa3072_sphincssha2128fsimple`\*, `sphincssha2128ssimple`\*, `p256_sphincssha2128ssimple`\*, `rsa3072_sphincssha2128ssimple`\*, `sphincssha2192fsimple`\*, `p384_sphincssha2192fsimple`\*, `sphincssha2192ssimple`, `p384_sphincssha2192ssimple`, `sphincssha2256fsimple`, `p521_sphincssha2256fsimple`, `sphincssha2256ssimple`, `p521_sphincssha2256ssimple`
+- **SPHINCS-SHAKE**:`sphincsshake128fsimple`\*, `p256_sphincsshake128fsimple`\*, `rsa3072_sphincsshake128fsimple`\*, `sphincsshake128ssimple`, `p256_sphincsshake128ssimple`, `rsa3072_sphincsshake128ssimple`, `sphincsshake192fsimple`, `p384_sphincsshake192fsimple`, `sphincsshake192ssimple`, `p384_sphincsshake192ssimple`, `sphincsshake256fsimple`, `p521_sphincsshake256fsimple`, `sphincsshake256ssimple`, `p521_sphincsshake256ssimple`
+
+<!--- OQS_TEMPLATE_FRAGMENT_ALGS_END -->
+
+As the underlying [liboqs](https://github.com/open-quantum-safe/liboqs)
+at build time may be configured to not enable all algorithms, it is
+advisable to check the possible subset of algorithms actually enabled
+via the standard commands, i.e.,
+`openssl list -signature-algorithms -provider oqsprovider` and
+`openssl list -kem-algorithms -provider oqsprovider`.
+
+In addition, algorithms not denoted with "\*" above are not enabled for
+TLS operations. This designation [can be changed by modifying the
+"enabled" flags in the main alorithm configuration file](CONFIGURE.md#pre-build-configuration).
+
+In order to support parallel use of classic and quantum-safe cryptography
+this provider also provides different hybrid algorithms, combining classic
+and quantum-safe methods: These are listed above with a prefix denoting a
+classic algorithm, e.g., for elliptic curve: "p256_".
+
+A full list of algorithms, their interoperability code points and OIDs as well
+as a method to dynamically adapt them, e.g., for interoperability testing are
+documented in [ALGORITHMS.md](ALGORITHMS.md).
+
+Building and testing -- Quick start
+-----------------------------------
+
+All component builds and testing described in detail below can be executed by
+running the scripts `scripts/fullbuild.sh` and `scripts/runtests.sh`
+respectively (tested on Linux Ubuntu and Mint as well as MacOS).
+
+By default, these scripts always build and test against the current OpenSSL `master` branch.
+
+These scripts can be [configured by setting various variables](CONFIGURE.md#convenience-build-script-options).
+
+Building and testing
+--------------------
+
+The below describes the basic build-test-install cycle using the standard
+`cmake` tooling. Platform-specific notes are available for [UNIX](NOTES-UNIX.md)
+(incl. MacOS and `cygwin`) and [Windows](NOTES-Windows.md).
+
+## Configuration options
+
+All options to configure `oqs-provider` at build- or run-time are documented
+in [CONFIGURE.md](CONFIGURE.md).
+
+## Pre-requisites
+
+To be able to build `oqsprovider`, OpenSSL 3.0 and liboqs need to be installed.
+It's not important where they are installed, just that they are. If installed
+in non-standard locations, these must be provided when running `cmake` via
+the variables "OPENSSL_ROOT_DIR" and "liboqs_DIR". See [CONFIGURE.md](CONFIGURE.md)
+for details.
+
+## Basic steps
+
+ cmake -S . -B _build && cmake --build _build && ctest --test-dir _build && cmake --install _build
+
+Using
+-----
+
+Usage of `oqsprovider` is documented in the separate [USAGE.md](USAGE.md) file.
+
+Note on OpenSSL versions
+------------------------
+
+`oqsprovider` is written to ensure building on all versions of OpenSSL
+supporting the provider concept. However, OpenSSL still is in active
+development regarding features supported via the provider interface.
+Therefore some functionalities documented above are only supported
+with specific OpenSSL versions:
+
+## 3.0/3.1
+
+In these versions, CMS functionality implemented in providers is not
+supported: The resolution of https://github.com/openssl/openssl/issues/17717
+has not been not getting back-ported to OpenSSL3.0.
+
+Also not supported in this version are provider-based signature algorithms
+used during TLS1.3 operations as documented in https://github.com/openssl/openssl/issues/10512.
+
+## 3.2(-dev)
+
+After https://github.com/openssl/openssl/pull/19312 landed, (also PQ) signature
+algorithms are working in TLS1.3 (handshaking); after https://github.com/openssl/openssl/pull/20486
+has landed, also algorithms with very long signatures are supported.
+
+For [general OpenSSL implementation limitations, e.g., regarding provider feature usage and support,
+see here](https://wiki.openssl.org/index.php/OpenSSL_3.0#STATUS_of_current_development).
+
+Team
+----
+
+The Open Quantum Safe project is led by [Douglas Stebila](https://www.douglas.stebila.ca/research/) and [Michele Mosca](http://faculty.iqc.uwaterloo.ca/mmosca/) at the University of Waterloo.
+
+Contributors to the `oqsprovider` include:
+
+- Michael Baentsch
+- Christian Paquin
+- Richard Levitte
+- Basil Hess
+- Julian Segeth
+- Alex Zaslavsky
+- Will Childs-Klein
+- Thomas Bailleux
+
+History
+-------
+
+Documentation on current and past releases ("code history") is documented in
+the separate file [RELEASE.md](RELEASE.md).
+
+Acknowledgments
+---------------
+
+The `oqsprovider` project is supported through the [NGI Assure Fund](https://nlnet.nl/assure),
+a fund established by [NLnet](https://nlnet.nl) with financial
+support from the European Commission's [Next Generation Internet programme](https://www.ngi.eu),
+under the aegis of DG Communications Networks, Content and Technology
+under grant agreement No 957073.
+
+Financial support for the development of Open Quantum Safe has been provided
+by Amazon Web Services and the Tutte Institute for Mathematics and Computing.
+
+The OQS project would like to make a special acknowledgement to the companies who
+have dedicated programmer time to contribute source code to OQS, including
+Amazon Web Services, evolutionQ, Microsoft Research, Cisco Systems, and IBM Research.
+
+Research projects which developed specific components of OQS have been
+supported by various research grants, including funding from the Natural
+Sciences and Engineering Research Council of Canada (NSERC); see
+[here](https://openquantumsafe.org/papers/SAC-SteMos16.pdf) and
+[here](https://openquantumsafe.org/papers/NISTPQC-CroPaqSte19.pdf)
+for funding acknowledgments.
--- /dev/null
+# oqs-provider 0.5.1
+
+## About
+
+The **Open Quantum Safe (OQS) project** has the goal of developing and prototyping quantum-resistant cryptography. More information on OQS can be found on our website: https://openquantumsafe.org/ and on Github at https://github.com/open-quantum-safe/.
+
+**oqs-provider** is a standalone [OpenSSL 3](https://github.com/openssl/openssl) [provider](https://www.openssl.org/docs/manmaster/man7/provider.html) enabling [liboqs](https://github.com/open-quantum-safe/liboqs)-based quantum-safe and hybrid key exchange for TLS 1.3, as well as quantum-safe and hybrid X.509 certificate generation, CMS and dgst operations.
+
+When deployed, the `oqs-provider` binary (shared library) thus adds support for quantum-safe cryptographic operations to any standard OpenSSL(v3) installation.
+
+In general, the oqs-provider `main` branch is meant to be useable in conjunction with the `main` branch of [liboqs](https://github.com/open-quantum-safe/liboqs) and the `master` branch of [OpenSSL](https://github.com/openssl/openssl).
+
+Further details on building, testing and use can be found in [README.md](https://github.com/open-quantum-safe/oqs-provider/blob/main/README.md). See in particular limitations on intended use.
+
+## Release notes
+
+This is version 0.5.1 of oqs-provider.
+
+### Security considerations
+
+None.
+
+### What's New
+
+This release continues from the 0.5.0 release of oqs-provider and is fully tested to be used in conjunction with the main branch of [liboqs](https://github.com/open-quantum-safe/liboqs). This release is guaranteed to be in sync with v0.8.0 of `liboqs`.
+
+### Additional new feature highlights
+
+- Support for Windows platform
+- Added `brew` support for MacOS
+- Documentation restructured supporting different platforms
+- Enable statically linkable oqsprovider
+
+#### What's Changed (full commit list)
+
+* trigger oqs-demos build when pushing to main by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/182
+* Enable building on platforms without _Atomic support by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/183
+* Standalone ctest by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/184
+* Convert oqs-kem-info.md code points to hex by @WillChilds-Klein in https://github.com/open-quantum-safe/oqs-provider/pull/188
+* Documentation update by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/187
+* Add full Windows support by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/192
+* Improve installation by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/196
+* document specs [skip ci] by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/190
+* Add .DS_Store (macOS), .vscode (visual studio code), and .idea (Jetbr… by @planetf1 in https://github.com/open-quantum-safe/oqs-provider/pull/200
+* first test for macos CI by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/198
+* Add brew to preinstall test matrix by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/205
+* General documentation overhaul by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/204
+* change TLS demo to use QSC alg [skip ci] by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/208
+* Build a module instead of a shared library. by @thb-sb in https://github.com/open-quantum-safe/oqs-provider/pull/207
+* explain groups in USAGE [skip ci] by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/214
+* ensure OpenSSL3 is linked to liboqs during script build by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/212
+* Remove trailing whitespaces in generated code. by @thb-sb in https://github.com/open-quantum-safe/oqs-provider/pull/215
+* Fix a minor bug in the `runtests.sh`. by @thb-sb in https://github.com/open-quantum-safe/oqs-provider/pull/216
+* Specify version `3.1` while installing OpenSSL using brew. by @thb-sb in https://github.com/open-quantum-safe/oqs-provider/pull/217
+* Allow the user to build oqs-provider as a static library. by @thb-sb in https://github.com/open-quantum-safe/oqs-provider/pull/201
+* Add a line to `RELEASE.md` to highlight the support for static libraries by @thb-sb in https://github.com/open-quantum-safe/oqs-provider/pull/220
+* Enhance github bug report template by @baentsch in https://github.com/open-quantum-safe/oqs-provider/pull/219
+* Use OpenSSL 3 if available to build liboqs on CircleCI/macOS. by @thb-sb in https://github.com/open-quantum-safe/oqs-provider/pull/222
+* Fix a bug in the CMake script. by @thb-sb in https://github.com/open-quantum-safe/oqs-provider/pull/221
+
+#### New Contributors
+
+* @WillChilds-Klein made their first contribution in https://github.com/open-quantum-safe/oqs-provider/pull/188
+* @planetf1 made their first contribution in https://github.com/open-quantum-safe/oqs-provider/pull/200
+* @thb-sb made their first contribution in https://github.com/open-quantum-safe/oqs-provider/pull/207
+
+**Full Changelog**: https://github.com/open-quantum-safe/oqs-provider/compare/0.5.0...0.5.1
+
+Previous Release Notes
+======================
+
+This is version 0.5.0 of oqs-provider.
+
+Security considerations
+-----------------------
+
+None.
+
+What's New
+----------
+
+This release continues from the 0.4.0 release of oqs-provider and is fully tested to be used in conjunction with the main branch of [liboqs](https://github.com/open-quantum-safe/liboqs). This release is guaranteed to be in sync with v0.8.0 of `liboqs`.
+
+oqs-provider now also enables use of QSC algorithms during TLS1.3 handshake. The required OpenSSL code updates are contained in https://github.com/openssl/openssl/pull/19312. Prior to this code merging, the functionality can be tested by using https://github.com/baentsch/openssl/tree/sigload.
+
+### Algorithm updates
+
+All algorithms no longer supported in the [NIST PQC competition](https://csrc.nist.gov/projects/post-quantum-cryptography) and not under consideration for standardization by ISO have been removed. All remaining algorithms with the exception of McEliece have been lifted to their final round 3 variants as documented in [liboqs](https://github.com/open-quantum-safe/liboqs/blob/main/RELEASE.md#release-notes). Most notably, algorithm names for Sphincs+ have been changed to the naming chosen by its authors.
+
+### Functional updates
+
+- Enablement of oqs-provider as a (first) dynamically fetchable OpenSSL3 TLS1.3 signature provider.
+- MacOS support
+- Full support for CA functionality
+- Algorithms can now be selected by their respective bit strength using the property string "oqsprovider.security_bits"
+- Documentation of (O)IDs used by the different PQC algorithms used and supported in current and past releases of oqs-openssl and oqs-provider
+- Testing is now completely independent of a source code distribution of OpenSSL being available
+- oqsprovider can be built and installed making use of pre-existing installations of `OpenSSL` and `liboqs`. Details are found in the "scripts" directory's build and test scripts.
+- Automated creation of (Debian) packaging information
+- Graceful handling (by way of functional degradation) of the feature sets contained in different OpenSSL releases; all oqsprovider capabilities are only available when using a version > than OpenSSL3.1.
+- A bug regarding handling of hybrid algorithms has been fixed as well as some memory leaks.
+
+### Misc updates
+
+- Dynamic code point and OID changes via environment variables. See [ALGORITHMS.md](ALGORITHMS.md).
+- Dynamic key encoding changes via environment variable using external qsc_key_encoder library. See [ALGORITHMS.md](ALGORITHMS.md).
+
+---
+
+**Full Changelog**: https://github.com/open-quantum-safe/oqs-provider/compare/0.4.0...0.5.0.
+
+Previous Release Notes
+======================
+
+This is version 0.4.0 of oqs-provider.
+
+Security considerations
+-----------------------
+
+This release removes Rainbow level 1 and all variants of SIDH and SIKE due to cryptanalytic breaks of those algorithms. Users are advised to move away from use of those algorithms immediately.
+
+What's New
+----------
+
+This release continues from the 0.3.0 release of oqs-provider and is fully tested to be used in conjunction with version 0.7.2 of [liboqs](https://github.com/open-quantum-safe/liboqs).
+
+oqs-provider has been integrated as an external test component for [OpenSSL3 testing](https://github.com/openssl/openssl/blob/master/test/README-external.md#oqsprovider-test-suite) and will thus remain in line with any possibly required provider API enhancements.
+
+### Algorithm updates
+
+- Removal of SIKE/SIDH and Rainbow level I due to cryptographic breaks
+
+### Functional updates
+
+- Addition of quantum-safe CMS operations via the [OpenSSL interface](https://www.openssl.org/docs/man3.0/man1/openssl-cms.html)
+- Addition of quantum-safe dgst operations via the [OpenSSL interface](https://www.openssl.org/docs/man3.0/man1/openssl-dgst.html)
+
+### Misc updates
+
+- Additional testing
+- Integration with and of OpenSSL test harness
+
+---
+
+**Full Changelog**: https://github.com/open-quantum-safe/oqs-provider/compare/0.3.0...0.4.0.
+
+# 0.3.0 - January 2022
+
+## About
+
+This is the first official release of `oqsprovider`, a plugin/shared library making available quantum safe cryptography (QSC) to [OpenSSL (3)](https://www.openssl.org/) installations via the [provider](https://www.openssl.org/docs/manmaster/man7/provider.html) API. Work on this project began in [oqs-openssl](https://github.com/open-quantum-safe/openssl)'s branch "OQS-OpenSSL3" by [@baentsch](https://github.com/baentsch). This original code dependent on OpenSSL APIs was transferred into a standalone project by [@levitte](https://github.com/levitte) and subsequently branched by the OQS project into this code base.
+
+This project is part of the **Open Quantum Safe (OQS) project**: More information on OQS can be found on our website: https://openquantumsafe.org/ and on Github at https://github.com/open-quantum-safe/.
+
+## Release Notes
+
+The current feature set of `oqsprovider` comprises
+
+- support of all QSC KEM algorithms contained in [liboqs](https://github.com/open-quantum-safe/liboqs) ([v.0.7.1](https://github.com/open-quantum-safe/liboqs/releases/tag/0.7.1)) including hybrid classic/QSC algorithm pairs
+- integration of all QSC KEM algorithms into TLS 1.3 using the [groups interface](https://github.com/open-quantum-safe/oqs-provider#running-a-client-to-interact-with-quantum-safe-kem-algorithms)
+- support of all QSC signature algorithms contained in [liboqs](https://github.com/open-quantum-safe/liboqs) ([v.0.7.1](https://github.com/open-quantum-safe/liboqs/releases/tag/0.7.1)) including hybrid classic/QSC algorithm pairs
+- integration for persistent data structures (X.509) of all QSC signature algorithms using the [standard OpenSSL toolset](https://github.com/open-quantum-safe/oqs-provider#creating-classic-keys-and-certificates)
+
+### Limitations
+
+- This code is [not meant to be used in productive deployments](https://openquantumsafe.org/liboqs/security)
+- Currently, only Linux is supported and only Ubuntu 20/x64 is tested
+- Full TLS1.3 support for QSC signatures is missing (see https://github.com/openssl/openssl/issues/10512)
--- /dev/null
+Standards supported when deploying oqsprovider
+==============================================
+
+For non-post-quantum algorithms, this provider is basically silent, i.e.,
+permits use of standards and algorithms implemented by [openssl](https://github.com/openssl/openssl)
+, e.g., concerning X.509, PKCS#8 or CMS.
+
+For post-quantum algorithms, the version of the cryptographic algorithm used
+depends on the version of [liboqs](https://github.com/open-quantum-safe/liboqs) used.
+Regarding the integration of post-quantum algorithms into higher level
+components, this provider implements the following standards:
+
+- For TLS:
+ - Hybrid post-quantum / traditional key exchange:
+ - The data structures used follow the Internet-Draft [Hybrid key exchange in TLS 1.3](https://datatracker.ietf.org/doc/draft-ietf-tls-hybrid-design/), namely simple concatenation of traditional and post-quantum public keys and shared secrets.
+ - The algorithm identifiers used are documented in [oqs-kem-info.md](https://github.com/open-quantum-safe/oqs-provider/blob/main/oqs-template/oqs-kem-info.md).
+ - Hybrid post-quantum / traditional signatures in TLS:
+ - For public keys and digital signatures inside X.509 certificates, see the bullet point on X.509 below.
+ - For digital signatures outside X.509 certificates and in the TLS 1.3 handshake directly, the data structures used follow the same encoding format as that used for X.509 certificates, namely simple concatenation of traditional and post-quantum signatures.
+ - The algorithm identifiers used are documented in [oqs-sig-info.md](https://github.com/open-quantum-safe/oqs-provider/blob/main/oqs-template/oqs-sig-info.md).
+- For X.509:
+ - Hybrid post-quantum / traditional public keys and signatures:
+ - The data structures used follow the Internet-Draft [Internet X.509 Public Key Infrastructure: Algorithm Identifiers for Dilithium](https://datatracker.ietf.org/doc/draft-ietf-lamps-dilithium-certificates/), namely simple concatenation of traditional and post-quantum components in plain binary / OCTET_STRING representations.
+ - The algorithm identifiers (OIDs) used are documented in [oqs-sig-info.md](https://github.com/open-quantum-safe/oqs-provider/blob/main/oqs-template/oqs-sig-info.md).
+- For PKCS#8:
+ - Hybrid post-quantum / traditional private keys:
+ - Simple concatenation of traditional and post-quantum components in plain binary / OCTET_STRING representations.
+
+Additionally worthwhile noting is that only quantum-safe [signature algorithms](#signature-algorithms) are persisted via PKCS#8 and X.509. No corresponding encoder/decoder logic exists for quantum safe [KEM algorithms](#kem-algorithms) -- See also #194.
+
--- /dev/null
+Usage instructions for oqsprovider
+==================================
+
+This file documents information required to properly utilize `oqsprovider`
+after installation on a machine running `openssl` v3.
+
+Beware that `oqsprovider` will not work on machines where an OpenSSL
+version below "3.0.0" is (the default) installed.
+
+## Baseline assumption
+
+An `openssl` version >= 3.0.0 is available and set in the "PATH" environment
+variable such as that the command `openssl version` yields a result documenting
+this, e.g., as follows:
+
+```
+OpenSSL 3.2.0-dev (Library: OpenSSL 3.2.0-dev )
+```
+
+## Activation
+
+Every OpenSSL provider needs to be activated for use. There are two main ways
+for this:
+
+### Explicit command line option
+
+#### -provider
+
+Most `openssl` commands permit passing the option `-provider`: The name after
+this command is that of the provider to be activated.
+
+As an example: `openssl list -signature-algorithms -provider oqsprovider`
+outputs all quantum safe signature algorithms made available for `openssl` use.
+
+#### -provider-path
+
+All `openssl` commands accepting `-provider` also permit passing `-provider-path`
+as a possibility to reference the location in the local filesystem where the
+provider binary is located. This is of particular use if the provider did not
+(yet) get installed in the system location, which typically is in `lib/ossl-modules`
+in the main `openssl` installation tree.
+
+### Configuration file
+
+As an alternative to passing command line parameters, providers can be activated
+for general use by adding instructions to the `openssl.cnf` file. In the case of
+`oqs-provider` add these lines to achieve this:
+
+```
+[provider_sect]
+default = default_sect
+oqsprovider = oqsprovider_sect
+[oqsprovider_sect]
+activate = 1
+```
+
+#### module option
+
+Next to the "activate" keyword, `openssl` also recognizes the "module" keyword
+which mirrors the functionality of `-provider-path` documented above: This way,
+a non-standard location for the `oqsprovider` shared library (.SO/.DYLIB/.DLL)
+can be registered for testing.
+
+If this configuration variable is not set, the global environment variable
+"OPENSSL_MODULES" must point to a directory where the `oqsprovider` binary
+is to be found.
+
+If the `oqsprovider` binary cannot be found, it simply (and silently) will
+not be available for use.
+
+#### System wide installation
+
+The system-wide `openssl.cnf` file is typically located at (operating system dependent):
+- /etc/ssl/ (UNIX/Linux)
+- /opt/homebrew/etc/openssl@3/ (MacOS Homebrew on Apple Silicon)
+- /usr/local/etc/openssl@3/ (MacOS Homebrew on Intel Silicon)
+- C:\Program Files\Common Files\SSL\ (Windows)
+
+Adding `oqsprovider` to this file will enable its seamless operation alongside other
+`openssl` providers. If successfully done, running, e.g., `openssl list -providers`
+should output something along these lines (version IDs variable of course):
+
+```
+providers:
+ default
+ name: OpenSSL Default Provider
+ version: 3.1.1
+ status: active
+ oqsprovider
+ name: OpenSSL OQS Provider
+ version: 0.5.0
+ status: active
+```
+
+If this is the case, all `openssl` commands can be used as usual, extended
+by the option to use quantum safe cryptographic algorithms in addition/instead
+of classical crypto algorithms.
+
+This configuration is the one used in all examples below.
+
+*Note*: Be sure to always activate either the "default" or "fips" provider as these
+deliver functionality also needed by `oqsprovider` (e.g., for hashing or high
+quality random data during key generation).
+
+## Selecting TLS1.3 default groups
+
+For activating specific [KEMs](README.md#kem-algorithms), two options exist:
+
+### Command line parameter
+
+All commands allowing pre-selecting KEMs for use permit this via the
+`-groups` switch. See example commands below.
+
+### Configuration parameter
+
+The set of acceptable KEM groups can also be set in the `openssl.cnf` file
+as per this example:
+
+```
+[openssl_init]
+ssl_conf = ssl_sect
+
+[ssl_sect]
+system_default = system_default_sect
+
+[system_default_sect]
+Groups = kyber768:kyber1024
+```
+
+Be sure to separate permissible KEM names by colon if specifying several.
+
+## Sample commands
+
+The following section provides example commands for certain standard OpenSSL operations.
+
+### Checking provider version information
+
+ openssl list -providers -verbose
+
+### Checking quantum safe signature algorithms available for use
+
+ openssl list -signature-algorithms -provider oqsprovider
+
+### Checking quantum safe KEM algorithms available for use
+
+ openssl list -kem-algorithms -provider oqsprovider
+
+### Creating keys and certificates
+
+This can be facilitated for example by using the usual `openssl` commands:
+
+ openssl req -x509 -new -newkey dilithium3 -keyout dilithium3_CA.key -out dilithium3_CA.crt -nodes -subj "/CN=test CA" -days 365 -config openssl/apps/openssl.cnf
+ openssl genpkey -algorithm dilithium3 -out dilithium3_srv.key
+ openssl req -new -newkey dilithium3 -keyout dilithium3_srv.key -out dilithium3_srv.csr -nodes -subj "/CN=test server" -config openssl/apps/openssl.cnf
+ openssl x509 -req -in dilithium3_srv.csr -out dilithium3_srv.crt -CA dilithium3_CA.crt -CAkey dilithium3_CA.key -CAcreateserial -days 365
+
+These examples create QSC dilithium3 keys but the very same commands can be used
+to create PQ certificates replacing the key type "dilithium" with any of the PQ
+[signature algorithms supported](README.md#signature-algorithms).
+Also, any classic signature algorithm like "rsa" may be used.
+
+### Setting up a (quantum-safe) test server
+
+Using keys and certificates as created above, a simple server utilizing a
+PQ/quantum-safe KEM algorithm and certicate can be set up for example by running
+
+ openssl s_server -cert dilithium3_srv.crt -key dilithium3_srv.key -www -tls1_3 -groups kyber768:frodo640shake
+
+Instead of "dilithium3" any [QSC/PQ signature algorithm supported](README.md#signature-algorithms)
+may be used as well as any classic crypto signature algorithm.
+
+### Running a client to interact with (quantum-safe) KEM algorithms
+
+This can be facilitated for example by running
+
+ openssl s_client -groups frodo640shake
+
+By issuing the command `GET /` the quantum-safe crypto enabled OpenSSL3
+server returns details about the established connection.
+
+Any [available quantum-safe/PQ KEM algorithm](README.md#kem-algorithms) can be selected by passing it in the `-groups` option.
+
+### S/MIME message signing -- Cryptographic Message Syntax (CMS)
+
+Also possible is the creation and verification of quantum-safe digital
+signatures using [CMS](https://datatracker.ietf.org/doc/html/rfc5652).
+
+#### Signing data
+
+For creating signed data, two steps are required: One is the creation
+of a certificate using a QSC algorithm; the second is the use of this
+certificate (and its signature algorithm) to create the signed data:
+
+Step 1: Create quantum-safe key pair and self-signed certificate:
+
+ openssl req -x509 -new -newkey dilithium3 -keyout qsc.key -out qsc.crt -nodes -subj "/CN=oqstest" -days 365 -config openssl/apps/openssl.cnf
+
+By changing the `-newkey` parameter algorithm name [any of the
+supported quantum-safe or hybrid algorithms](README.md#signature-algorithms)
+can be utilized instead of the sample algorithm `dilithium3`.
+
+Step 2: Sign data:
+
+As
+[the CMS standard](https://datatracker.ietf.org/doc/html/rfc5652#section-5.3)
+requires the presence of a digest algorithm, while quantum-safe crypto
+does not, in difference to the QSC certificate creation command above,
+passing a message digest algorithm via the `-md` parameter is mandatory.
+
+ openssl cms -in inputfile -sign -signer qsc.crt -inkey qsc.key -nodetach -outform pem -binary -out signedfile -md sha512
+
+Data to be signed is to be contained in the file named `inputfile`. The
+resultant CMS output is contained in file `signedfile`. The QSC algorithm
+used is the same signature algorithm utilized for signing the certificate
+`qsc.crt`.
+
+#### Verifying data
+
+Continuing the example above, the following command verifies the CMS file
+`signedfile` and outputs the `outputfile`. Its contents should be identical
+to the original data in `inputfile` above.
+
+ openssl cms -verify -CAfile qsc.crt -inform pem -in signedfile -crlfeol -out outputfile
+
+Note that it is also possible to build proper QSC certificate chains
+using the standard OpenSSL calls. For sample code see
+[scripts/oqsprovider-certgen.sh](scripts/oqsprovider-certgen.sh).
+
+### Support of `dgst` (and sign)
+
+Also tested to operate OK is the [openssl dgst](https://www.openssl.org/docs/man3.0/man1/openssl-dgst.html)
+command. Sample invocations building on the keys and certificate files in the examples above:
+
+#### Signing
+
+ openssl dgst -sign qsc.key -out dgstsignfile inputfile
+
+#### Verifying
+
+ openssl dgst -signature dgstsignfile -verify qsc.pubkey inputfile
+
+The public key can be extracted from the certificate using standard openssl command:
+
+ openssl x509 -in qsc.crt -pubkey -noout > qsc.pubkey
+
+The `dgst` command is not tested for interoperability with [oqs-openssl111](https://github.com/open-quantum-safe/openssl).
+
+*Note on KEM Decapsulation API*:
+
+The OpenSSL [`EVP_PKEY_decapsulate` API](https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_decapsulate.html) specifies an explicit return value for failure. For security reasons, most KEM algorithms available from liboqs do not return an error code if decapsulation failed. Successful decapsulation can instead be implicitly verified by comparing the original and the decapsulated message.
+
--- /dev/null
+
+|Environment Variable | Permissible Values |
+| --- | --- |
+{% for sig in config['sigs'] -%}
+ {%- for variant in sig['variants'] -%}
+ {%- if 'supported_encodings' in variant -%}
+|`OQS_ENCODING_{{variant['name']|upper}}`|
+{%- for item in variant['supported_encodings'] -%}
+`{{item}}`{% if not loop.last %}, {%- endif -%}
+{% endfor %}|
+{% endif %}
+{%- endfor %}
+{%- endfor %}
--- /dev/null
+
+|Algorithm name | default ID | enabled | environment variable |
+|---------------|:----------:|:-------:|----------------------|
+{%- for kem in config['kems'] %}
+| {{ kem['name_group'] }} | {{ kem['nid'] }} | Yes | OQS_CODEPOINT_{{ kem['name_group']|upper }} |
+{%- for hybrid in kem['hybrids'] %}
+| {{ hybrid['hybrid_group'] }}_{{ kem['name_group'] }} | {{ hybrid['nid'] }} | Yes | OQS_CODEPOINT_{{ hybrid['hybrid_group']|upper }}_{{ kem['name_group']|upper }} |
+{%- endfor %}
+{%- endfor %}
+{%- for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+| {{variant['name']}} | {{ variant['code_point'] }} | {%- if variant['enable'] -%} Yes {%- else -%} No {%- endif -%} | OQS_CODEPOINT_{{ variant['name']|upper }}
+ {%- for classical_alg in variant['mix_with'] %}
+| {{ classical_alg['name'] }}_{{variant['name']}} | {{ classical_alg['code_point'] }} | {%- if variant['enable'] -%} Yes {%- else -%} No {%- endif -%} | OQS_CODEPOINT_{{ classical_alg['name']|upper }}_{{ variant['name']|upper }}
+ {%- endfor %}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+
+|Algorithm name | default OID | enabled | environment variable |
+|---------------|:-----------------:|:-------:|----------------------|
+
+{%- for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+| {{variant['name']}} | {{ variant['oid'] }} | {%- if variant['enable'] -%} Yes {%- else -%} No {%- endif -%} | OQS_OID_{{ variant['name']|upper }}
+ {%- for classical_alg in variant['mix_with'] %}
+| {{ classical_alg['name'] }}_{{variant['name']}} | {{ classical_alg['oid'] }} | {%- if variant['enable'] -%} Yes {%- else -%} No {%- endif -%} | OQS_OID_{{ classical_alg['name']|upper }}_{{ variant['name']|upper }}
+ {%- endfor %}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+
+### KEM algorithms
+{% for family, kems in config['kems'] | groupby('family') %}
+- **{{ family }}**: {% for kem in kems -%} `{{ kem['name_group'] }}` {%- for hybrid in kem['hybrids'] -%}, `{{ hybrid['hybrid_group']}}_{{ kem['name_group'] }}`{%- endfor -%}{%- if not loop.last %}, {% endif -%}{%- if loop.last and family == 'HQC' -%}†{%- endif -%}{%- endfor -%}
+{%- endfor %}
+
+### Signature algorithms
+{% for sig in config['sigs'] %}
+{% if sig['variants']|length > 0 -%}
+- **{{ sig['family'] }}**:
+ {%- for variant in sig['variants'] -%}
+`{{ variant['name'] }}`
+{%- if variant['enable'] -%} \* {%- endif -%}
+{%- for classical_alg in variant['mix_with'] -%} , `{{ classical_alg['name']}}_{{ variant['name'] }}`{%- if variant['enable'] -%} \* {%- endif -%}{%- endfor -%}
+{%- if not loop.last %}, {% endif -%}
+ {%- endfor -%}
+{%- endif -%}
+{%- endfor %}
+
+
--- /dev/null
+#!/usr/bin/env python3
+
+import copy
+import glob
+import jinja2
+import jinja2.ext
+import os
+import shutil
+import subprocess
+import yaml
+
+# For files generated, the copyright message can be adapted
+# see https://github.com/open-quantum-safe/oqs-provider/issues/2#issuecomment-920904048
+# SPDX message to be leading, OpenSSL Copyright notice to be deleted
+def fixup_copyright(filename):
+ with open(filename, "r") as origfile:
+ with open(filename+".new", "w") as newfile:
+ newfile.write("// SPDX-License-Identifier: Apache-2.0 AND MIT\n\n")
+ skipline = False
+ checkline = True
+ for line in origfile:
+ if checkline==True and " * Copyright" in line:
+ skipline=True
+ if "*/" in line:
+ skipline=False
+ checkline=False
+ if not skipline:
+ newfile.write(line)
+ os.rename(filename+".new", filename)
+
+def get_kem_nistlevel(alg):
+ if 'LIBOQS_SRC_DIR' not in os.environ:
+ print("Must include LIBOQS_SRC_DIR in environment")
+ exit(1)
+ # translate family names in generate.yml to directory names for liboqs algorithm datasheets
+ if alg['family'] == 'CRYSTALS-Kyber': datasheetname = 'kyber'
+ elif alg['family'] == 'SIDH': datasheetname = 'sike'
+ elif alg['family'] == 'NTRU-Prime': datasheetname = 'ntruprime'
+ else: datasheetname = alg['family'].lower()
+ # load datasheet
+ algymlfilename = os.path.join(os.environ['LIBOQS_SRC_DIR'], 'docs', 'algorithms', 'kem', '{:s}.yml'.format(datasheetname))
+ algyml = yaml.safe_load(file_get_contents(algymlfilename, encoding='utf-8'))
+ # hacks to match names
+ def matches(name, alg):
+ def simplify(s):
+ return s.lower().replace('_', '').replace('-', '')
+ if 'FrodoKEM' in name: name = name.replace('FrodoKEM', 'Frodo')
+ if 'Saber-KEM' in name: name = name.replace('-KEM', '')
+ if '-90s' in name: name = name.replace('-90s', '').replace('Kyber', 'Kyber90s')
+ if simplify(name) == simplify(alg['name_group']): return True
+ return False
+ # find the variant that matches
+ for variant in algyml['parameter-sets']:
+ if matches(variant['name'], alg):
+ return variant['claimed-nist-level']
+ return None
+
+def get_sig_nistlevel(family, alg):
+ if 'LIBOQS_SRC_DIR' not in os.environ:
+ print("Must include LIBOQS_SRC_DIR in environment")
+ exit(1)
+ # translate family names in generate.yml to directory names for liboqs algorithm datasheets
+ if family['family'] == 'CRYSTALS-Dilithium': datasheetname = 'dilithium'
+ elif family['family'] == 'SPHINCS-Haraka': datasheetname = 'sphincs'
+ elif family['family'] == 'SPHINCS-SHA2': datasheetname = 'sphincs'
+ elif family['family'] == 'SPHINCS-SHAKE': datasheetname = 'sphincs'
+ else: datasheetname = family['family'].lower()
+ # load datasheet
+ algymlfilename = os.path.join(os.environ['LIBOQS_SRC_DIR'], 'docs', 'algorithms', 'sig', '{:s}.yml'.format(datasheetname))
+ algyml = yaml.safe_load(file_get_contents(algymlfilename, encoding='utf-8'))
+ # hacks to match names
+ def matches(name, alg):
+ def simplify(s):
+ return s.lower().replace('_', '').replace('-', '').replace('+', '')
+ if simplify(name) == simplify(alg['name']): return True
+ return False
+ # find the variant that matches
+ for variant in algyml['parameter-sets']:
+ if matches(variant['name'], alg):
+ return variant['claimed-nist-level']
+ return None
+
+def nist_to_bits(nistlevel):
+ if nistlevel==1 or nistlevel==2:
+ return 128
+ elif nistlevel==3 or nistlevel==4:
+ return 192
+ elif nistlevel==5:
+ return 256
+ else:
+ return None
+
+def complete_config(config):
+ for kem in config['kems']:
+ bits_level = nist_to_bits(get_kem_nistlevel(kem))
+ if bits_level == None:
+ print("Cannot find security level for {:s} {:s}".format(kem['family'], kem['name_group']))
+ exit(1)
+ kem['bit_security'] = bits_level
+
+ # now add hybrid_nid to hybrid_groups
+ phyb = {}
+ if (bits_level == 128):
+ phyb['hybrid_group']='p256'
+ elif (bits_level == 192):
+ phyb['hybrid_group']='p384'
+ elif (bits_level == 256):
+ phyb['hybrid_group']='p521'
+ else:
+ print("Warning: Unknown bit level for %s. Cannot assign hybrid." % (kem['group_name']))
+ exit(1)
+ phyb['bit_security']=bits_level
+ phyb['nid']=kem['nid_hybrid']
+ kem['hybrids'].insert(0, phyb)
+
+ for famsig in config['sigs']:
+ for sig in famsig['variants']:
+ bits_level = nist_to_bits(get_sig_nistlevel(famsig, sig))
+ if bits_level == None:
+ print("Cannot find security level for {:s} {:s}. Setting to 0.".format(famsig['family'], sig['name']))
+ bits_level = 0
+ sig['security'] = bits_level
+ return config
+
+def run_subprocess(command, outfilename=None, working_dir='.', expected_returncode=0, input=None, ignore_returncode=False):
+ result = subprocess.run(
+ command,
+ input=input,
+ stdout=(open(outfilename, "w") if outfilename!=None else subprocess.PIPE),
+ stderr=subprocess.PIPE,
+ cwd=working_dir,
+ )
+
+ if not(ignore_returncode) and (result.returncode != expected_returncode):
+ if outfilename == None:
+ print(result.stdout.decode('utf-8'))
+ assert False, "Got unexpected return code {}".format(result.returncode)
+
+# For list.append in Jinja templates
+Jinja2 = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath="."),extensions=['jinja2.ext.do'])
+
+def file_get_contents(filename, encoding=None):
+ with open(filename, mode='r', encoding=encoding) as fh:
+ return fh.read()
+
+def file_put_contents(filename, s, encoding=None):
+ with open(filename, mode='w', encoding=encoding) as fh:
+ fh.write(s)
+
+def populate(filename, config, delimiter, overwrite=False):
+ fragments = glob.glob(os.path.join('oqs-template', filename, '*.fragment'))
+ if overwrite == True:
+ source_file = os.path.join('oqs-template', filename, os.path.basename(filename)+ '.base')
+ contents = file_get_contents(source_file)
+ else:
+ contents = file_get_contents(filename)
+ for fragment in fragments:
+ identifier = os.path.splitext(os.path.basename(fragment))[0]
+ if filename.endswith('.md'):
+ identifier_start = '{} OQS_TEMPLATE_FRAGMENT_{}_START -->'.format(delimiter, identifier.upper())
+ else:
+ identifier_start = '{} OQS_TEMPLATE_FRAGMENT_{}_START'.format(delimiter, identifier.upper())
+ identifier_end = '{} OQS_TEMPLATE_FRAGMENT_{}_END'.format(delimiter, identifier.upper())
+ preamble = contents[:contents.find(identifier_start)]
+ postamble = contents[contents.find(identifier_end):]
+ if overwrite == True:
+ contents = preamble + Jinja2.get_template(fragment).render({'config': config}) + postamble.replace(identifier_end + '\n', '')
+ else:
+ contents = preamble + identifier_start + Jinja2.get_template(fragment).render({'config': config}) + postamble
+ file_put_contents(filename, contents)
+
+def load_config(include_disabled_sigs=False):
+ config = file_get_contents(os.path.join('oqs-template', 'generate.yml'), encoding='utf-8')
+ config = yaml.safe_load(config)
+ if not include_disabled_sigs:
+ for sig in config['sigs']:
+ sig['variants'] = [variant for variant in sig['variants'] if ('enable' in variant and variant['enable'])]
+
+ # remove KEMs without NID (old stuff)
+ newkems = []
+ for kem in config['kems']:
+ if 'nid' in kem:
+ newkems.append(kem)
+ config['kems']=newkems
+
+ # remove SIGs without OID (old stuff)
+ for sig in config['sigs']:
+ newvars = []
+ for variant in sig['variants']:
+ if 'oid' in variant:
+ newvars.append(variant)
+ sig['variants']=newvars
+
+ for kem in config['kems']:
+ kem['hybrids'] = []
+ if 'extra_nids' not in kem or 'current' not in kem['extra_nids']:
+ continue
+ hybrid_nids = set()
+ for extra_hybrid in kem['extra_nids']['current']:
+ if extra_hybrid['hybrid_group'] == "x25519" or extra_hybrid['hybrid_group'] == "p256":
+ extra_hybrid['bit_security'] = 128
+ if extra_hybrid['hybrid_group'] == "x448" or extra_hybrid['hybrid_group'] == "p384":
+ extra_hybrid['bit_security'] = 192
+ if extra_hybrid['hybrid_group'] == "p521":
+ extra_hybrid['bit_security'] = 256
+ kem['hybrids'].append(extra_hybrid)
+ if 'hybrid_group' in extra_hybrid:
+ extra_hybrid_nid = extra_hybrid['nid']
+ if extra_hybrid_nid in hybrid_nids:
+ print("ERROR: duplicate hybrid NID for", kem['name_group'],
+ ":", extra_hybrid_nid, "in generate.yml.",
+ "Curve NIDs may only be specified once per KEM.")
+ exit(1)
+ hybrid_nids.add(extra_hybrid_nid)
+ return config
+
+# extend config with "hybrid_groups" array:
+config = load_config() # extend config with "hybrid_groups" array
+
+# complete config with "bit_security" and "hybrid_group from
+# nid_hybrid information
+config = complete_config(config)
+
+
+populate('oqsprov/oqsencoders.inc', config, '/////')
+populate('oqsprov/oqsdecoders.inc', config, '/////')
+populate('oqsprov/oqs_prov.h', config, '/////')
+populate('oqsprov/oqsprov.c', config, '/////')
+populate('oqsprov/oqsprov_capabilities.c', config, '/////')
+populate('oqsprov/oqs_kmgmt.c', config, '/////')
+populate('oqsprov/oqs_encode_key2any.c', config, '/////')
+populate('oqsprov/oqs_decode_der2key.c', config, '/////')
+populate('oqsprov/oqsprov_keys.c', config, '/////')
+
+config2 = load_config(include_disabled_sigs=True)
+config2 = complete_config(config2)
+
+populate('ALGORITHMS.md', config2, '<!---')
+populate('README.md', config2, '<!---')
+print("All files generated")
+os.environ["LIBOQS_DOCS_DIR"]=os.path.join(os.environ["LIBOQS_SRC_DIR"], "docs")
+import generate_oid_nid_table
--- /dev/null
+#!/bin/bash
+
+cd oqs-template
+
+rm generate.yml
+
+# Step 1: Obtain current generate.yml from main:
+wget -c https://raw.githubusercontent.com/open-quantum-safe/openssl/OQS-OpenSSL_1_1_1-stable/oqs-template/generate.yml
+
+# Step 2: Run the generator:
+cd .. && python3 oqs-template/generate.py
--- /dev/null
+# This is the master document for ID interoperability for KEM IDs, p-hybrid KEM IDs, SIG (O)IDs
+# Next free plain KEM ID: 0x0244, p-hybrid: 0x2F44, X-hybrid: 0x2FB0
+kems:
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo640aes'
+ nid: '0x0200'
+ nid_hybrid: '0x2F00'
+ oqs_alg: 'OQS_KEM_alg_frodokem_640_aes'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F80'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo640shake'
+ nid: '0x0201'
+ nid_hybrid: '0x2F01'
+ oqs_alg: 'OQS_KEM_alg_frodokem_640_shake'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F81'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo976aes'
+ nid: '0x0202'
+ nid_hybrid: '0x2F02'
+ oqs_alg: 'OQS_KEM_alg_frodokem_976_aes'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F82'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo976shake'
+ nid: '0x0203'
+ nid_hybrid: '0x2F03'
+ oqs_alg: 'OQS_KEM_alg_frodokem_976_shake'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F83'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo1344aes'
+ nid: '0x0204'
+ nid_hybrid: '0x2F04'
+ oqs_alg: 'OQS_KEM_alg_frodokem_1344_aes'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo1344shake'
+ nid: '0x0205'
+ nid_hybrid: '0x2F05'
+ oqs_alg: 'OQS_KEM_alg_frodokem_1344_shake'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l1cpa'
+ bit_security: 128
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0206'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F06'
+ oqs_alg: 'OQS_KEM_alg_bike1_l1_cpa'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l3cpa'
+ bit_security: 192
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0207'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F07'
+ oqs_alg: 'OQS_KEM_alg_bike1_l3_cpa'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber512'
+ nid: '0x023A'
+ nid_hybrid: '0x2F3A'
+ oqs_alg: 'OQS_KEM_alg_kyber_512'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F39'
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x020F'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F0F'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: x25519
+ nid: '0x2F26'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber768'
+ nid: '0x023C'
+ nid_hybrid: '0x2F3C'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F90'
+ - hybrid_group: "x25519"
+ nid: '0x6399'
+ - hybrid_group: "p256"
+ nid: '0x639A'
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0210'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F10'
+ oqs_alg: 'OQS_KEM_alg_kyber_768'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber1024'
+ nid: '0x023D'
+ nid_hybrid: '0x2F3D'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0211'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp521_r1
+ nid: '0x2F11'
+ oqs_alg: 'OQS_KEM_alg_kyber_1024'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l1fo'
+ bit_security: 128
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0223'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F23'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: "x25519"
+ nid: '0x2F28'
+ oqs_alg: 'OQS_KEM_alg_bike1_l1_fo'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l3fo'
+ bit_security: 192
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0224'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F24'
+ oqs_alg: 'OQS_KEM_alg_bike1_l3_fo'
+ -
+ family: 'BIKE'
+ name_group: 'bikel1'
+ implementation_version: '5.1'
+ nid: '0x0241'
+ nid_hybrid: '0x2F41'
+ oqs_alg: 'OQS_KEM_alg_bike_l1'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FAE'
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x0238'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: x25519
+ nid: '0x2F37'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp256_r1
+ nid: '0x2F38'
+ -
+ family: 'BIKE'
+ name_group: 'bikel3'
+ implementation_version: '5.1'
+ nid: '0x0242'
+ nid_hybrid: '0x2F42'
+ oqs_alg: 'OQS_KEM_alg_bike_l3'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2FAF'
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x023B'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp384_r1
+ nid: '0x2F3B'
+ -
+ family: 'BIKE'
+ name_group: 'bikel5'
+ implementation_version: '5.1'
+ nid: '0x0243'
+ nid_hybrid: '0x2F43'
+ oqs_alg: 'OQS_KEM_alg_bike_l5'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber90s512'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0229'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F29'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x023E'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp256_r1
+ nid: '0x2F3E'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: x25519
+ nid: '0x2FA9'
+ oqs_alg: 'OQS_KEM_alg_kyber_512_90s'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber90s768'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x022A'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F2A'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x023F'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp384_r1
+ nid: '0x2F3F'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: x448
+ nid: '0x2FAA'
+ oqs_alg: 'OQS_KEM_alg_kyber_768_90s'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber90s1024'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x022B'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp521_r1
+ nid: '0x2F2B'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x0240'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp521_r1
+ nid: '0x2F40'
+ oqs_alg: 'OQS_KEM_alg_kyber_1024_90s'
+ -
+ family: 'HQC'
+ name_group: 'hqc128'
+ nid: '0x022C'
+ nid_hybrid: '0x2F2C'
+ oqs_alg: 'OQS_KEM_alg_hqc_128'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FAC'
+ -
+ family: 'HQC'
+ name_group: 'hqc192'
+ nid: '0x022D'
+ nid_hybrid: '0x2F2D'
+ oqs_alg: 'OQS_KEM_alg_hqc_192'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2FAD'
+ -
+ family: 'HQC'
+ name_group: 'hqc256'
+ nid: '0x022E'
+ nid_hybrid: '0x2F2E'
+ oqs_alg: 'OQS_KEM_alg_hqc_256'
+
+kem_nid_end: '0x0250'
+kem_nid_hybrid_end: '0x2FFF'
+# need to edit ssl_local.h macros IS_OQS_KEM_CURVEID and IS_OQS_KEM_HYBRID_CURVEID with the above _end values
+
+# Next free signature ID: 0xfed0
+sigs:
+ # -
+ # iso (1)
+ # identified-organization (3)
+ # reserved (9999)
+ # oqs_sig_default (1)
+ # disabled
+ #variants:
+ # -
+ # name: 'oqs_sig_default'
+ # pretty_name: 'OQS Default Signature Algorithm'
+ # oqs_meth: 'OQS_SIG_alg_default'
+ # oid: '1.3.9999.1.1'
+ # code_point: '0xfe00'
+ # enable: true
+ # mix_with: [{'name': 'p256',
+ # 'pretty_name': 'ECDSA p256',
+ # 'oid': '1.3.9999.1.2',
+ # 'code_point': '0xfe01'},
+ # {'name': 'rsa3072',
+ # 'pretty_name': 'RSA3072',
+ # 'oid': '1.3.9999.1.3',
+ # 'code_point': '0xfe02'}]
+ -
+ # OID scheme for hybrid variants of Dilithium:
+ # iso (1)
+ # identified-organization (3)
+ # reserved (9999)
+ # dilithium (2)
+ # OID scheme for plain Dilithium:
+ # iso (1)
+ # identified-organization (3)
+ # dod (6)
+ # internet (1)
+ # private (4)
+ # enterprise (1)
+ # IBM (2)
+ # qsc (267)
+ # Dilithium-r3 (7)
+ family: 'CRYSTALS-Dilithium'
+ variants:
+ -
+ name: 'dilithium2'
+ pretty_name: 'Dilithium2'
+ oqs_meth: 'OQS_SIG_alg_dilithium_2'
+ oid: '1.3.6.1.4.1.2.267.7.4.4'
+ code_point: '0xfea0'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.2.7.1',
+ 'code_point': '0xfea1'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.2.7.2',
+ 'code_point': '0xfea2'}]
+ -
+ name: 'dilithium3'
+ pretty_name: 'Dilithium3'
+ oqs_meth: 'OQS_SIG_alg_dilithium_3'
+ oid: '1.3.6.1.4.1.2.267.7.6.5'
+ code_point: '0xfea3'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.2.7.3',
+ 'code_point': '0xfea4'}]
+ -
+ name: 'dilithium5'
+ pretty_name: 'Dilithium5'
+ oqs_meth: 'OQS_SIG_alg_dilithium_5'
+ oid: '1.3.6.1.4.1.2.267.7.8.7'
+ code_point: '0xfea5'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.2.7.4',
+ 'code_point': '0xfea6'}]
+ -
+ name: 'dilithium2_aes'
+ pretty_name: 'Dilithium2_AES'
+ oqs_meth: 'OQS_SIG_alg_dilithium_2_aes'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.6.1.4.1.2.267.11.4.4'
+ code_point: '0xfea7'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.2.11.1',
+ 'code_point': '0xfea8'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.2.11.2',
+ 'code_point': '0xfea9'}]
+ -
+ name: 'dilithium3_aes'
+ pretty_name: 'Dilithium3_AES'
+ oqs_meth: 'OQS_SIG_alg_dilithium_3_aes'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.6.1.4.1.2.267.11.6.5'
+ code_point: '0xfeaa'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.2.11.3',
+ 'code_point': '0xfeab'}]
+ -
+ name: 'dilithium5_aes'
+ pretty_name: 'Dilithium5_AES'
+ oqs_meth: 'OQS_SIG_alg_dilithium_5_aes'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.6.1.4.1.2.267.11.8.7'
+ code_point: '0xfeac'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.2.11.4',
+ 'code_point': '0xfead'}]
+ -
+ # iso (1)
+ # identified-organization (3)
+ # reserved (9999)
+ # falcon (3)
+ family: 'Falcon'
+ variants:
+ -
+ name: 'falcon512'
+ pretty_name: 'Falcon-512'
+ oqs_meth: 'OQS_SIG_alg_falcon_512'
+ oid: '1.3.9999.3.6'
+ code_point: '0xfeae'
+ supported_encodings: ['draft-uni-qsckeys-falcon-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.3.7',
+ 'code_point': '0xfeaf'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.3.8',
+ 'code_point': '0xfeb0'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.3.1'
+ code_point: '0xfe0b'
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.3.2',
+ 'code_point': '0xfe0c'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.3.3',
+ 'code_point': '0xfe0d'}]
+ -
+ name: 'falcon1024'
+ pretty_name: 'Falcon-1024'
+ oqs_meth: 'OQS_SIG_alg_falcon_1024'
+ oid: '1.3.9999.3.9'
+ code_point: '0xfeb1'
+ supported_encodings: ['draft-uni-qsckeys-falcon-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.3.10',
+ 'code_point': '0xfeb2'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.3.4'
+ code_point: '0xfe0e'
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.3.5',
+ 'code_point': '0xfe0f'}]
+ -
+ family: 'SPHINCS-Haraka'
+ variants:
+ -
+ name: 'sphincsharaka128frobust'
+ pretty_name: 'SPHINCS+-Haraka-128f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.1.1'
+ code_point: '0xfe42'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.2',
+ 'code_point': '0xfe43'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.3',
+ 'code_point': '0xfe44'}]
+ -
+ name: 'sphincsharaka128fsimple'
+ pretty_name: 'SPHINCS+-Haraka-128f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128f_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.1.4'
+ code_point: '0xfe45'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.5',
+ 'code_point': '0xfe46'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.6',
+ 'code_point': '0xfe47'}]
+ -
+ name: 'sphincsharaka128srobust'
+ pretty_name: 'SPHINCS+-Haraka-128s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.1.7'
+ code_point: '0xfe48'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.8',
+ 'code_point': '0xfe49'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.9',
+ 'code_point': '0xfe4a'}]
+ -
+ name: 'sphincsharaka128ssimple'
+ pretty_name: 'SPHINCS+-Haraka-128s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128s_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.1.10'
+ code_point: '0xfe4b'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.11',
+ 'code_point': '0xfe4c'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.12',
+ 'code_point': '0xfe4d'}]
+ -
+ name: 'sphincsharaka192frobust'
+ pretty_name: 'SPHINCS+-Haraka-192f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.2.1'
+ code_point: '0xfe4e'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.2',
+ 'code_point': '0xfe4f'}]
+ -
+ name: 'sphincsharaka192fsimple'
+ pretty_name: 'SPHINCS+-Haraka-192f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192f_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.2.3'
+ code_point: '0xfe50'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.4',
+ 'code_point': '0xfe51'}]
+ -
+ name: 'sphincsharaka192srobust'
+ pretty_name: 'SPHINCS+-Haraka-192s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.2.5'
+ code_point: '0xfe52'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.6',
+ 'code_point': '0xfe53'}]
+ -
+ name: 'sphincsharaka192ssimple'
+ pretty_name: 'SPHINCS+-Haraka-192s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192s_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.2.7'
+ code_point: '0xfe54'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.8',
+ 'code_point': '0xfe55'}]
+ -
+ name: 'sphincsharaka256frobust'
+ pretty_name: 'SPHINCS+-Haraka-256f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.3.1'
+ code_point: '0xfe56'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.2',
+ 'code_point': '0xfe57'}]
+ -
+ name: 'sphincsharaka256fsimple'
+ pretty_name: 'SPHINCS+-Haraka-256f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256f_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.3.3'
+ code_point: '0xfe58'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.4',
+ 'code_point': '0xfe59'}]
+ -
+ name: 'sphincsharaka256srobust'
+ pretty_name: 'SPHINCS+-Haraka-256s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.3.5'
+ code_point: '0xfe5a'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.6',
+ 'code_point': '0xfe5b'}]
+ -
+ name: 'sphincsharaka256ssimple'
+ pretty_name: 'SPHINCS+-Haraka-256s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256s_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.3.7'
+ code_point: '0xfe5c'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.8',
+ 'code_point': '0xfe5d'}]
+ -
+ family: 'SPHINCS-SHA2'
+ variants:
+ -
+ name: 'sphincssha26128frobust'
+ pretty_name: 'SPHINCS+-SHA256-128f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_128f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.4.1'
+ code_point: '0xfe5e'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.2',
+ 'code_point': '0xfe5f'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.3',
+ 'code_point': '0xfe60'}]
+ -
+ name: 'sphincssha2128fsimple'
+ pretty_name: 'SPHINCS+-SHA2-128f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_128f_simple'
+ oid: '1.3.9999.6.4.13'
+ code_point: '0xfeb3'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.14',
+ 'code_point': '0xfeb4'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.15',
+ 'code_point': '0xfeb5'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.4.4'
+ code_point: '0xfe61'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.5',
+ 'code_point': '0xfe62'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.6',
+ 'code_point': '0xfe63'}]
+ -
+ name: 'sphincssha256128srobust'
+ pretty_name: 'SPHINCS+-SHA256-128s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_128s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.4.7'
+ code_point: '0xfe64'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.8',
+ 'code_point': '0xfe65'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.9',
+ 'code_point': '0xfe66'}]
+ -
+ name: 'sphincssha2128ssimple'
+ pretty_name: 'SPHINCS+-SHA2-128s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_128s_simple'
+ oid: '1.3.9999.6.4.16'
+ code_point: '0xfeb6'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.17',
+ 'code_point': '0xfeb7'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.18',
+ 'code_point': '0xfeb8'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.4.10'
+ code_point: '0xfe67'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.11',
+ 'code_point': '0xfe68'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.12',
+ 'code_point': '0xfe69'}]
+ -
+ name: 'sphincssha256192frobust'
+ pretty_name: 'SPHINCS+-SHA256-192f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_192f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.5.1'
+ code_point: '0xfe6a'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.2',
+ 'code_point': '0xfe6b'}]
+ -
+ name: 'sphincssha2192fsimple'
+ pretty_name: 'SPHINCS+-SHA2-192f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_192f_simple'
+ oid: '1.3.9999.6.5.10'
+ code_point: '0xfeb9'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.11',
+ 'code_point': '0xfeba'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.5.3'
+ code_point: '0xfe6c'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.4',
+ 'code_point': '0xfe6d'}]
+ -
+ name: 'sphincssha256192srobust'
+ pretty_name: 'SPHINCS+-SHA256-192s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_192s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.5.5'
+ code_point: '0xfe6e'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.6',
+ 'code_point': '0xfe6f'}]
+ -
+ name: 'sphincssha2192ssimple'
+ pretty_name: 'SPHINCS+-SHA2-192s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_192s_simple'
+ oid: '1.3.9999.6.5.12'
+ code_point: '0xfebb'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.13',
+ 'code_point': '0xfebc'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.5.7'
+ code_point: '0xfe70'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.8',
+ 'code_point': '0xfe71'}]
+ -
+ name: 'sphincssha256256frobust'
+ pretty_name: 'SPHINCS+-SHA256-256f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_256f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.6.1'
+ code_point: '0xfe72'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.2',
+ 'code_point': '0xfe73'}]
+ -
+ name: 'sphincssha2256fsimple'
+ pretty_name: 'SPHINCS+-SHA2-256f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_256f_simple'
+ oid: '1.3.9999.6.6.10'
+ code_point: '0xfebd'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.11',
+ 'code_point': '0xfebe'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.6.3'
+ code_point: '0xfe74'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.4',
+ 'code_point': '0xfe75'}]
+ -
+ name: 'sphincssha256256srobust'
+ pretty_name: 'SPHINCS+-SHA256-256s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_256s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.6.5'
+ code_point: '0xfe76'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.6',
+ 'code_point': '0xfe77'}]
+ -
+ name: 'sphincssha2256ssimple'
+ pretty_name: 'SPHINCS+-SHA2-256s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_256s_simple'
+ oid: '1.3.9999.6.6.12'
+ code_point: '0xfec0'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.13',
+ 'code_point': '0xfec1'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.6.7'
+ code_point: '0xfe78'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.8',
+ 'code_point': '0xfe79'}]
+ -
+ family: 'SPHINCS-SHAKE'
+ variants:
+ -
+ name: 'sphincsshake256128frobust'
+ pretty_name: 'SPHINCS+-SHAKE256-128f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_128f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.7.1'
+ code_point: '0xfe7a'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.2',
+ 'code_point': '0xfe7b'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.3',
+ 'code_point': '0xfe7c'}]
+ -
+ name: 'sphincsshake128fsimple'
+ pretty_name: 'SPHINCS+-SHAKE-128f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_128f_simple'
+ oid: '1.3.9999.6.7.13'
+ code_point: '0xfec2'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.14',
+ 'code_point': '0xfec3'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.15',
+ 'code_point': '0xfec4'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.7.4'
+ code_point: '0xfe7d'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.5',
+ 'code_point': '0xfe7e'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.6',
+ 'code_point': '0xfe7f'}]
+ -
+ name: 'sphincsshake256128srobust'
+ pretty_name: 'SPHINCS+-SHAKE256-128s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_128s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.7.7'
+ code_point: '0xfe80'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.8',
+ 'code_point': '0xfe81'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.9',
+ 'code_point': '0xfe82'}]
+ -
+ name: 'sphincsshake128ssimple'
+ pretty_name: 'SPHINCS+-SHAKE-128s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_128s_simple'
+ oid: '1.3.9999.6.7.16'
+ code_point: '0xfec5'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.17',
+ 'code_point': '0xfec6'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.18',
+ 'code_point': '0xfec7'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.7.10'
+ code_point: '0xfe83'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.11',
+ 'code_point': '0xfe84'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.12',
+ 'code_point': '0xfe85'}]
+ -
+ name: 'sphincsshake256192frobust'
+ pretty_name: 'SPHINCS+-SHAKE256-192f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_192f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.8.1'
+ code_point: '0xfe86'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.2',
+ 'code_point': '0xfe87'}]
+ -
+ name: 'sphincsshake192fsimple'
+ pretty_name: 'SPHINCS+-SHAKE-192f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_192f_simple'
+ oid: '1.3.9999.6.8.10'
+ code_point: '0xfec8'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.11',
+ 'code_point': '0xfec9'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.8.3'
+ code_point: '0xfe88'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.4',
+ 'code_point': '0xfe89'}]
+ -
+ name: 'sphincsshake256192srobust'
+ pretty_name: 'SPHINCS+-SHAKE256-192s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_192s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.8.5'
+ code_point: '0xfe8a'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.6',
+ 'code_point': '0xfe8b'}]
+ -
+ name: 'sphincsshake192ssimple'
+ pretty_name: 'SPHINCS+-SHAKE-192s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_192s_simple'
+ oid: '1.3.9999.6.8.12'
+ code_point: '0xfeca'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.13',
+ 'code_point': '0xfecb'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.8.7'
+ code_point: '0xfe8c'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.8',
+ 'code_point': '0xfe8d'}]
+ -
+ name: 'sphincsshake256256frobust'
+ pretty_name: 'SPHINCS+-SHAKE256-256f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_256f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.9.1'
+ code_point: '0xfe8e'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.2',
+ 'code_point': '0xfe8f'}]
+ -
+ name: 'sphincsshake256fsimple'
+ pretty_name: 'SPHINCS+-SHAKE-256f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_256f_simple'
+ oid: '1.3.9999.6.9.10'
+ code_point: '0xfecc'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.11',
+ 'code_point': '0xfecd'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.9.3'
+ code_point: '0xfe90'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.4',
+ 'code_point': '0xfe91'}]
+ -
+ name: 'sphincsshake256256srobust'
+ pretty_name: 'SPHINCS+-SHAKE256-256s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_256s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.9.5'
+ code_point: '0xfe92'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.6',
+ 'code_point': '0xfe93'}]
+ -
+ name: 'sphincsshake256ssimple'
+ pretty_name: 'SPHINCS+-SHAKE-256s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_256s_simple'
+ oid: '1.3.9999.6.9.12'
+ code_point: '0xfece'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.13',
+ 'code_point': '0xfecf'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.9.7'
+ code_point: '0xfe94'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.8',
+ 'code_point': '0xfe95'}]
+
+
--- /dev/null
+# N.B: For interoperability, NIDS must match the curve IDs used in
+# https://docs.google.com/spreadsheets/d/12YarzaNv3XQNLnvDsWLlRKwtZFhRrDdWf36YlzwrPeg/edit#gid=0
+kems:
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo640aes'
+ nid: '0x0200'
+ nid_hybrid: '0x2F00'
+ oqs_alg: 'OQS_KEM_alg_frodokem_640_aes'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F80'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo640shake'
+ nid: '0x0201'
+ nid_hybrid: '0x2F01'
+ oqs_alg: 'OQS_KEM_alg_frodokem_640_shake'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F81'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo976aes'
+ nid: '0x0202'
+ nid_hybrid: '0x2F02'
+ oqs_alg: 'OQS_KEM_alg_frodokem_976_aes'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F82'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo976shake'
+ nid: '0x0203'
+ nid_hybrid: '0x2F03'
+ oqs_alg: 'OQS_KEM_alg_frodokem_976_shake'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F83'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo1344aes'
+ nid: '0x0204'
+ nid_hybrid: '0x2F04'
+ oqs_alg: 'OQS_KEM_alg_frodokem_1344_aes'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo1344shake'
+ nid: '0x0205'
+ nid_hybrid: '0x2F05'
+ oqs_alg: 'OQS_KEM_alg_frodokem_1344_shake'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l1cpa'
+ bit_security: 128
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0206'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F06'
+ oqs_alg: 'OQS_KEM_alg_bike1_l1_cpa'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l3cpa'
+ bit_security: 192
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0207'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F07'
+ oqs_alg: 'OQS_KEM_alg_bike1_l3_cpa'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber512'
+ nid: '0x023A'
+ nid_hybrid: '0x2F3A'
+ oqs_alg: 'OQS_KEM_alg_kyber_512'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F39'
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x020F'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F0F'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: x25519
+ nid: '0x2F26'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber768'
+ nid: '0x023C'
+ nid_hybrid: '0x2F3C'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F90'
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0210'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F10'
+ oqs_alg: 'OQS_KEM_alg_kyber_768'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber1024'
+ nid: '0x023D'
+ nid_hybrid: '0x2F3D'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0211'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp521_r1
+ nid: '0x2F11'
+ oqs_alg: 'OQS_KEM_alg_kyber_1024'
+ -
+ family: 'NTRU'
+ name_group: 'ntru_hps2048509'
+ nid: '0x0214'
+ nid_hybrid: '0x2F14'
+ oqs_alg: 'OQS_KEM_alg_ntru_hps2048509'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F94'
+ -
+ family: 'NTRU'
+ name_group: 'ntru_hps2048677'
+ nid: '0x0215'
+ nid_hybrid: '0x2F15'
+ oqs_alg: 'OQS_KEM_alg_ntru_hps2048677'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F95'
+ -
+ family: 'NTRU'
+ name_group: 'ntru_hps4096821'
+ nid: '0x0216'
+ nid_hybrid: '0x2F16'
+ oqs_alg: 'OQS_KEM_alg_ntru_hps4096821'
+ -
+ family: 'NTRU'
+ name_group: 'ntru_hps40961229'
+ nid: '0x0245'
+ nid_hybrid: '0x2F45'
+ oqs_alg: 'OQS_KEM_alg_ntru_hps40961229'
+ -
+ family: 'NTRU'
+ name_group: 'ntru_hrss701'
+ nid: '0x0217'
+ nid_hybrid: '0x2F17'
+ oqs_alg: 'OQS_KEM_alg_ntru_hrss701'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F97'
+ -
+ family: 'NTRU'
+ name_group: 'ntru_hrss1373'
+ nid: '0x0246'
+ nid_hybrid: '0x2F46'
+ oqs_alg: 'OQS_KEM_alg_ntru_hrss1373'
+ -
+ family: 'SABER'
+ name_group: 'lightsaber'
+ nid: '0x0218'
+ nid_hybrid: '0x2F18'
+ oqs_alg: 'OQS_KEM_alg_saber_lightsaber'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F98'
+ -
+ family: 'SABER'
+ name_group: 'saber'
+ nid: '0x0219'
+ nid_hybrid: '0x2F19'
+ oqs_alg: 'OQS_KEM_alg_saber_saber'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F99'
+ -
+ family: 'SABER'
+ name_group: 'firesaber'
+ nid: '0x021A'
+ nid_hybrid: '0x2F1A'
+ oqs_alg: 'OQS_KEM_alg_saber_firesaber'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l1fo'
+ bit_security: 128
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0223'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F23'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: "x25519"
+ nid: '0x2F28'
+ oqs_alg: 'OQS_KEM_alg_bike1_l1_fo'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l3fo'
+ bit_security: 192
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0224'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F24'
+ oqs_alg: 'OQS_KEM_alg_bike1_l3_fo'
+ -
+ family: 'BIKE'
+ name_group: 'bikel1'
+ implementation_version: '4.1'
+ nid: '0x0238'
+ nid_hybrid: '0x2F38'
+ oqs_alg: 'OQS_KEM_alg_bike_l1'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F37'
+ implementation_version: '4.1'
+ -
+ family: 'BIKE'
+ name_group: 'bikel3'
+ implementation_version: '4.1'
+ nid: '0x023B'
+ nid_hybrid: '0x2F3B'
+ oqs_alg: 'OQS_KEM_alg_bike_l3'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber90s512'
+ nid: '0x023E'
+ nid_hybrid: '0x2F3E'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FA9'
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0229'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F29'
+ oqs_alg: 'OQS_KEM_alg_kyber_512_90s'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber90s768'
+ nid: '0x023F'
+ nid_hybrid: '0x2F3F'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2FAA'
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x022A'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F2A'
+ oqs_alg: 'OQS_KEM_alg_kyber_768_90s'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber90s1024'
+ nid: '0x0240'
+ nid_hybrid: '0x2F40'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x022B'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp521_r1
+ nid: '0x2F2B'
+ oqs_alg: 'OQS_KEM_alg_kyber_1024_90s'
+ -
+ family: 'HQC'
+ name_group: 'hqc128'
+ nid: '0x022C'
+ nid_hybrid: '0x2F2C'
+ oqs_alg: 'OQS_KEM_alg_hqc_128'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FAC'
+ -
+ family: 'HQC'
+ name_group: 'hqc192'
+ nid: '0x022D'
+ nid_hybrid: '0x2F2D'
+ oqs_alg: 'OQS_KEM_alg_hqc_192'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2FAD'
+ -
+ family: 'HQC'
+ name_group: 'hqc256'
+ nid: '0x022E'
+ nid_hybrid: '0x2F2E'
+ oqs_alg: 'OQS_KEM_alg_hqc_256'
+ -
+ family: 'NTRU-Prime'
+ name_group: 'ntrulpr653'
+ nid: '0x022F'
+ nid_hybrid: '0x2F2F'
+ oqs_alg: 'OQS_KEM_alg_ntruprime_ntrulpr653'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FAF'
+ -
+ family: 'NTRU-Prime'
+ name_group: 'ntrulpr761'
+ nid: '0x0230'
+ nid_hybrid: '0x2F43'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FB0'
+ old:
+ - implementation_version: Round 3 p384 hybrid
+ nist-round: 3
+ nid: '0x2F30'
+ oqs_alg: 'OQS_KEM_alg_ntruprime_ntrulpr761'
+ -
+ family: 'NTRU-Prime'
+ name_group: 'ntrulpr857'
+ nid: '0x0231'
+ nid_hybrid: '0x2F31'
+ oqs_alg: 'OQS_KEM_alg_ntruprime_ntrulpr857'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2FB1'
+ -
+ family: 'NTRU-Prime'
+ name_group: 'ntrulpr1277'
+ nid: '0x0241'
+ nid_hybrid: '0x2F41'
+ oqs_alg: 'OQS_KEM_alg_ntruprime_ntrulpr1277'
+ -
+ family: 'NTRU-Prime'
+ name_group: 'sntrup653'
+ nid: '0x0232'
+ nid_hybrid: '0x2F32'
+ oqs_alg: 'OQS_KEM_alg_ntruprime_sntrup653'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FB2'
+ -
+ family: 'NTRU-Prime'
+ name_group: 'sntrup761'
+ nid: '0x0233'
+ nid_hybrid: '0x2F44'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FB3'
+ old:
+ - implementation_version: Round 3 p384 hybrid
+ nist-round: 3
+ nid: '0x2F33'
+ oqs_alg: 'OQS_KEM_alg_ntruprime_sntrup761'
+ -
+ family: 'NTRU-Prime'
+ name_group: 'sntrup857'
+ nid: '0x0234'
+ nid_hybrid: '0x2F34'
+ oqs_alg: 'OQS_KEM_alg_ntruprime_sntrup857'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2FB4'
+ -
+ family: 'NTRU-Prime'
+ name_group: 'sntrup1277'
+ nid: '0x0242'
+ nid_hybrid: '0x2F42'
+ oqs_alg: 'OQS_KEM_alg_ntruprime_sntrup1277'
+
+kem_nid_end: '0x0250'
+kem_nid_hybrid_end: '0x2FFF'
+# need to edit ssl_local.h macros IS_OQS_KEM_CURVEID and IS_OQS_KEM_HYBRID_CURVEID with the above _end values
+
+# N.B: For interoperability, code-points and OIDs must match those used in
+# https://docs.google.com/spreadsheets/d/12YarzaNv3XQNLnvDsWLlRKwtZFhRrDdWf36YlzwrPeg/edit#gid=0
+sigs:
+ # -
+ # iso (1)
+ # identified-organization (3)
+ # reserved (9999)
+ # oqs_sig_default (1)
+ # disabled
+ #variants:
+ # -
+ # name: 'oqs_sig_default'
+ # pretty_name: 'OQS Default Signature Algorithm'
+ # oqs_meth: 'OQS_SIG_alg_default'
+ # oid: '1.3.9999.1.1'
+ # code_point: '0xfe00'
+ # enable: true
+ # mix_with: [{'name': 'p256',
+ # 'pretty_name': 'ECDSA p256',
+ # 'oid': '1.3.9999.1.2',
+ # 'code_point': '0xfe01'},
+ # {'name': 'rsa3072',
+ # 'pretty_name': 'RSA3072',
+ # 'oid': '1.3.9999.1.3',
+ # 'code_point': '0xfe02'}]
+ -
+ # OID scheme for hybrid variants of Dilithium:
+ # iso (1)
+ # identified-organization (3)
+ # reserved (9999)
+ # dilithium (2)
+ # OID scheme for plain Dilithium:
+ # iso (1)
+ # identified-organization (3)
+ # dod (6)
+ # internet (1)
+ # private (4)
+ # enterprise (1)
+ # IBM (2)
+ # qsc (267)
+ # Dilithium-r3 (7)
+ family: 'CRYSTALS-Dilithium'
+ variants:
+ -
+ name: 'dilithium2'
+ pretty_name: 'Dilithium2'
+ oqs_meth: 'OQS_SIG_alg_dilithium_2'
+ oid: '1.3.6.1.4.1.2.267.7.4.4'
+ code_point: '0xfea0'
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.2.7.1',
+ 'code_point': '0xfea1'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.2.7.2',
+ 'code_point': '0xfea2'}]
+ -
+ name: 'dilithium3'
+ pretty_name: 'Dilithium3'
+ oqs_meth: 'OQS_SIG_alg_dilithium_3'
+ oid: '1.3.6.1.4.1.2.267.7.6.5'
+ code_point: '0xfea3'
+ enable: true
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.2.7.3',
+ 'code_point': '0xfea4'}]
+ -
+ name: 'dilithium5'
+ pretty_name: 'Dilithium5'
+ oqs_meth: 'OQS_SIG_alg_dilithium_5'
+ oid: '1.3.6.1.4.1.2.267.7.8.7'
+ code_point: '0xfea5'
+ enable: true
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.2.7.4',
+ 'code_point': '0xfea6'}]
+ -
+ name: 'dilithium2_aes'
+ pretty_name: 'Dilithium2_AES'
+ oqs_meth: 'OQS_SIG_alg_dilithium_2_aes'
+ oid: '1.3.6.1.4.1.2.267.11.4.4'
+ code_point: '0xfea7'
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.2.11.1',
+ 'code_point': '0xfea8'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.2.11.2',
+ 'code_point': '0xfea9'}]
+ -
+ name: 'dilithium3_aes'
+ pretty_name: 'Dilithium3_AES'
+ oqs_meth: 'OQS_SIG_alg_dilithium_3_aes'
+ oid: '1.3.6.1.4.1.2.267.11.6.5'
+ code_point: '0xfeaa'
+ enable: true
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.2.11.3',
+ 'code_point': '0xfeab'}]
+ -
+ name: 'dilithium5_aes'
+ pretty_name: 'Dilithium5_AES'
+ oqs_meth: 'OQS_SIG_alg_dilithium_5_aes'
+ oid: '1.3.6.1.4.1.2.267.11.8.7'
+ code_point: '0xfeac'
+ enable: true
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.2.11.4',
+ 'code_point': '0xfead'}]
+ -
+ # iso (1)
+ # identified-organization (3)
+ # reserved (9999)
+ # falcon (3)
+ family: 'Falcon'
+ variants:
+ -
+ name: 'falcon512'
+ pretty_name: 'Falcon-512'
+ oqs_meth: 'OQS_SIG_alg_falcon_512'
+ oid: '1.3.9999.3.1'
+ code_point: '0xfe0b'
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.3.2',
+ 'code_point': '0xfe0c'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.3.3',
+ 'code_point': '0xfe0d'}]
+ -
+ name: 'falcon1024'
+ pretty_name: 'Falcon-1024'
+ oqs_meth: 'OQS_SIG_alg_falcon_1024'
+ oid: '1.3.9999.3.4'
+ code_point: '0xfe0e'
+ enable: true
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.3.5',
+ 'code_point': '0xfe0f'}]
+ -
+ # iso (1)
+ # identified-organization (3)
+ # dod (6)
+ # internet (1)
+ # private (4)
+ # enterprise (1)
+ # Microsoft (311)
+ # MSRCrypto (89)
+ # PQC (2)
+ # picnic (1)
+ family: 'Picnic'
+ variants:
+ -
+ name: 'picnicl1fs'
+ pretty_name: 'Picnic L1 FS'
+ oqs_meth: 'OQS_SIG_alg_picnic_L1_FS'
+ oid: '1.3.6.1.4.1.311.89.2.1.1'
+ code_point: '0xfe15'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.2',
+ 'code_point': '0xfe16'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.3',
+ 'code_point': '0xfe17'}]
+ -
+ name: 'picnicl1ur'
+ pretty_name: 'Picnic L1 UR'
+ oqs_meth: 'OQS_SIG_alg_picnic_L1_UR'
+ oid: '1.3.6.1.4.1.311.89.2.1.4'
+ code_point: '0xfe18'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.5',
+ 'code_point': '0xfe19'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.6',
+ 'code_point': '0xfe1a'}]
+ -
+ name: 'picnicl1full'
+ pretty_name: 'Picnic L1 full'
+ oqs_meth: 'OQS_SIG_alg_picnic_L1_full'
+ oid: '1.3.6.1.4.1.311.89.2.1.7'
+ code_point: '0xfe96'
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.8',
+ 'code_point': '0xfe97'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.9',
+ 'code_point': '0xfe98'}]
+ -
+ name: 'picnic3l1'
+ pretty_name: 'Picnic3 L1'
+ oqs_meth: 'OQS_SIG_alg_picnic3_L1'
+ oid: '1.3.6.1.4.1.311.89.2.1.21'
+ code_point: '0xfe1b'
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.22',
+ 'code_point': '0xfe1c'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.23',
+ 'code_point': '0xfe1d'}]
+ -
+ name: 'picnic3l3'
+ pretty_name: 'Picnic3 L3'
+ oqs_meth: 'OQS_SIG_alg_picnic3_L3'
+ oid: '1.3.6.1.4.1.311.89.2.1.24'
+ code_point: '0xfe1e'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.25',
+ 'code_point': '0xfe1f'}]
+ -
+ name: 'picnic3l5'
+ pretty_name: 'Picnic3 L5'
+ oqs_meth: 'OQS_SIG_alg_picnic3_L5'
+ oid: '1.3.6.1.4.1.311.89.2.1.26'
+ code_point: '0xfe20'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.6.1.4.1.311.89.2.1.27',
+ 'code_point': '0xfe21'}]
+ -
+ family: 'Rainbow'
+ variants:
+ -
+ name: 'rainbowIclassic'
+ pretty_name: 'Rainbow-I-Classic'
+ oqs_meth: 'OQS_SIG_alg_rainbow_I_classic'
+ extra_oids:
+ nist-round: 3
+ oid: '1.3.9999.5.1.1.1'
+ code_point: '0xfe27'
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.5.1.2.1',
+ 'code_point': '0xfe28'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.5.1.3.1',
+ 'code_point': '0xfe29'}]
+ -
+ name: 'rainbowIcircumzenithal'
+ pretty_name: 'Rainbow-I-Circumzenithal'
+ oqs_meth: 'OQS_SIG_alg_rainbow_I_circumzenithal'
+ extra_oids:
+ nist-round: 3
+ oid: '1.3.9999.5.1.4.1'
+ code_point: '0xfe30'
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.5.1.5.1',
+ 'code_point': '0xfe31'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.5.1.6.1',
+ 'code_point': '0xfe32'}]
+ -
+ name: 'rainbowIcompressed'
+ pretty_name: 'Rainbow-I-Compressed'
+ oqs_meth: 'OQS_SIG_alg_rainbow_I_compressed'
+ extra_oids:
+ nist-round: 3
+ oid: '1.3.9999.5.1.7.1'
+ code_point: '0xfe33'
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.5.1.8.1',
+ 'code_point': '0xfe34'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.5.1.9.1',
+ 'code_point': '0xfe35'}]
+ -
+ name: 'rainbowIIIclassic'
+ pretty_name: 'Rainbow-III-Classic'
+ oqs_meth: 'OQS_SIG_alg_rainbow_III_classic'
+ oid: '1.3.9999.5.2.1.1'
+ code_point: '0xfe36'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.5.2.2.1',
+ 'code_point': '0xfe37'}]
+ -
+ name: 'rainbowIIIcircumzenithal'
+ pretty_name: 'Rainbow-III-Circumzenithal'
+ oqs_meth: 'OQS_SIG_alg_rainbow_III_circumzenithal'
+ oid: '1.3.9999.5.2.3.1'
+ code_point: '0xfe38'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.5.2.4.1',
+ 'code_point': '0xfe39'}]
+ -
+ name: 'rainbowIIIcompressed'
+ pretty_name: 'Rainbow-III-Compressed'
+ oqs_meth: 'OQS_SIG_alg_rainbow_III_compressed'
+ oid: '1.3.9999.5.2.5.1'
+ code_point: '0xfe3a'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.5.2.6.1',
+ 'code_point': '0xfe3b'}]
+ -
+ name: 'rainbowVclassic'
+ pretty_name: 'Rainbow-V-Classic'
+ oqs_meth: 'OQS_SIG_alg_rainbow_V_classic'
+ oid: '1.3.9999.5.3.1.1'
+ code_point: '0xfe3c'
+ enable: true
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.5.3.2.1',
+ 'code_point': '0xfe3d'}]
+ -
+ name: 'rainbowVcircumzenithal'
+ pretty_name: 'Rainbow-V-Circumzenithal'
+ oqs_meth: 'OQS_SIG_alg_rainbow_V_circumzenithal'
+ oid: '1.3.9999.5.3.3.1'
+ code_point: '0xfe3e'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.5.3.4.1',
+ 'code_point': '0xfe3f'}]
+ -
+ name: 'rainbowVcompressed'
+ pretty_name: 'Rainbow-V-Compressed'
+ oqs_meth: 'OQS_SIG_alg_rainbow_V_compressed'
+ oid: '1.3.9999.5.3.5.1'
+ code_point: '0xfe40'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.5.3.6.1',
+ 'code_point': '0xfe41'}]
+ -
+ family: 'SPHINCS-Haraka'
+ variants:
+ -
+ name: 'sphincsharaka128frobust'
+ pretty_name: 'SPHINCS+-Haraka-128f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128f_robust'
+ oid: '1.3.9999.6.1.1'
+ code_point: '0xfe42'
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.2',
+ 'code_point': '0xfe43'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.3',
+ 'code_point': '0xfe44'}]
+ -
+ name: 'sphincsharaka128fsimple'
+ pretty_name: 'SPHINCS+-Haraka-128f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128f_simple'
+ oid: '1.3.9999.6.1.4'
+ code_point: '0xfe45'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.5',
+ 'code_point': '0xfe46'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.6',
+ 'code_point': '0xfe47'}]
+ -
+ name: 'sphincsharaka128srobust'
+ pretty_name: 'SPHINCS+-Haraka-128s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128s_robust'
+ oid: '1.3.9999.6.1.7'
+ code_point: '0xfe48'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.8',
+ 'code_point': '0xfe49'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.9',
+ 'code_point': '0xfe4a'}]
+ -
+ name: 'sphincsharaka128ssimple'
+ pretty_name: 'SPHINCS+-Haraka-128s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128s_simple'
+ oid: '1.3.9999.6.1.10'
+ code_point: '0xfe4b'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.11',
+ 'code_point': '0xfe4c'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.12',
+ 'code_point': '0xfe4d'}]
+ -
+ name: 'sphincsharaka192frobust'
+ pretty_name: 'SPHINCS+-Haraka-192f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192f_robust'
+ oid: '1.3.9999.6.2.1'
+ code_point: '0xfe4e'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.2',
+ 'code_point': '0xfe4f'}]
+ -
+ name: 'sphincsharaka192fsimple'
+ pretty_name: 'SPHINCS+-Haraka-192f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192f_simple'
+ oid: '1.3.9999.6.2.3'
+ code_point: '0xfe50'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.4',
+ 'code_point': '0xfe51'}]
+ -
+ name: 'sphincsharaka192srobust'
+ pretty_name: 'SPHINCS+-Haraka-192s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192s_robust'
+ oid: '1.3.9999.6.2.5'
+ code_point: '0xfe52'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.6',
+ 'code_point': '0xfe53'}]
+ -
+ name: 'sphincsharaka192ssimple'
+ pretty_name: 'SPHINCS+-Haraka-192s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192s_simple'
+ oid: '1.3.9999.6.2.7'
+ code_point: '0xfe54'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.8',
+ 'code_point': '0xfe55'}]
+ -
+ name: 'sphincsharaka256frobust'
+ pretty_name: 'SPHINCS+-Haraka-256f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256f_robust'
+ oid: '1.3.9999.6.3.1'
+ code_point: '0xfe56'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.2',
+ 'code_point': '0xfe57'}]
+ -
+ name: 'sphincsharaka256fsimple'
+ pretty_name: 'SPHINCS+-Haraka-256f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256f_simple'
+ oid: '1.3.9999.6.3.3'
+ code_point: '0xfe58'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.4',
+ 'code_point': '0xfe59'}]
+ -
+ name: 'sphincsharaka256srobust'
+ pretty_name: 'SPHINCS+-Haraka-256s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256s_robust'
+ oid: '1.3.9999.6.3.5'
+ code_point: '0xfe5a'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.6',
+ 'code_point': '0xfe5b'}]
+ -
+ name: 'sphincsharaka256ssimple'
+ pretty_name: 'SPHINCS+-Haraka-256s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256s_simple'
+ oid: '1.3.9999.6.3.7'
+ code_point: '0xfe5c'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.8',
+ 'code_point': '0xfe5d'}]
+ -
+ family: 'SPHINCS-SHA256'
+ variants:
+ -
+ name: 'sphincssha256128frobust'
+ pretty_name: 'SPHINCS+-SHA256-128f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_128f_robust'
+ oid: '1.3.9999.6.4.1'
+ code_point: '0xfe5e'
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.2',
+ 'code_point': '0xfe5f'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.3',
+ 'code_point': '0xfe60'}]
+ -
+ name: 'sphincssha256128fsimple'
+ pretty_name: 'SPHINCS+-SHA256-128f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_128f_simple'
+ oid: '1.3.9999.6.4.4'
+ code_point: '0xfe61'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.5',
+ 'code_point': '0xfe62'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.6',
+ 'code_point': '0xfe63'}]
+ -
+ name: 'sphincssha256128srobust'
+ pretty_name: 'SPHINCS+-SHA256-128s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_128s_robust'
+ oid: '1.3.9999.6.4.7'
+ code_point: '0xfe64'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.8',
+ 'code_point': '0xfe65'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.9',
+ 'code_point': '0xfe66'}]
+ -
+ name: 'sphincssha256128ssimple'
+ pretty_name: 'SPHINCS+-SHA256-128s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_128s_simple'
+ oid: '1.3.9999.6.4.10'
+ code_point: '0xfe67'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.11',
+ 'code_point': '0xfe68'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.12',
+ 'code_point': '0xfe69'}]
+ -
+ name: 'sphincssha256192frobust'
+ pretty_name: 'SPHINCS+-SHA256-192f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_192f_robust'
+ oid: '1.3.9999.6.5.1'
+ code_point: '0xfe6a'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.2',
+ 'code_point': '0xfe6b'}]
+ -
+ name: 'sphincssha256192fsimple'
+ pretty_name: 'SPHINCS+-SHA256-192f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_192f_simple'
+ oid: '1.3.9999.6.5.3'
+ code_point: '0xfe6c'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.4',
+ 'code_point': '0xfe6d'}]
+ -
+ name: 'sphincssha256192srobust'
+ pretty_name: 'SPHINCS+-SHA256-192s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_192s_robust'
+ oid: '1.3.9999.6.5.5'
+ code_point: '0xfe6e'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.6',
+ 'code_point': '0xfe6f'}]
+ -
+ name: 'sphincssha256192ssimple'
+ pretty_name: 'SPHINCS+-SHA256-192s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_192s_simple'
+ oid: '1.3.9999.6.5.7'
+ code_point: '0xfe70'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.8',
+ 'code_point': '0xfe71'}]
+ -
+ name: 'sphincssha256256frobust'
+ pretty_name: 'SPHINCS+-SHA256-256f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_256f_robust'
+ oid: '1.3.9999.6.6.1'
+ code_point: '0xfe72'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.2',
+ 'code_point': '0xfe73'}]
+ -
+ name: 'sphincssha256256fsimple'
+ pretty_name: 'SPHINCS+-SHA256-256f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_256f_simple'
+ oid: '1.3.9999.6.6.3'
+ code_point: '0xfe74'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.4',
+ 'code_point': '0xfe75'}]
+ -
+ name: 'sphincssha256256srobust'
+ pretty_name: 'SPHINCS+-SHA256-256s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_256s_robust'
+ oid: '1.3.9999.6.6.5'
+ code_point: '0xfe76'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.6',
+ 'code_point': '0xfe77'}]
+ -
+ name: 'sphincssha256256ssimple'
+ pretty_name: 'SPHINCS+-SHA256-256s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_256s_simple'
+ oid: '1.3.9999.6.6.7'
+ code_point: '0xfe78'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.8',
+ 'code_point': '0xfe79'}]
+ -
+ family: 'SPHINCS-SHAKE256'
+ variants:
+ -
+ name: 'sphincsshake256128frobust'
+ pretty_name: 'SPHINCS+-SHAKE256-128f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_128f_robust'
+ oid: '1.3.9999.6.7.1'
+ code_point: '0xfe7a'
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.2',
+ 'code_point': '0xfe7b'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.3',
+ 'code_point': '0xfe7c'}]
+ -
+ name: 'sphincsshake256128fsimple'
+ pretty_name: 'SPHINCS+-SHAKE256-128f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_128f_simple'
+ oid: '1.3.9999.6.7.4'
+ code_point: '0xfe7d'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.5',
+ 'code_point': '0xfe7e'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.6',
+ 'code_point': '0xfe7f'}]
+ -
+ name: 'sphincsshake256128srobust'
+ pretty_name: 'SPHINCS+-SHAKE256-128s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_128s_robust'
+ oid: '1.3.9999.6.7.7'
+ code_point: '0xfe80'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.8',
+ 'code_point': '0xfe81'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.9',
+ 'code_point': '0xfe82'}]
+ -
+ name: 'sphincsshake256128ssimple'
+ pretty_name: 'SPHINCS+-SHAKE256-128s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_128s_simple'
+ oid: '1.3.9999.6.7.10'
+ code_point: '0xfe83'
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.11',
+ 'code_point': '0xfe84'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.12',
+ 'code_point': '0xfe85'}]
+ -
+ name: 'sphincsshake256192frobust'
+ pretty_name: 'SPHINCS+-SHAKE256-192f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_192f_robust'
+ oid: '1.3.9999.6.8.1'
+ code_point: '0xfe86'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.2',
+ 'code_point': '0xfe87'}]
+ -
+ name: 'sphincsshake256192fsimple'
+ pretty_name: 'SPHINCS+-SHAKE256-192f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_192f_simple'
+ oid: '1.3.9999.6.8.3'
+ code_point: '0xfe88'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.4',
+ 'code_point': '0xfe89'}]
+ -
+ name: 'sphincsshake256192srobust'
+ pretty_name: 'SPHINCS+-SHAKE256-192s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_192s_robust'
+ oid: '1.3.9999.6.8.5'
+ code_point: '0xfe8a'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.6',
+ 'code_point': '0xfe8b'}]
+ -
+ name: 'sphincsshake256192ssimple'
+ pretty_name: 'SPHINCS+-SHAKE256-192s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_192s_simple'
+ oid: '1.3.9999.6.8.7'
+ code_point: '0xfe8c'
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.8',
+ 'code_point': '0xfe8d'}]
+ -
+ name: 'sphincsshake256256frobust'
+ pretty_name: 'SPHINCS+-SHAKE256-256f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_256f_robust'
+ oid: '1.3.9999.6.9.1'
+ code_point: '0xfe8e'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.2',
+ 'code_point': '0xfe8f'}]
+ -
+ name: 'sphincsshake256256fsimple'
+ pretty_name: 'SPHINCS+-SHAKE256-256f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_256f_simple'
+ oid: '1.3.9999.6.9.3'
+ code_point: '0xfe90'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.4',
+ 'code_point': '0xfe91'}]
+ -
+ name: 'sphincsshake256256srobust'
+ pretty_name: 'SPHINCS+-SHAKE256-256s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_256s_robust'
+ oid: '1.3.9999.6.9.5'
+ code_point: '0xfe92'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.6',
+ 'code_point': '0xfe93'}]
+ -
+ name: 'sphincsshake256256ssimple'
+ pretty_name: 'SPHINCS+-SHAKE256-256s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_256s_simple'
+ oid: '1.3.9999.6.9.7'
+ code_point: '0xfe94'
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.8',
+ 'code_point': '0xfe95'}]
--- /dev/null
+# This is the master document for ID interoperability for KEM IDs, p-hybrid KEM IDs, SIG (O)IDs
+# Next free plain KEM ID: 0x0244, p-hybrid: 0x2F44, X-hybrid: 0x2FB0
+kems:
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo640aes'
+ nid: '0x0200'
+ nid_hybrid: '0x2F00'
+ oqs_alg: 'OQS_KEM_alg_frodokem_640_aes'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F80'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo640shake'
+ nid: '0x0201'
+ nid_hybrid: '0x2F01'
+ oqs_alg: 'OQS_KEM_alg_frodokem_640_shake'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F81'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo976aes'
+ nid: '0x0202'
+ nid_hybrid: '0x2F02'
+ oqs_alg: 'OQS_KEM_alg_frodokem_976_aes'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F82'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo976shake'
+ nid: '0x0203'
+ nid_hybrid: '0x2F03'
+ oqs_alg: 'OQS_KEM_alg_frodokem_976_shake'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F83'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo1344aes'
+ nid: '0x0204'
+ nid_hybrid: '0x2F04'
+ oqs_alg: 'OQS_KEM_alg_frodokem_1344_aes'
+ -
+ family: 'FrodoKEM'
+ name_group: 'frodo1344shake'
+ nid: '0x0205'
+ nid_hybrid: '0x2F05'
+ oqs_alg: 'OQS_KEM_alg_frodokem_1344_shake'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l1cpa'
+ bit_security: 128
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0206'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F06'
+ oqs_alg: 'OQS_KEM_alg_bike1_l1_cpa'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l3cpa'
+ bit_security: 192
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0207'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F07'
+ oqs_alg: 'OQS_KEM_alg_bike1_l3_cpa'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber512'
+ nid: '0x023A'
+ nid_hybrid: '0x2F3A'
+ oqs_alg: 'OQS_KEM_alg_kyber_512'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2F39'
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x020F'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F0F'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: x25519
+ nid: '0x2F26'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber768'
+ nid: '0x023C'
+ nid_hybrid: '0x2F3C'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2F90'
+ - hybrid_group: "x25519"
+ nid: '0x6399'
+ - hybrid_group: "p256"
+ nid: '0x639A'
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0210'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F10'
+ oqs_alg: 'OQS_KEM_alg_kyber_768'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber1024'
+ nid: '0x023D'
+ nid_hybrid: '0x2F3D'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0211'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp521_r1
+ nid: '0x2F11'
+ oqs_alg: 'OQS_KEM_alg_kyber_1024'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l1fo'
+ bit_security: 128
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0223'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F23'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: "x25519"
+ nid: '0x2F28'
+ oqs_alg: 'OQS_KEM_alg_bike1_l1_fo'
+ -
+ family: 'BIKE'
+ name_group: 'bike1l3fo'
+ bit_security: 192
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0224'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F24'
+ oqs_alg: 'OQS_KEM_alg_bike1_l3_fo'
+ -
+ family: 'BIKE'
+ name_group: 'bikel1'
+ implementation_version: '5.1'
+ nid: '0x0241'
+ nid_hybrid: '0x2F41'
+ oqs_alg: 'OQS_KEM_alg_bike_l1'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FAE'
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x0238'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: x25519
+ nid: '0x2F37'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp256_r1
+ nid: '0x2F38'
+ -
+ family: 'BIKE'
+ name_group: 'bikel3'
+ implementation_version: '5.1'
+ nid: '0x0242'
+ nid_hybrid: '0x2F42'
+ oqs_alg: 'OQS_KEM_alg_bike_l3'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2FAF'
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x023B'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp384_r1
+ nid: '0x2F3B'
+ -
+ family: 'BIKE'
+ name_group: 'bikel5'
+ implementation_version: '5.1'
+ nid: '0x0243'
+ nid_hybrid: '0x2F43'
+ oqs_alg: 'OQS_KEM_alg_bike_l5'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber90s512'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x0229'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp256_r1
+ nid: '0x2F29'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x023E'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp256_r1
+ nid: '0x2F3E'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: x25519
+ nid: '0x2FA9'
+ oqs_alg: 'OQS_KEM_alg_kyber_512_90s'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber90s768'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x022A'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp384_r1
+ nid: '0x2F2A'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x023F'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp384_r1
+ nid: '0x2F3F'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: x448
+ nid: '0x2FAA'
+ oqs_alg: 'OQS_KEM_alg_kyber_768_90s'
+ -
+ family: 'CRYSTALS-Kyber'
+ name_group: 'kyber90s1024'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ nid: '0x022B'
+ - implementation_version: NIST Round 2 submission
+ nist-round: 2
+ hybrid_group: secp521_r1
+ nid: '0x2F2B'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ nid: '0x0240'
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ hybrid_group: secp521_r1
+ nid: '0x2F40'
+ oqs_alg: 'OQS_KEM_alg_kyber_1024_90s'
+ -
+ family: 'HQC'
+ name_group: 'hqc128'
+ nid: '0x022C'
+ nid_hybrid: '0x2F2C'
+ oqs_alg: 'OQS_KEM_alg_hqc_128'
+ extra_nids:
+ current:
+ - hybrid_group: "x25519"
+ nid: '0x2FAC'
+ -
+ family: 'HQC'
+ name_group: 'hqc192'
+ nid: '0x022D'
+ nid_hybrid: '0x2F2D'
+ oqs_alg: 'OQS_KEM_alg_hqc_192'
+ extra_nids:
+ current:
+ - hybrid_group: "x448"
+ nid: '0x2FAD'
+ -
+ family: 'HQC'
+ name_group: 'hqc256'
+ nid: '0x022E'
+ nid_hybrid: '0x2F2E'
+ oqs_alg: 'OQS_KEM_alg_hqc_256'
+
+kem_nid_end: '0x0250'
+kem_nid_hybrid_end: '0x2FFF'
+# need to edit ssl_local.h macros IS_OQS_KEM_CURVEID and IS_OQS_KEM_HYBRID_CURVEID with the above _end values
+
+# Next free signature ID: 0xfed0
+sigs:
+ # -
+ # iso (1)
+ # identified-organization (3)
+ # reserved (9999)
+ # oqs_sig_default (1)
+ # disabled
+ #variants:
+ # -
+ # name: 'oqs_sig_default'
+ # pretty_name: 'OQS Default Signature Algorithm'
+ # oqs_meth: 'OQS_SIG_alg_default'
+ # oid: '1.3.9999.1.1'
+ # code_point: '0xfe00'
+ # enable: true
+ # mix_with: [{'name': 'p256',
+ # 'pretty_name': 'ECDSA p256',
+ # 'oid': '1.3.9999.1.2',
+ # 'code_point': '0xfe01'},
+ # {'name': 'rsa3072',
+ # 'pretty_name': 'RSA3072',
+ # 'oid': '1.3.9999.1.3',
+ # 'code_point': '0xfe02'}]
+ -
+ # OID scheme for hybrid variants of Dilithium:
+ # iso (1)
+ # identified-organization (3)
+ # reserved (9999)
+ # dilithium (2)
+ # OID scheme for plain Dilithium:
+ # iso (1)
+ # identified-organization (3)
+ # dod (6)
+ # internet (1)
+ # private (4)
+ # enterprise (1)
+ # IBM (2)
+ # qsc (267)
+ # Dilithium-r3 (7)
+ family: 'CRYSTALS-Dilithium'
+ variants:
+ -
+ name: 'dilithium2'
+ pretty_name: 'Dilithium2'
+ oqs_meth: 'OQS_SIG_alg_dilithium_2'
+ oid: '1.3.6.1.4.1.2.267.7.4.4'
+ code_point: '0xfea0'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.2.7.1',
+ 'code_point': '0xfea1'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.2.7.2',
+ 'code_point': '0xfea2'}]
+ -
+ name: 'dilithium3'
+ pretty_name: 'Dilithium3'
+ oqs_meth: 'OQS_SIG_alg_dilithium_3'
+ oid: '1.3.6.1.4.1.2.267.7.6.5'
+ code_point: '0xfea3'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.2.7.3',
+ 'code_point': '0xfea4'}]
+ -
+ name: 'dilithium5'
+ pretty_name: 'Dilithium5'
+ oqs_meth: 'OQS_SIG_alg_dilithium_5'
+ oid: '1.3.6.1.4.1.2.267.7.8.7'
+ code_point: '0xfea5'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.2.7.4',
+ 'code_point': '0xfea6'}]
+ -
+ name: 'dilithium2_aes'
+ pretty_name: 'Dilithium2_AES'
+ oqs_meth: 'OQS_SIG_alg_dilithium_2_aes'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.6.1.4.1.2.267.11.4.4'
+ code_point: '0xfea7'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.2.11.1',
+ 'code_point': '0xfea8'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.2.11.2',
+ 'code_point': '0xfea9'}]
+ -
+ name: 'dilithium3_aes'
+ pretty_name: 'Dilithium3_AES'
+ oqs_meth: 'OQS_SIG_alg_dilithium_3_aes'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.6.1.4.1.2.267.11.6.5'
+ code_point: '0xfeaa'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.2.11.3',
+ 'code_point': '0xfeab'}]
+ -
+ name: 'dilithium5_aes'
+ pretty_name: 'Dilithium5_AES'
+ oqs_meth: 'OQS_SIG_alg_dilithium_5_aes'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.6.1.4.1.2.267.11.8.7'
+ code_point: '0xfeac'
+ supported_encodings: ['draft-uni-qsckeys-dilithium-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.2.11.4',
+ 'code_point': '0xfead'}]
+ -
+ # iso (1)
+ # identified-organization (3)
+ # reserved (9999)
+ # falcon (3)
+ family: 'Falcon'
+ variants:
+ -
+ name: 'falcon512'
+ pretty_name: 'Falcon-512'
+ oqs_meth: 'OQS_SIG_alg_falcon_512'
+ oid: '1.3.9999.3.6'
+ code_point: '0xfeae'
+ supported_encodings: ['draft-uni-qsckeys-falcon-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.3.7',
+ 'code_point': '0xfeaf'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.3.8',
+ 'code_point': '0xfeb0'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.3.1'
+ code_point: '0xfe0b'
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.3.2',
+ 'code_point': '0xfe0c'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.3.3',
+ 'code_point': '0xfe0d'}]
+ -
+ name: 'falcon1024'
+ pretty_name: 'Falcon-1024'
+ oqs_meth: 'OQS_SIG_alg_falcon_1024'
+ oid: '1.3.9999.3.9'
+ code_point: '0xfeb1'
+ supported_encodings: ['draft-uni-qsckeys-falcon-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.3.10',
+ 'code_point': '0xfeb2'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.3.4'
+ code_point: '0xfe0e'
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.3.5',
+ 'code_point': '0xfe0f'}]
+ -
+ family: 'SPHINCS-Haraka'
+ variants:
+ -
+ name: 'sphincsharaka128frobust'
+ pretty_name: 'SPHINCS+-Haraka-128f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.1.1'
+ code_point: '0xfe42'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.2',
+ 'code_point': '0xfe43'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.3',
+ 'code_point': '0xfe44'}]
+ -
+ name: 'sphincsharaka128fsimple'
+ pretty_name: 'SPHINCS+-Haraka-128f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128f_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.1.4'
+ code_point: '0xfe45'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.5',
+ 'code_point': '0xfe46'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.6',
+ 'code_point': '0xfe47'}]
+ -
+ name: 'sphincsharaka128srobust'
+ pretty_name: 'SPHINCS+-Haraka-128s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.1.7'
+ code_point: '0xfe48'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.8',
+ 'code_point': '0xfe49'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.9',
+ 'code_point': '0xfe4a'}]
+ -
+ name: 'sphincsharaka128ssimple'
+ pretty_name: 'SPHINCS+-Haraka-128s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_128s_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.1.10'
+ code_point: '0xfe4b'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.1.11',
+ 'code_point': '0xfe4c'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.1.12',
+ 'code_point': '0xfe4d'}]
+ -
+ name: 'sphincsharaka192frobust'
+ pretty_name: 'SPHINCS+-Haraka-192f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.2.1'
+ code_point: '0xfe4e'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.2',
+ 'code_point': '0xfe4f'}]
+ -
+ name: 'sphincsharaka192fsimple'
+ pretty_name: 'SPHINCS+-Haraka-192f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192f_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.2.3'
+ code_point: '0xfe50'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.4',
+ 'code_point': '0xfe51'}]
+ -
+ name: 'sphincsharaka192srobust'
+ pretty_name: 'SPHINCS+-Haraka-192s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.2.5'
+ code_point: '0xfe52'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.6',
+ 'code_point': '0xfe53'}]
+ -
+ name: 'sphincsharaka192ssimple'
+ pretty_name: 'SPHINCS+-Haraka-192s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_192s_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.2.7'
+ code_point: '0xfe54'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.2.8',
+ 'code_point': '0xfe55'}]
+ -
+ name: 'sphincsharaka256frobust'
+ pretty_name: 'SPHINCS+-Haraka-256f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.3.1'
+ code_point: '0xfe56'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.2',
+ 'code_point': '0xfe57'}]
+ -
+ name: 'sphincsharaka256fsimple'
+ pretty_name: 'SPHINCS+-Haraka-256f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256f_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.3.3'
+ code_point: '0xfe58'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.4',
+ 'code_point': '0xfe59'}]
+ -
+ name: 'sphincsharaka256srobust'
+ pretty_name: 'SPHINCS+-Haraka-256s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.3.5'
+ code_point: '0xfe5a'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.6',
+ 'code_point': '0xfe5b'}]
+ -
+ name: 'sphincsharaka256ssimple'
+ pretty_name: 'SPHINCS+-Haraka-256s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_haraka_256s_simple'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.3.7'
+ code_point: '0xfe5c'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.3.8',
+ 'code_point': '0xfe5d'}]
+ -
+ family: 'SPHINCS-SHA2'
+ variants:
+ -
+ name: 'sphincssha26128frobust'
+ pretty_name: 'SPHINCS+-SHA256-128f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_128f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.4.1'
+ code_point: '0xfe5e'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.2',
+ 'code_point': '0xfe5f'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.3',
+ 'code_point': '0xfe60'}]
+ -
+ name: 'sphincssha2128fsimple'
+ pretty_name: 'SPHINCS+-SHA2-128f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_128f_simple'
+ oid: '1.3.9999.6.4.13'
+ code_point: '0xfeb3'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.14',
+ 'code_point': '0xfeb4'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.15',
+ 'code_point': '0xfeb5'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.4.4'
+ code_point: '0xfe61'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.5',
+ 'code_point': '0xfe62'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.6',
+ 'code_point': '0xfe63'}]
+ -
+ name: 'sphincssha256128srobust'
+ pretty_name: 'SPHINCS+-SHA256-128s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_128s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.4.7'
+ code_point: '0xfe64'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.8',
+ 'code_point': '0xfe65'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.9',
+ 'code_point': '0xfe66'}]
+ -
+ name: 'sphincssha2128ssimple'
+ pretty_name: 'SPHINCS+-SHA2-128s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_128s_simple'
+ oid: '1.3.9999.6.4.16'
+ code_point: '0xfeb6'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.17',
+ 'code_point': '0xfeb7'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.18',
+ 'code_point': '0xfeb8'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.4.10'
+ code_point: '0xfe67'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.4.11',
+ 'code_point': '0xfe68'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.4.12',
+ 'code_point': '0xfe69'}]
+ -
+ name: 'sphincssha256192frobust'
+ pretty_name: 'SPHINCS+-SHA256-192f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_192f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.5.1'
+ code_point: '0xfe6a'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.2',
+ 'code_point': '0xfe6b'}]
+ -
+ name: 'sphincssha2192fsimple'
+ pretty_name: 'SPHINCS+-SHA2-192f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_192f_simple'
+ oid: '1.3.9999.6.5.10'
+ code_point: '0xfeb9'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.11',
+ 'code_point': '0xfeba'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.5.3'
+ code_point: '0xfe6c'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.4',
+ 'code_point': '0xfe6d'}]
+ -
+ name: 'sphincssha256192srobust'
+ pretty_name: 'SPHINCS+-SHA256-192s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_192s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.5.5'
+ code_point: '0xfe6e'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.6',
+ 'code_point': '0xfe6f'}]
+ -
+ name: 'sphincssha2192ssimple'
+ pretty_name: 'SPHINCS+-SHA2-192s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_192s_simple'
+ oid: '1.3.9999.6.5.12'
+ code_point: '0xfebb'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.13',
+ 'code_point': '0xfebc'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.5.7'
+ code_point: '0xfe70'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.5.8',
+ 'code_point': '0xfe71'}]
+ -
+ name: 'sphincssha256256frobust'
+ pretty_name: 'SPHINCS+-SHA256-256f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_256f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.6.1'
+ code_point: '0xfe72'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.2',
+ 'code_point': '0xfe73'}]
+ -
+ name: 'sphincssha2256fsimple'
+ pretty_name: 'SPHINCS+-SHA2-256f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_256f_simple'
+ oid: '1.3.9999.6.6.10'
+ code_point: '0xfebd'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.11',
+ 'code_point': '0xfebe'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.6.3'
+ code_point: '0xfe74'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.4',
+ 'code_point': '0xfe75'}]
+ -
+ name: 'sphincssha256256srobust'
+ pretty_name: 'SPHINCS+-SHA256-256s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha256_256s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.6.5'
+ code_point: '0xfe76'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.6',
+ 'code_point': '0xfe77'}]
+ -
+ name: 'sphincssha2256ssimple'
+ pretty_name: 'SPHINCS+-SHA2-256s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_sha2_256s_simple'
+ oid: '1.3.9999.6.6.12'
+ code_point: '0xfec0'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.13',
+ 'code_point': '0xfec1'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.6.7'
+ code_point: '0xfe78'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.6.8',
+ 'code_point': '0xfe79'}]
+ -
+ family: 'SPHINCS-SHAKE'
+ variants:
+ -
+ name: 'sphincsshake256128frobust'
+ pretty_name: 'SPHINCS+-SHAKE256-128f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_128f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.7.1'
+ code_point: '0xfe7a'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.2',
+ 'code_point': '0xfe7b'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.3',
+ 'code_point': '0xfe7c'}]
+ -
+ name: 'sphincsshake128fsimple'
+ pretty_name: 'SPHINCS+-SHAKE-128f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_128f_simple'
+ oid: '1.3.9999.6.7.13'
+ code_point: '0xfec2'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: true
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.14',
+ 'code_point': '0xfec3'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.15',
+ 'code_point': '0xfec4'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.7.4'
+ code_point: '0xfe7d'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.5',
+ 'code_point': '0xfe7e'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.6',
+ 'code_point': '0xfe7f'}]
+ -
+ name: 'sphincsshake256128srobust'
+ pretty_name: 'SPHINCS+-SHAKE256-128s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_128s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.7.7'
+ code_point: '0xfe80'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.8',
+ 'code_point': '0xfe81'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.9',
+ 'code_point': '0xfe82'}]
+ -
+ name: 'sphincsshake128ssimple'
+ pretty_name: 'SPHINCS+-SHAKE-128s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_128s_simple'
+ oid: '1.3.9999.6.7.16'
+ code_point: '0xfec5'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.17',
+ 'code_point': '0xfec6'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.18',
+ 'code_point': '0xfec7'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.7.10'
+ code_point: '0xfe83'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p256',
+ 'pretty_name': 'ECDSA p256',
+ 'oid': '1.3.9999.6.7.11',
+ 'code_point': '0xfe84'},
+ {'name': 'rsa3072',
+ 'pretty_name': 'RSA3072',
+ 'oid': '1.3.9999.6.7.12',
+ 'code_point': '0xfe85'}]
+ -
+ name: 'sphincsshake256192frobust'
+ pretty_name: 'SPHINCS+-SHAKE256-192f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_192f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.8.1'
+ code_point: '0xfe86'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.2',
+ 'code_point': '0xfe87'}]
+ -
+ name: 'sphincsshake192fsimple'
+ pretty_name: 'SPHINCS+-SHAKE-192f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_192f_simple'
+ oid: '1.3.9999.6.8.10'
+ code_point: '0xfec8'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.11',
+ 'code_point': '0xfec9'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.8.3'
+ code_point: '0xfe88'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.4',
+ 'code_point': '0xfe89'}]
+ -
+ name: 'sphincsshake256192srobust'
+ pretty_name: 'SPHINCS+-SHAKE256-192s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_192s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.8.5'
+ code_point: '0xfe8a'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.6',
+ 'code_point': '0xfe8b'}]
+ -
+ name: 'sphincsshake192ssimple'
+ pretty_name: 'SPHINCS+-SHAKE-192s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_192s_simple'
+ oid: '1.3.9999.6.8.12'
+ code_point: '0xfeca'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.13',
+ 'code_point': '0xfecb'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.8.7'
+ code_point: '0xfe8c'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p384',
+ 'pretty_name': 'ECDSA p384',
+ 'oid': '1.3.9999.6.8.8',
+ 'code_point': '0xfe8d'}]
+ -
+ name: 'sphincsshake256256frobust'
+ pretty_name: 'SPHINCS+-SHAKE256-256f-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_256f_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.9.1'
+ code_point: '0xfe8e'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.2',
+ 'code_point': '0xfe8f'}]
+ -
+ name: 'sphincsshake256fsimple'
+ pretty_name: 'SPHINCS+-SHAKE-256f-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_256f_simple'
+ oid: '1.3.9999.6.9.10'
+ code_point: '0xfecc'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.11',
+ 'code_point': '0xfecd'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.9.3'
+ code_point: '0xfe90'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.4',
+ 'code_point': '0xfe91'}]
+ -
+ name: 'sphincsshake256256srobust'
+ pretty_name: 'SPHINCS+-SHAKE256-256s-robust'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake256_256s_robust'
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.9.5'
+ code_point: '0xfe92'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.6',
+ 'code_point': '0xfe93'}]
+ -
+ name: 'sphincsshake256ssimple'
+ pretty_name: 'SPHINCS+-SHAKE-256s-simple'
+ oqs_meth: 'OQS_SIG_alg_sphincs_shake_256s_simple'
+ oid: '1.3.9999.6.9.12'
+ code_point: '0xfece'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ enable: false
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.13',
+ 'code_point': '0xfecf'}]
+ extra_nids:
+ old:
+ - implementation_version: NIST Round 3 submission
+ nist-round: 3
+ oid: '1.3.9999.6.9.7'
+ code_point: '0xfe94'
+ supported_encodings: ['draft-uni-qsckeys-sphincsplus-00/sk-pk']
+ mix_with: [{'name': 'p521',
+ 'pretty_name': 'ECDSA p521',
+ 'oid': '1.3.9999.6.9.8',
+ 'code_point': '0xfe95'}]
+
+
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+import sys
+from tabulate import tabulate
+import yaml
+import os
+
+import generatehelpers
+
+config = {}
+
+def gen_sig_table(oqslibdocdir):
+ liboqs_sig_docs_dir = os.path.join(oqslibdocdir, 'algorithms', 'sig')
+ liboqs_sigs = {}
+ for root, _, files in os.walk(liboqs_sig_docs_dir):
+ for fil in files:
+ if fil.endswith(".yml"):
+ with open(os.path.join(root, fil), mode='r', encoding='utf-8') as f:
+ algyml = yaml.safe_load(f.read())
+ liboqs_sigs[algyml['name']]=algyml
+
+ table = [['Algorithm', 'Implementation Version',
+ 'NIST round', 'Claimed NIST Level', 'Code Point', 'OID']]
+ claimed_nist_level = 0
+ for sig in sorted(config['sigs'], key=lambda s: s['family']):
+ for variant in sig['variants']:
+ if variant['security'] == 128:
+ claimed_nist_level = 1
+ elif variant['security'] == 192:
+ claimed_nist_level = 3
+ elif variant['security'] == 256:
+ claimed_nist_level = 5
+ else:
+ sys.exit("variant['security'] value malformed.")
+
+ if sig['family'].startswith('SPHINCS'):
+ sig['family'] = 'SPHINCS+'
+
+ if variant['name'].startswith('dilithium2'):
+ claimed_nist_level = 2
+
+ try:
+ table.append([variant['name'], liboqs_sigs[sig['family']]['spec-version'],
+ liboqs_sigs[sig['family']]['nist-round'], claimed_nist_level, variant['code_point'],
+ variant['oid']])
+ for hybrid in variant['mix_with']:
+ table.append([variant['name'] + ' **hybrid with** ' + hybrid['name'],
+ liboqs_sigs[sig['family']]['spec-version'],
+ liboqs_sigs[sig['family']]['nist-round'],
+ claimed_nist_level,
+ hybrid['code_point'],
+ hybrid['oid']])
+ except KeyError as ke:
+ # Non-existant NIDs mean this alg is not supported any more
+ pass
+
+ if 'extra_nids' in variant:
+ for i in range(len(variant['extra_nids']['old'])):
+ table.append([variant['name'], variant['extra_nids']['old'][i]['implementation_version'],
+ variant['extra_nids']['old'][i]['nist-round'], claimed_nist_level, variant['extra_nids']['old'][i]['code_point'],
+ variant['extra_nids']['old'][i]['oid']])
+ for hybrid in variant['extra_nids']['old'][i]['mix_with']:
+ table.append([variant['name'] + ' **hybrid with** ' + hybrid['name'],
+ variant['extra_nids']['old'][i]['implementation_version'],
+ variant['extra_nids']['old'][i]['nist-round'],
+ claimed_nist_level,
+ hybrid['code_point'],
+ hybrid['oid']])
+
+ with open(os.path.join('oqs-template', 'oqs-sig-info.md'), mode='w', encoding='utf-8') as f:
+ f.write(tabulate(table, tablefmt="pipe", headers="firstrow"))
+ print("Written oqs-sig-info.md")
+
+def gen_kem_table(oqslibdocdir):
+ liboqs_kem_docs_dir = os.path.join(oqslibdocdir, 'algorithms', 'kem')
+ liboqs_kems = {}
+ for root, _, files in os.walk(liboqs_kem_docs_dir):
+ for fil in files:
+ if fil.endswith(".yml"):
+ with open(os.path.join(root, fil), mode='r', encoding='utf-8') as f:
+ algyml = yaml.safe_load(f.read())
+ liboqs_kems[algyml['name']]=algyml
+ if 'SIKE' in liboqs_kems:
+ liboqs_kems['SIDH']=liboqs_kems['SIKE']
+ # TODO: Workaround for wrong upstream name for Kyber:
+ liboqs_kems['CRYSTALS-Kyber']=liboqs_kems['Kyber']
+
+ table_header = ['Family', 'Implementation Version', 'Variant', 'NIST round', 'Claimed NIST Level',
+ 'Code Point', 'Hybrid Elliptic Curve (if any)']
+ table = []
+ hybrid_elliptic_curve = ''
+ for kem in sorted(config['kems'], key=lambda k: k['family']):
+ if kem['bit_security'] == 128:
+ claimed_nist_level = 1
+ hybrid_elliptic_curve = 'secp256_r1'
+ elif kem['bit_security'] == 192:
+ claimed_nist_level = 3
+ hybrid_elliptic_curve = 'secp384_r1'
+ elif kem['bit_security'] == 256:
+ claimed_nist_level = 5
+ hybrid_elliptic_curve = 'secp521_r1'
+ else:
+ sys.exit("kem['bit_security'] value malformed.")
+
+ if 'implementation_version' in kem:
+ implementation_version = kem['implementation_version']
+ else:
+ if kem['family'] in liboqs_kems:
+ implementation_version = liboqs_kems[kem['family']]['spec-version']
+
+ if kem['name_group'].startswith('sidhp503') or kem['name_group'].startswith('sikep503'):
+ claimed_nist_level = 2
+
+ try:
+ table.append([kem['family'], implementation_version,
+ kem['name_group'], liboqs_kems[kem['family']]['nist-round'], claimed_nist_level,
+ kem['nid'], ""])
+ table.append([kem['family'], implementation_version,
+ kem['name_group'], liboqs_kems[kem['family']]['nist-round'], claimed_nist_level,
+ kem['nid_hybrid'], hybrid_elliptic_curve])
+ except KeyError as ke:
+ # Non-existant NIDs mean this alg is not supported any more
+ pass
+
+ if 'extra_nids' in kem:
+ if 'current' in kem['extra_nids']: # assume "current" NIDs to mean liboqs-driven NIST round information:
+ for entry in kem['extra_nids']['current']:
+ table.append([kem['family'], implementation_version,
+ kem['name_group'], liboqs_kems[kem['family']]['nist-round'], claimed_nist_level,
+ entry['nid'],
+ entry['hybrid_group'] if 'hybrid_group' in entry else ""])
+ if 'old' in kem['extra_nids']:
+ for entry in kem['extra_nids']['old']:
+ table.append([kem['family'], entry['implementation_version'],
+ kem['name_group'], entry['nist-round'], claimed_nist_level,
+ entry['nid'],
+ entry['hybrid_group'] if 'hybrid_group' in entry else ""])
+
+ # sort by: family, version, security level, variant, hybrid
+ table.sort(key = lambda row: "{:s}|{:s}|{:d}|{:s}|{:s}".format(row[0], row[1], row[3], row[2], row[5]))
+
+ table = [table_header] + table
+
+ with open(os.path.join('oqs-template', 'oqs-kem-info.md'), mode='w', encoding='utf-8') as f:
+ f.write(tabulate(table, tablefmt="pipe", headers="firstrow"))
+ f.write("\n")
+ print("Written oqs-kem-info.md")
+
+# main:
+with open(os.path.join('oqs-template', 'generate.yml'), mode='r', encoding='utf-8') as f:
+ config = yaml.safe_load(f.read())
+
+if 'LIBOQS_DOCS_DIR' not in os.environ:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--liboqs-docs-dir', dest="liboqs_docs_dir", required=True)
+ args = parser.parse_args()
+ oqsdocsdir = args.liboqs_docs_dir
+else:
+ oqsdocsdir = os.environ["LIBOQS_DOCS_DIR"]
+
+config = generatehelpers.complete_config(config, oqsdocsdir)
+
+gen_kem_table(oqsdocsdir)
+gen_sig_table(oqsdocsdir)
--- /dev/null
+#!/usr/bin/env python3
+
+import copy
+import glob
+import jinja2
+import jinja2.ext
+import os
+import shutil
+import subprocess
+import yaml
+import json
+import sys
+
+def file_get_contents(filename, encoding=None):
+ with open(filename, mode='r', encoding=encoding) as fh:
+ return fh.read()
+
+def file_put_contents(filename, s, encoding=None):
+ with open(filename, mode='w', encoding=encoding) as fh:
+ fh.write(s)
+
+def get_kem_nistlevel(alg, docsdir):
+ # translate family names in generate.yml to directory names for liboqs algorithm datasheets
+ if alg['family'] == 'CRYSTALS-Kyber': datasheetname = 'kyber'
+ elif alg['family'] == 'SIDH': datasheetname = 'sike'
+ elif alg['family'] == 'NTRU-Prime': datasheetname = 'ntruprime'
+ else: datasheetname = alg['family'].lower()
+ # load datasheet
+ try:
+ algymlfilename = os.path.join(docsdir, 'algorithms', 'kem', '{:s}.yml'.format(datasheetname))
+ algyml = yaml.safe_load(file_get_contents(algymlfilename, encoding='utf-8'))
+ except: # check alternate location in "oldalgs" folder
+ algymlfilename = os.path.join("oqs-template", 'oldalgdocs', 'kem', '{:s}.yml'.format(datasheetname))
+ algyml = yaml.safe_load(file_get_contents(algymlfilename, encoding='utf-8'))
+
+ # hacks to match names
+ def matches(name, alg):
+ def simplify(s):
+ return s.lower().replace('_', '').replace('-', '')
+ if 'FrodoKEM' in name: name = name.replace('FrodoKEM', 'Frodo')
+ if 'Saber-KEM' in name: name = name.replace('-KEM', '')
+ if '-90s' in name: name = name.replace('-90s', '').replace('Kyber', 'Kyber90s')
+ if simplify(name) == simplify(alg['name_group']): return True
+ return False
+ # find the variant that matches
+ for variant in algyml['parameter-sets']:
+ if matches(variant['name'], alg):
+ return variant['claimed-nist-level']
+ # Information file for algorithms no longer supported by liboqs:
+ oldalgs = yaml.safe_load(file_get_contents(os.path.join("oqs-template", "oldalgs.yml"), encoding='utf-8'))
+ name = alg['name_group']
+ if name in oldalgs:
+ return oldalgs[name]['claimed-nist-level']
+ return None
+
+def get_sig_nistlevel(family, alg, docsdir):
+ # translate family names in generate.yml to directory names for liboqs algorithm datasheets
+ if family['family'] == 'CRYSTALS-Dilithium': datasheetname = 'dilithium'
+ elif family['family'] == 'SPHINCS-Haraka': datasheetname = 'sphincs'
+ elif family['family'] == 'SPHINCS-SHA256': datasheetname = 'sphincs'
+ elif family['family'] == 'SPHINCS-SHAKE256': datasheetname = 'sphincs'
+ elif family['family'] == 'SPHINCS-SHA2': datasheetname = 'sphincs'
+ elif family['family'] == 'SPHINCS-SHAKE': datasheetname = 'sphincs'
+ else: datasheetname = family['family'].lower()
+ # load datasheet
+ algymlfilename = os.path.join(docsdir, 'algorithms', 'sig', '{:s}.yml'.format(datasheetname))
+ algyml = yaml.safe_load(file_get_contents(algymlfilename, encoding='utf-8'))
+ # hacks to match names
+ def matches(name, alg):
+ def simplify(s):
+ return s.lower().replace('_', '').replace('-', '').replace('+', '')
+ if simplify(name) == simplify(alg['name']): return True
+ return False
+ # find the variant that matches
+ for variant in algyml['parameter-sets']:
+ if matches(variant['name'], alg):
+ return variant['claimed-nist-level']
+ # Information file for algorithms no longer supported by liboqs:
+ oldalgs = yaml.safe_load(file_get_contents(os.path.join("oqs-template", "oldalgs.yml"), encoding='utf-8'))
+ name = alg['name']
+ if name in oldalgs:
+ return oldalgs[name]['claimed-nist-level']
+ return None
+
+def nist_to_bits(nistlevel):
+ if nistlevel==1 or nistlevel==2:
+ return 128
+ elif nistlevel==3 or nistlevel==4:
+ return 192
+ elif nistlevel==5:
+ return 256
+ else:
+ return None
+
+def complete_config(config, oqsdocsdir = None):
+ if oqsdocsdir == None:
+ if 'LIBOQS_DOCS_DIR' not in os.environ:
+ print("Must include LIBOQS_DOCS_DIR in environment")
+ exit(1)
+ oqsdocsdir = os.environ["LIBOQS_DOCS_DIR"]
+ for kem in config['kems']:
+ if not "bit_security" in kem.keys():
+ bits_level = nist_to_bits(get_kem_nistlevel(kem, oqsdocsdir))
+ if bits_level == None:
+ print("Cannot find security level for {:s} {:s}".format(kem['family'], kem['name_group']))
+ exit(1)
+ kem['bit_security'] = bits_level
+ for famsig in config['sigs']:
+ for sig in famsig['variants']:
+ if not "security" in sig.keys():
+ bits_level = nist_to_bits(get_sig_nistlevel(famsig, sig, oqsdocsdir))
+ if bits_level == None:
+ if sig['name'].startswith("rainbowI"):
+ bits_level=128
+ else:
+ print("Cannot find security level for {:s} {:s}".format(famsig['family'], sig['name']))
+ exit(1)
+ sig['security'] = bits_level
+ return config
+
--- /dev/null
+name: SIKE
+type: kem
+principal-submitters:
+- David Jao
+- Reza Azarderakhsh
+- Matthew Campagna
+- Craig Costello
+- Luca De Feo
+- Basil Hess
+- Amir Jalali
+- Brian Koziel
+- Brian LaMacchia
+- Patrick Longa
+- Michael Naehrig
+- Joost Renes
+- Vladimir Soukharev
+- David Urbanik
+crypto-assumption: (supersingular) isogeny walk problem
+website: https://sike.org
+nist-round: 3
+spec-version: NIST Round 3 submission
+spdx-license-identifier: MIT
+primary-upstream:
+ source: https://github.com/microsoft/PQCrypto-SIDH/commit/effa607f244768cdd38f930887076373604eaa78
+ spdx-license-identifier: MIT
+parameter-sets:
+- name: SIDH-p434
+ claimed-nist-level: 1
+ claimed-security: IND-CPA
+ length-public-key: 330
+ length-ciphertext: 330
+ length-secret-key: 28
+ length-shared-secret: 110
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIDH-p434-compressed
+ claimed-nist-level: 1
+ claimed-security: IND-CPA
+ length-public-key: 197
+ length-ciphertext: 197
+ length-secret-key: 28
+ length-shared-secret: 110
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIDH-p503
+ claimed-nist-level: 2
+ claimed-security: IND-CPA
+ length-public-key: 378
+ length-ciphertext: 378
+ length-secret-key: 32
+ length-shared-secret: 126
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIDH-p503-compressed
+ claimed-nist-level: 2
+ claimed-security: IND-CPA
+ length-public-key: 225
+ length-ciphertext: 225
+ length-secret-key: 32
+ length-shared-secret: 126
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIDH-p610
+ claimed-nist-level: 3
+ claimed-security: IND-CPA
+ length-public-key: 462
+ length-ciphertext: 462
+ length-secret-key: 39
+ length-shared-secret: 154
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIDH-p610-compressed
+ claimed-nist-level: 3
+ claimed-security: IND-CPA
+ length-public-key: 274
+ length-ciphertext: 274
+ length-secret-key: 39
+ length-shared-secret: 154
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIDH-p751
+ claimed-nist-level: 5
+ claimed-security: IND-CPA
+ length-public-key: 564
+ length-ciphertext: 564
+ length-secret-key: 48
+ length-shared-secret: 188
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIDH-p751-compressed
+ claimed-nist-level: 5
+ claimed-security: IND-CPA
+ length-public-key: 335
+ length-ciphertext: 335
+ length-secret-key: 48
+ length-shared-secret: 188
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIKE-p434
+ claimed-nist-level: 1
+ claimed-security: IND-CCA2
+ length-public-key: 330
+ length-ciphertext: 346
+ length-secret-key: 374
+ length-shared-secret: 16
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIKE-p434-compressed
+ claimed-nist-level: 1
+ claimed-security: IND-CCA2
+ length-public-key: 197
+ length-ciphertext: 236
+ length-secret-key: 350
+ length-shared-secret: 16
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIKE-p503
+ claimed-nist-level: 2
+ claimed-security: IND-CCA2
+ length-public-key: 378
+ length-ciphertext: 402
+ length-secret-key: 434
+ length-shared-secret: 24
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIKE-p503-compressed
+ claimed-nist-level: 2
+ claimed-security: IND-CCA2
+ length-public-key: 225
+ length-ciphertext: 280
+ length-secret-key: 407
+ length-shared-secret: 24
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIKE-p610
+ claimed-nist-level: 3
+ claimed-security: IND-CCA2
+ length-public-key: 462
+ length-ciphertext: 486
+ length-secret-key: 524
+ length-shared-secret: 24
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIKE-p610-compressed
+ claimed-nist-level: 3
+ claimed-security: IND-CCA2
+ length-public-key: 274
+ length-ciphertext: 336
+ length-secret-key: 491
+ length-shared-secret: 24
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIKE-p751
+ claimed-nist-level: 5
+ claimed-security: IND-CCA2
+ length-public-key: 564
+ length-ciphertext: 596
+ length-secret-key: 644
+ length-shared-secret: 32
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+- name: SIKE-p751-compressed
+ claimed-nist-level: 5
+ claimed-security: IND-CCA2
+ length-public-key: 335
+ length-ciphertext: 410
+ length-secret-key: 602
+ length-shared-secret: 32
+ implementations-switch-on-runtime-cpu-features: false
+ implementations:
+ - upstream: primary-upstream
+ upstream-id: optimized
+ supported-platforms: all
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_bmi2
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_amd64_adx
+ supported-platforms:
+ - architecture: x86_64
+ operating_systems:
+ - Linux
+ - Darwin
+ required_flags:
+ - bmi2
+ - adx
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
+ - upstream: primary-upstream
+ upstream-id: additional_arm64
+ supported-platforms:
+ - architecture: arm64v8
+ operating_systems:
+ - Linux
+ - Darwin
+ - FreeBSD
+ common-crypto:
+ - SHA3: liboqs
+ no-secret-dependent-branching-claimed: true
+ no-secret-dependent-branching-checked-by-valgrind: true
+ large-stack-usage: false
--- /dev/null
+kyber90s512:
+ claimed-nist-level: 1
+kyber90s768:
+ claimed-nist-level: 3
+kyber90s1024:
+ claimed-nist-level: 5
+dilithium2_aes:
+ claimed-nist-level: 2
+dilithium3_aes:
+ claimed-nist-level: 3
+dilithium5_aes:
+ claimed-nist-level: 5
+sphincsharaka128frobust:
+ claimed-nist-level: 1
+sphincsshake256128frobust:
+ claimed-nist-level: 1
+sphincsshake256128srobust:
+ claimed-nist-level: 1
+sphincsharaka128fsimple:
+ claimed-nist-level: 1
+sphincsharaka128srobust:
+ claimed-nist-level: 1
+sphincsharaka128ssimple:
+ claimed-nist-level: 1
+sphincsharaka192frobust:
+ claimed-nist-level: 3
+sphincsharaka192fsimple:
+ claimed-nist-level: 3
+sphincsharaka192srobust:
+ claimed-nist-level: 3
+sphincsharaka192ssimple:
+ claimed-nist-level: 3
+sphincsshake256192frobust:
+ claimed-nist-level: 3
+sphincsshake256192srobust:
+ claimed-nist-level: 3
+sphincsharaka256frobust:
+ claimed-nist-level: 3
+sphincsharaka256fsimple:
+ claimed-nist-level: 5
+sphincsharaka256srobust:
+ claimed-nist-level: 5
+sphincsharaka256ssimple:
+ claimed-nist-level: 5
+sphincssha26128frobust:
+ claimed-nist-level: 5
+sphincssha256128srobust:
+ claimed-nist-level: 5
+sphincssha256192frobust:
+ claimed-nist-level: 5
+sphincssha256192srobust:
+ claimed-nist-level: 5
+sphincssha256256frobust:
+ claimed-nist-level: 5
+sphincssha256256srobust:
+ claimed-nist-level: 5
+sphincsshake256256frobust:
+ claimed-nist-level: 5
+sphincsshake256256srobust:
+ claimed-nist-level: 5
+
+
--- /dev/null
+| Family | Implementation Version | Variant | NIST round | Claimed NIST Level | Code Point | Hybrid Elliptic Curve (if any) |
+|:---------------|:-------------------------|:---------------|-------------:|---------------------:|:-------------|:---------------------------------|
+| BIKE | 5.1 | bikel1 | 4 | 1 | 0x0241 | |
+| BIKE | 5.1 | bikel1 | 4 | 1 | 0x2F41 | secp256_r1 |
+| BIKE | 5.1 | bikel1 | 4 | 1 | 0x2FAE | x25519 |
+| BIKE | 5.1 | bikel3 | 4 | 3 | 0x0242 | |
+| BIKE | 5.1 | bikel3 | 4 | 3 | 0x2F42 | secp384_r1 |
+| BIKE | 5.1 | bikel3 | 4 | 3 | 0x2FAF | x448 |
+| BIKE | 5.1 | bikel5 | 4 | 5 | 0x0243 | |
+| BIKE | 5.1 | bikel5 | 4 | 5 | 0x2F43 | secp521_r1 |
+| BIKE | NIST Round 2 submission | bike1l1cpa | 2 | 1 | 0x0206 | |
+| BIKE | NIST Round 2 submission | bike1l1cpa | 2 | 1 | 0x2F06 | secp256_r1 |
+| BIKE | NIST Round 2 submission | bike1l1fo | 2 | 1 | 0x0223 | |
+| BIKE | NIST Round 2 submission | bike1l1fo | 2 | 1 | 0x2F23 | secp256_r1 |
+| BIKE | NIST Round 2 submission | bike1l1fo | 2 | 1 | 0x2F28 | x25519 |
+| BIKE | NIST Round 2 submission | bike1l3cpa | 2 | 3 | 0x0207 | |
+| BIKE | NIST Round 2 submission | bike1l3cpa | 2 | 3 | 0x2F07 | secp384_r1 |
+| BIKE | NIST Round 2 submission | bike1l3fo | 2 | 3 | 0x0224 | |
+| BIKE | NIST Round 2 submission | bike1l3fo | 2 | 3 | 0x2F24 | secp384_r1 |
+| BIKE | NIST Round 3 submission | bikel1 | 3 | 1 | 0x0238 | |
+| BIKE | NIST Round 3 submission | bikel1 | 3 | 1 | 0x2F37 | x25519 |
+| BIKE | NIST Round 3 submission | bikel1 | 3 | 1 | 0x2F38 | secp256_r1 |
+| BIKE | NIST Round 3 submission | bikel3 | 3 | 3 | 0x023B | |
+| BIKE | NIST Round 3 submission | bikel3 | 3 | 3 | 0x2F3B | secp384_r1 |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber1024 | 2 | 5 | 0x0211 | |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber1024 | 2 | 5 | 0x2F11 | secp521_r1 |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber512 | 2 | 1 | 0x020F | |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber512 | 2 | 1 | 0x2F0F | secp256_r1 |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber512 | 2 | 1 | 0x2F26 | x25519 |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber768 | 2 | 3 | 0x0210 | |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber768 | 2 | 3 | 0x2F10 | secp384_r1 |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber90s1024 | 2 | 5 | 0x022B | |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber90s1024 | 2 | 5 | 0x2F2B | secp521_r1 |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber90s512 | 2 | 1 | 0x0229 | |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber90s512 | 2 | 1 | 0x2F29 | secp256_r1 |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber90s768 | 2 | 3 | 0x022A | |
+| CRYSTALS-Kyber | NIST Round 2 submission | kyber90s768 | 2 | 3 | 0x2F2A | secp384_r1 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber1024 | 3 | 5 | 0x023D | |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber1024 | 3 | 5 | 0x2F3D | secp521_r1 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber512 | 3 | 1 | 0x023A | |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber512 | 3 | 1 | 0x2F39 | x25519 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber512 | 3 | 1 | 0x2F3A | secp256_r1 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber768 | 3 | 3 | 0x023C | |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber768 | 3 | 3 | 0x2F3C | secp384_r1 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber768 | 3 | 3 | 0x2F90 | x448 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber768 | 3 | 3 | 0x6399 | x25519 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber768 | 3 | 3 | 0x639A | p256 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber90s1024 | 3 | 5 | 0x0240 | |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber90s1024 | 3 | 5 | 0x2F40 | secp521_r1 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber90s512 | 3 | 1 | 0x023E | |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber90s512 | 3 | 1 | 0x2F3E | secp256_r1 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber90s512 | 3 | 1 | 0x2FA9 | x25519 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber90s768 | 3 | 3 | 0x023F | |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber90s768 | 3 | 3 | 0x2F3F | secp384_r1 |
+| CRYSTALS-Kyber | NIST Round 3 submission | kyber90s768 | 3 | 3 | 0x2FAA | x448 |
+| FrodoKEM | NIST Round 3 submission | frodo1344aes | 3 | 5 | 0x0204 | |
+| FrodoKEM | NIST Round 3 submission | frodo1344aes | 3 | 5 | 0x2F04 | secp521_r1 |
+| FrodoKEM | NIST Round 3 submission | frodo1344shake | 3 | 5 | 0x0205 | |
+| FrodoKEM | NIST Round 3 submission | frodo1344shake | 3 | 5 | 0x2F05 | secp521_r1 |
+| FrodoKEM | NIST Round 3 submission | frodo640aes | 3 | 1 | 0x0200 | |
+| FrodoKEM | NIST Round 3 submission | frodo640aes | 3 | 1 | 0x2F00 | secp256_r1 |
+| FrodoKEM | NIST Round 3 submission | frodo640aes | 3 | 1 | 0x2F80 | x25519 |
+| FrodoKEM | NIST Round 3 submission | frodo640shake | 3 | 1 | 0x0201 | |
+| FrodoKEM | NIST Round 3 submission | frodo640shake | 3 | 1 | 0x2F01 | secp256_r1 |
+| FrodoKEM | NIST Round 3 submission | frodo640shake | 3 | 1 | 0x2F81 | x25519 |
+| FrodoKEM | NIST Round 3 submission | frodo976aes | 3 | 3 | 0x0202 | |
+| FrodoKEM | NIST Round 3 submission | frodo976aes | 3 | 3 | 0x2F02 | secp384_r1 |
+| FrodoKEM | NIST Round 3 submission | frodo976aes | 3 | 3 | 0x2F82 | x448 |
+| FrodoKEM | NIST Round 3 submission | frodo976shake | 3 | 3 | 0x0203 | |
+| FrodoKEM | NIST Round 3 submission | frodo976shake | 3 | 3 | 0x2F03 | secp384_r1 |
+| FrodoKEM | NIST Round 3 submission | frodo976shake | 3 | 3 | 0x2F83 | x448 |
+| HQC | NIST Round 3 submission | hqc128 | 3 | 1 | 0x022C | |
+| HQC | NIST Round 3 submission | hqc128 | 3 | 1 | 0x2F2C | secp256_r1 |
+| HQC | NIST Round 3 submission | hqc128 | 3 | 1 | 0x2FAC | x25519 |
+| HQC | NIST Round 3 submission | hqc192 | 3 | 3 | 0x022D | |
+| HQC | NIST Round 3 submission | hqc192 | 3 | 3 | 0x2F2D | secp384_r1 |
+| HQC | NIST Round 3 submission | hqc192 | 3 | 3 | 0x2FAD | x448 |
+| HQC | NIST Round 3 submission | hqc256 | 3 | 5 | 0x022E | |
+| HQC | NIST Round 3 submission | hqc256 | 3 | 5 | 0x2F2E | secp521_r1 |
--- /dev/null
+| Algorithm | Implementation Version | NIST round | Claimed NIST Level | Code Point | OID |
+|:--------------------------------------------------|:----------------------------------------------|-------------:|---------------------:|:-------------|:-------------------------|
+| dilithium2 | 3.1 | 3 | 2 | 0xfea0 | 1.3.6.1.4.1.2.267.7.4.4 |
+| dilithium2 **hybrid with** p256 | 3.1 | 3 | 2 | 0xfea1 | 1.3.9999.2.7.1 |
+| dilithium2 **hybrid with** rsa3072 | 3.1 | 3 | 2 | 0xfea2 | 1.3.9999.2.7.2 |
+| dilithium3 | 3.1 | 3 | 3 | 0xfea3 | 1.3.6.1.4.1.2.267.7.6.5 |
+| dilithium3 **hybrid with** p384 | 3.1 | 3 | 3 | 0xfea4 | 1.3.9999.2.7.3 |
+| dilithium5 | 3.1 | 3 | 5 | 0xfea5 | 1.3.6.1.4.1.2.267.7.8.7 |
+| dilithium5 **hybrid with** p521 | 3.1 | 3 | 5 | 0xfea6 | 1.3.9999.2.7.4 |
+| dilithium2_aes | NIST Round 3 submission | 3 | 2 | 0xfea7 | 1.3.6.1.4.1.2.267.11.4.4 |
+| dilithium2_aes **hybrid with** p256 | NIST Round 3 submission | 3 | 2 | 0xfea8 | 1.3.9999.2.11.1 |
+| dilithium2_aes **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 2 | 0xfea9 | 1.3.9999.2.11.2 |
+| dilithium3_aes | NIST Round 3 submission | 3 | 3 | 0xfeaa | 1.3.6.1.4.1.2.267.11.6.5 |
+| dilithium3_aes **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfeab | 1.3.9999.2.11.3 |
+| dilithium5_aes | NIST Round 3 submission | 3 | 5 | 0xfeac | 1.3.6.1.4.1.2.267.11.8.7 |
+| dilithium5_aes **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfead | 1.3.9999.2.11.4 |
+| falcon512 | 20211101 | 3 | 1 | 0xfeae | 1.3.9999.3.6 |
+| falcon512 **hybrid with** p256 | 20211101 | 3 | 1 | 0xfeaf | 1.3.9999.3.7 |
+| falcon512 **hybrid with** rsa3072 | 20211101 | 3 | 1 | 0xfeb0 | 1.3.9999.3.8 |
+| falcon512 | NIST Round 3 submission | 3 | 1 | 0xfe0b | 1.3.9999.3.1 |
+| falcon512 **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe0c | 1.3.9999.3.2 |
+| falcon512 **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe0d | 1.3.9999.3.3 |
+| falcon1024 | 20211101 | 3 | 5 | 0xfeb1 | 1.3.9999.3.9 |
+| falcon1024 **hybrid with** p521 | 20211101 | 3 | 5 | 0xfeb2 | 1.3.9999.3.10 |
+| falcon1024 | NIST Round 3 submission | 3 | 5 | 0xfe0e | 1.3.9999.3.4 |
+| falcon1024 **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe0f | 1.3.9999.3.5 |
+| sphincsharaka128frobust | NIST Round 3 submission | 3 | 1 | 0xfe42 | 1.3.9999.6.1.1 |
+| sphincsharaka128frobust **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe43 | 1.3.9999.6.1.2 |
+| sphincsharaka128frobust **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe44 | 1.3.9999.6.1.3 |
+| sphincsharaka128fsimple | NIST Round 3 submission | 3 | 1 | 0xfe45 | 1.3.9999.6.1.4 |
+| sphincsharaka128fsimple **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe46 | 1.3.9999.6.1.5 |
+| sphincsharaka128fsimple **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe47 | 1.3.9999.6.1.6 |
+| sphincsharaka128srobust | NIST Round 3 submission | 3 | 1 | 0xfe48 | 1.3.9999.6.1.7 |
+| sphincsharaka128srobust **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe49 | 1.3.9999.6.1.8 |
+| sphincsharaka128srobust **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe4a | 1.3.9999.6.1.9 |
+| sphincsharaka128ssimple | NIST Round 3 submission | 3 | 1 | 0xfe4b | 1.3.9999.6.1.10 |
+| sphincsharaka128ssimple **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe4c | 1.3.9999.6.1.11 |
+| sphincsharaka128ssimple **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe4d | 1.3.9999.6.1.12 |
+| sphincsharaka192frobust | NIST Round 3 submission | 3 | 3 | 0xfe4e | 1.3.9999.6.2.1 |
+| sphincsharaka192frobust **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe4f | 1.3.9999.6.2.2 |
+| sphincsharaka192fsimple | NIST Round 3 submission | 3 | 3 | 0xfe50 | 1.3.9999.6.2.3 |
+| sphincsharaka192fsimple **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe51 | 1.3.9999.6.2.4 |
+| sphincsharaka192srobust | NIST Round 3 submission | 3 | 3 | 0xfe52 | 1.3.9999.6.2.5 |
+| sphincsharaka192srobust **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe53 | 1.3.9999.6.2.6 |
+| sphincsharaka192ssimple | NIST Round 3 submission | 3 | 3 | 0xfe54 | 1.3.9999.6.2.7 |
+| sphincsharaka192ssimple **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe55 | 1.3.9999.6.2.8 |
+| sphincsharaka256frobust | NIST Round 3 submission | 3 | 3 | 0xfe56 | 1.3.9999.6.3.1 |
+| sphincsharaka256frobust **hybrid with** p521 | NIST Round 3 submission | 3 | 3 | 0xfe57 | 1.3.9999.6.3.2 |
+| sphincsharaka256fsimple | NIST Round 3 submission | 3 | 5 | 0xfe58 | 1.3.9999.6.3.3 |
+| sphincsharaka256fsimple **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe59 | 1.3.9999.6.3.4 |
+| sphincsharaka256srobust | NIST Round 3 submission | 3 | 5 | 0xfe5a | 1.3.9999.6.3.5 |
+| sphincsharaka256srobust **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe5b | 1.3.9999.6.3.6 |
+| sphincsharaka256ssimple | NIST Round 3 submission | 3 | 5 | 0xfe5c | 1.3.9999.6.3.7 |
+| sphincsharaka256ssimple **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe5d | 1.3.9999.6.3.8 |
+| sphincssha26128frobust | NIST Round 3 submission | 3 | 5 | 0xfe5e | 1.3.9999.6.4.1 |
+| sphincssha26128frobust **hybrid with** p256 | NIST Round 3 submission | 3 | 5 | 0xfe5f | 1.3.9999.6.4.2 |
+| sphincssha26128frobust **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 5 | 0xfe60 | 1.3.9999.6.4.3 |
+| sphincssha2128fsimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfeb3 | 1.3.9999.6.4.13 |
+| sphincssha2128fsimple **hybrid with** p256 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfeb4 | 1.3.9999.6.4.14 |
+| sphincssha2128fsimple **hybrid with** rsa3072 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfeb5 | 1.3.9999.6.4.15 |
+| sphincssha2128fsimple | NIST Round 3 submission | 3 | 1 | 0xfe61 | 1.3.9999.6.4.4 |
+| sphincssha2128fsimple **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe62 | 1.3.9999.6.4.5 |
+| sphincssha2128fsimple **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe63 | 1.3.9999.6.4.6 |
+| sphincssha256128srobust | NIST Round 3 submission | 3 | 5 | 0xfe64 | 1.3.9999.6.4.7 |
+| sphincssha256128srobust **hybrid with** p256 | NIST Round 3 submission | 3 | 5 | 0xfe65 | 1.3.9999.6.4.8 |
+| sphincssha256128srobust **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 5 | 0xfe66 | 1.3.9999.6.4.9 |
+| sphincssha2128ssimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfeb6 | 1.3.9999.6.4.16 |
+| sphincssha2128ssimple **hybrid with** p256 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfeb7 | 1.3.9999.6.4.17 |
+| sphincssha2128ssimple **hybrid with** rsa3072 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfeb8 | 1.3.9999.6.4.18 |
+| sphincssha2128ssimple | NIST Round 3 submission | 3 | 1 | 0xfe67 | 1.3.9999.6.4.10 |
+| sphincssha2128ssimple **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe68 | 1.3.9999.6.4.11 |
+| sphincssha2128ssimple **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe69 | 1.3.9999.6.4.12 |
+| sphincssha256192frobust | NIST Round 3 submission | 3 | 5 | 0xfe6a | 1.3.9999.6.5.1 |
+| sphincssha256192frobust **hybrid with** p384 | NIST Round 3 submission | 3 | 5 | 0xfe6b | 1.3.9999.6.5.2 |
+| sphincssha2192fsimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 3 | 0xfeb9 | 1.3.9999.6.5.10 |
+| sphincssha2192fsimple **hybrid with** p384 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 3 | 0xfeba | 1.3.9999.6.5.11 |
+| sphincssha2192fsimple | NIST Round 3 submission | 3 | 3 | 0xfe6c | 1.3.9999.6.5.3 |
+| sphincssha2192fsimple **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe6d | 1.3.9999.6.5.4 |
+| sphincssha256192srobust | NIST Round 3 submission | 3 | 5 | 0xfe6e | 1.3.9999.6.5.5 |
+| sphincssha256192srobust **hybrid with** p384 | NIST Round 3 submission | 3 | 5 | 0xfe6f | 1.3.9999.6.5.6 |
+| sphincssha2192ssimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 3 | 0xfebb | 1.3.9999.6.5.12 |
+| sphincssha2192ssimple **hybrid with** p384 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 3 | 0xfebc | 1.3.9999.6.5.13 |
+| sphincssha2192ssimple | NIST Round 3 submission | 3 | 3 | 0xfe70 | 1.3.9999.6.5.7 |
+| sphincssha2192ssimple **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe71 | 1.3.9999.6.5.8 |
+| sphincssha256256frobust | NIST Round 3 submission | 3 | 5 | 0xfe72 | 1.3.9999.6.6.1 |
+| sphincssha256256frobust **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe73 | 1.3.9999.6.6.2 |
+| sphincssha2256fsimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 5 | 0xfebd | 1.3.9999.6.6.10 |
+| sphincssha2256fsimple **hybrid with** p521 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 5 | 0xfebe | 1.3.9999.6.6.11 |
+| sphincssha2256fsimple | NIST Round 3 submission | 3 | 5 | 0xfe74 | 1.3.9999.6.6.3 |
+| sphincssha2256fsimple **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe75 | 1.3.9999.6.6.4 |
+| sphincssha256256srobust | NIST Round 3 submission | 3 | 5 | 0xfe76 | 1.3.9999.6.6.5 |
+| sphincssha256256srobust **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe77 | 1.3.9999.6.6.6 |
+| sphincssha2256ssimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 5 | 0xfec0 | 1.3.9999.6.6.12 |
+| sphincssha2256ssimple **hybrid with** p521 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 5 | 0xfec1 | 1.3.9999.6.6.13 |
+| sphincssha2256ssimple | NIST Round 3 submission | 3 | 5 | 0xfe78 | 1.3.9999.6.6.7 |
+| sphincssha2256ssimple **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe79 | 1.3.9999.6.6.8 |
+| sphincsshake256128frobust | NIST Round 3 submission | 3 | 1 | 0xfe7a | 1.3.9999.6.7.1 |
+| sphincsshake256128frobust **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe7b | 1.3.9999.6.7.2 |
+| sphincsshake256128frobust **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe7c | 1.3.9999.6.7.3 |
+| sphincsshake128fsimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfec2 | 1.3.9999.6.7.13 |
+| sphincsshake128fsimple **hybrid with** p256 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfec3 | 1.3.9999.6.7.14 |
+| sphincsshake128fsimple **hybrid with** rsa3072 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfec4 | 1.3.9999.6.7.15 |
+| sphincsshake128fsimple | NIST Round 3 submission | 3 | 1 | 0xfe7d | 1.3.9999.6.7.4 |
+| sphincsshake128fsimple **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe7e | 1.3.9999.6.7.5 |
+| sphincsshake128fsimple **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe7f | 1.3.9999.6.7.6 |
+| sphincsshake256128srobust | NIST Round 3 submission | 3 | 1 | 0xfe80 | 1.3.9999.6.7.7 |
+| sphincsshake256128srobust **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe81 | 1.3.9999.6.7.8 |
+| sphincsshake256128srobust **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe82 | 1.3.9999.6.7.9 |
+| sphincsshake128ssimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfec5 | 1.3.9999.6.7.16 |
+| sphincsshake128ssimple **hybrid with** p256 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfec6 | 1.3.9999.6.7.17 |
+| sphincsshake128ssimple **hybrid with** rsa3072 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 1 | 0xfec7 | 1.3.9999.6.7.18 |
+| sphincsshake128ssimple | NIST Round 3 submission | 3 | 1 | 0xfe83 | 1.3.9999.6.7.10 |
+| sphincsshake128ssimple **hybrid with** p256 | NIST Round 3 submission | 3 | 1 | 0xfe84 | 1.3.9999.6.7.11 |
+| sphincsshake128ssimple **hybrid with** rsa3072 | NIST Round 3 submission | 3 | 1 | 0xfe85 | 1.3.9999.6.7.12 |
+| sphincsshake256192frobust | NIST Round 3 submission | 3 | 3 | 0xfe86 | 1.3.9999.6.8.1 |
+| sphincsshake256192frobust **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe87 | 1.3.9999.6.8.2 |
+| sphincsshake192fsimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 3 | 0xfec8 | 1.3.9999.6.8.10 |
+| sphincsshake192fsimple **hybrid with** p384 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 3 | 0xfec9 | 1.3.9999.6.8.11 |
+| sphincsshake192fsimple | NIST Round 3 submission | 3 | 3 | 0xfe88 | 1.3.9999.6.8.3 |
+| sphincsshake192fsimple **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe89 | 1.3.9999.6.8.4 |
+| sphincsshake256192srobust | NIST Round 3 submission | 3 | 3 | 0xfe8a | 1.3.9999.6.8.5 |
+| sphincsshake256192srobust **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe8b | 1.3.9999.6.8.6 |
+| sphincsshake192ssimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 3 | 0xfeca | 1.3.9999.6.8.12 |
+| sphincsshake192ssimple **hybrid with** p384 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 3 | 0xfecb | 1.3.9999.6.8.13 |
+| sphincsshake192ssimple | NIST Round 3 submission | 3 | 3 | 0xfe8c | 1.3.9999.6.8.7 |
+| sphincsshake192ssimple **hybrid with** p384 | NIST Round 3 submission | 3 | 3 | 0xfe8d | 1.3.9999.6.8.8 |
+| sphincsshake256256frobust | NIST Round 3 submission | 3 | 5 | 0xfe8e | 1.3.9999.6.9.1 |
+| sphincsshake256256frobust **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe8f | 1.3.9999.6.9.2 |
+| sphincsshake256fsimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 5 | 0xfecc | 1.3.9999.6.9.10 |
+| sphincsshake256fsimple **hybrid with** p521 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 5 | 0xfecd | 1.3.9999.6.9.11 |
+| sphincsshake256fsimple | NIST Round 3 submission | 3 | 5 | 0xfe90 | 1.3.9999.6.9.3 |
+| sphincsshake256fsimple **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe91 | 1.3.9999.6.9.4 |
+| sphincsshake256256srobust | NIST Round 3 submission | 3 | 5 | 0xfe92 | 1.3.9999.6.9.5 |
+| sphincsshake256256srobust **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe93 | 1.3.9999.6.9.6 |
+| sphincsshake256ssimple | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 5 | 0xfece | 1.3.9999.6.9.12 |
+| sphincsshake256ssimple **hybrid with** p521 | NIST Round 3 submission, v3.1 (June 10, 2022) | 3 | 5 | 0xfecf | 1.3.9999.6.9.13 |
+| sphincsshake256ssimple | NIST Round 3 submission | 3 | 5 | 0xfe94 | 1.3.9999.6.9.7 |
+| sphincsshake256ssimple **hybrid with** p521 | NIST Round 3 submission | 3 | 5 | 0xfe95 | 1.3.9999.6.9.8 |
\ No newline at end of file
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+MAKE_DECODER("{{ variant['name'] }}", {{ variant['name'] }}, oqsx, PrivateKeyInfo);
+MAKE_DECODER("{{ variant['name'] }}", {{ variant['name'] }}, oqsx, SubjectPublicKeyInfo);
+ {%- for classical_alg in variant['mix_with'] %}
+MAKE_DECODER("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, PrivateKeyInfo);
+MAKE_DECODER("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, SubjectPublicKeyInfo);
+ {%- endfor -%}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+# define {{ variant['name'] }}_evp_type 0
+# define {{ variant['name'] }}_input_type "{{ variant['name'] }}"
+# define {{ variant['name'] }}_pem_type "{{ variant['name'] }}"
+ {%- for classical_alg in variant['mix_with'] %}
+# define {{ classical_alg['name'] }}_{{ variant['name'] }}_evp_type 0
+# define {{ classical_alg['name'] }}_{{ variant['name'] }}_input_type "{{ classical_alg['name'] }}_{{ variant['name'] }}"
+# define {{ classical_alg['name'] }}_{{ variant['name'] }}_pem_type "{{ classical_alg['name'] }}_{{ variant['name'] }}"
+ {%- endfor -%}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+MAKE_ENCODER({{ variant['name'] }}, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER({{ variant['name'] }}, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER({{ variant['name'] }}, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER({{ variant['name'] }}, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER({{ variant['name'] }}, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER({{ variant['name'] }}, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER({{ variant['name'] }});
+ {%- for classical_alg in variant['mix_with'] %}
+MAKE_ENCODER({{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER({{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER({{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER({{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER({{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER({{ classical_alg['name'] }}_{{ variant['name'] }}, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER({{ classical_alg['name'] }}_{{ variant['name'] }});
+ {%- endfor -%}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% set count = namespace(val=-1) -%}
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+ {%- set count.val = count.val + 1 %}
+static void *{{variant['name']}}_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{variant['name']}}", KEY_TYPE_SIG, NULL, {{variant['security']}}, {{ count.val }});
+}
+
+static void *{{variant['name']}}_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{variant['name']}}", 0, {{variant['security']}}, {{ count.val }});
+}
+
+ {%- for classical_alg in variant['mix_with'] %}
+ {%- set count.val = count.val + 1 %}
+static void *{{ classical_alg['name'] }}_{{variant['name']}}_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), {{variant['oqs_meth']}}, "{{ classical_alg['name'] }}_{{variant['name']}}", KEY_TYPE_HYB_SIG, NULL, {{variant['security']}}, {{ count.val }});
+}
+
+static void *{{ classical_alg['name'] }}_{{variant['name']}}_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, {{variant['oqs_meth']}}, "{{ classical_alg['name'] }}_{{variant['name']}}", KEY_TYPE_HYB_SIG, {{variant['security']}}, {{ count.val }});
+}
+
+ {%- endfor -%}
+ {%- endfor %}
+{% endfor %}
+
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+MAKE_SIG_KEYMGMT_FUNCTIONS({{variant['name']}})
+ {%- for classical_alg in variant['mix_with'] %}
+MAKE_SIG_KEYMGMT_FUNCTIONS({{ classical_alg['name'] }}_{{variant['name']}})
+ {%- endfor -%}
+ {%- endfor %}
+{%- endfor %}
+{% for kem in config['kems'] %}
+MAKE_KEM_KEYMGMT_FUNCTIONS({{kem['name_group']}}, {{kem['oqs_alg']}}, {{kem['bit_security']}})
+{% for hybrid in kem['hybrids'] %}
+{% if hybrid['hybrid_group'].startswith('p') -%}
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS({{hybrid['hybrid_group']}}_{{kem['name_group']}}, {{kem['oqs_alg']}}, {{hybrid['bit_security']}})
+{%- else %}
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS({{hybrid['hybrid_group']}}_{{kem['name_group']}}, {{kem['oqs_alg']}}, {{hybrid['bit_security']}})
+{%- endif %}
+{%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_keymgmt_functions[];
+ {%- for classical_alg in variant['mix_with'] -%}
+extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_keymgmt_functions[];
+ {%- endfor -%}
+ {%- endfor %}
+{%- endfor %}
+{% for kem in config['kems'] %}
+extern const OSSL_DISPATCH oqs_{{ kem['name_group'] }}_keymgmt_functions[];
+{% for hybrid in kem['hybrids'] %}
+{% if hybrid['hybrid_group'].startswith('p') -%}
+extern const OSSL_DISPATCH oqs_ecp_{{ hybrid['hybrid_group']}}_{{ kem['name_group'] }}_keymgmt_functions[];
+{%- else -%}
+extern const OSSL_DISPATCH oqs_ecx_{{ hybrid['hybrid_group']}}_{{ kem['name_group'] }}_keymgmt_functions[];
+{%- endif %}
+{%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ variant['name'] }}_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_{{ variant['name'] }}_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_{{ variant['name'] }}_decoder_functions[];
+ {%- for classical_alg in variant['mix_with'] -%}
+extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_{{ classical_alg['name'] }}_{{ variant['name'] }}_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_{{ classical_alg['name'] }}_{{ variant['name'] }}_decoder_functions[];
+ {%- endfor -%}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+#ifdef OQS_ENABLE_SIG_{{ variant['oqs_meth']|replace("OQS_SIG_alg_","") }}
+DECODER_w_structure("{{ variant['name'] }}", der, PrivateKeyInfo, {{ variant['name'] }}),
+DECODER_w_structure("{{ variant['name'] }}", der, SubjectPublicKeyInfo, {{ variant['name'] }}),
+ {%- for classical_alg in variant['mix_with'] -%}
+DECODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", der, PrivateKeyInfo, {{ classical_alg['name'] }}_{{ variant['name'] }}),
+DECODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", der, SubjectPublicKeyInfo, {{ classical_alg['name'] }}_{{ variant['name'] }}),
+ {%- endfor %}
+#endif
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+#ifdef OQS_ENABLE_SIG_{{ variant['oqs_meth']|replace("OQS_SIG_alg_","") }}
+ENCODER_w_structure("{{ variant['name'] }}", {{ variant['name'] }}, der, PrivateKeyInfo),
+ENCODER_w_structure("{{ variant['name'] }}", {{ variant['name'] }}, pem, PrivateKeyInfo),
+ENCODER_w_structure("{{ variant['name'] }}", {{ variant['name'] }}, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("{{ variant['name'] }}", {{ variant['name'] }}, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("{{ variant['name'] }}", {{ variant['name'] }}, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("{{ variant['name'] }}", {{ variant['name'] }}, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("{{ variant['name'] }}", {{ variant['name'] }}),
+{% for classical_alg in variant['mix_with'] -%}
+ENCODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, der, PrivateKeyInfo),
+ENCODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, pem, PrivateKeyInfo),
+ENCODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("{{ classical_alg['name'] }}_{{ variant['name'] }}", {{ classical_alg['name'] }}_{{ variant['name'] }}),
+{% endfor -%}
+#endif
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% set count = namespace(val=0) %}
+{%- for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+{%- set count.val = count.val + 1 -%}
+ {%- for classical_alg in variant['mix_with'] %}
+{%- set count.val = count.val + 1 -%}
+ {%- endfor %}
+ {%- endfor %}
+{%- endfor %}
+#define OQS_OID_CNT {{ count.val*2 }}
+const char* oqs_oid_alg_list[OQS_OID_CNT] =
+{
+
+{%- for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+"{{ variant['oid'] }}", "{{ variant['name'] }}",
+ {%- for classical_alg in variant['mix_with'] %}
+"{{ classical_alg['oid'] }}" , "{{ classical_alg['name'] }}_{{ variant['name'] }}",
+ {%- endfor %}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% set cnt = namespace(val=-2) %}
+{%- for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+ {%- set cnt.val = cnt.val + 2 %}
+ if (getenv("OQS_ENCODING_{{variant['name']|upper}}")) oqs_alg_encoding_list[{{ cnt.val }}] = getenv("OQS_ENCODING_{{variant['name']|upper}}");
+ if (getenv("OQS_ENCODING_{{variant['name']|upper}}_ALGNAME")) oqs_alg_encoding_list[{{ cnt.val + 1 }}] = getenv("OQS_ENCODING_{{variant['name']|upper}}_ALGNAME");
+ {%- for classical_alg in variant['mix_with'] %}
+ {%- set cnt.val = cnt.val + 2 %}
+ if (getenv("OQS_ENCODING_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}")) oqs_alg_encoding_list[{{ cnt.val }}] = getenv("OQS_ENCODING_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}");
+ if (getenv("OQS_ENCODING_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}_ALGNAME")) oqs_alg_encoding_list[{{ cnt.val + 1 }}] = getenv("OQS_ENCODING_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}_ALGNAME");
+ {%- endfor %}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{%- for kem in config['kems'] %}
+#ifdef OQS_ENABLE_KEM_{{ kem['oqs_alg']|replace("OQS_KEM_alg_","") }}
+ KEMBASEALG({{kem['name_group']}}, {{kem['bit_security']}})
+{%- for hybrid in kem['hybrids'] %}
+ KEMHYBALG({{hybrid['hybrid_group']}}_{{kem['name_group']}}, {{hybrid['bit_security']}})
+{%- endfor %}
+#endif
+{%- endfor %}
+
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+#ifdef OQS_ENABLE_SIG_{{ variant['oqs_meth']|replace("OQS_SIG_alg_","") }}
+ SIGALG("{{variant['name']}}", {{variant['security']}}, oqs_{{ variant['name'] }}_keymgmt_functions),
+ {%- for classical_alg in variant['mix_with'] %}
+ SIGALG("{{ classical_alg['name'] }}_{{variant['name']}}", {{variant['security']}}, oqs_{{ classical_alg['name'] }}_{{ variant['name'] }}_keymgmt_functions),
+ {%- endfor %}
+#endif
+ {%- endfor %}
+{%- endfor %}
+{% for kem in config['kems'] %}
+#ifdef OQS_ENABLE_KEM_{{ kem['oqs_alg']|replace("OQS_KEM_alg_","") }}
+ KEMKMALG({{ kem['name_group'] }}, {{ kem['bit_security'] }})
+{% for hybrid in kem['hybrids'] %}
+{% if hybrid['hybrid_group'].startswith('x') %} KEMKMHYBALG({{ hybrid['hybrid_group']}}_{{kem['name_group'] }}, {{ hybrid['bit_security'] }}, ecx){% else %} KEMKMHYBALG({{ hybrid['hybrid_group']}}_{{ kem['name_group'] }}, {{ hybrid['bit_security'] }}, ecp){% endif %}
+{%- endfor %}
+#endif
+{%- endfor %}
+
--- /dev/null
+{% set cnt = namespace(val=-2) %}
+{%- for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+ {%- set cnt.val = cnt.val + 2 %}
+ if (getenv("OQS_OID_{{variant['name']|upper}}")) oqs_oid_alg_list[{{ cnt.val }}] = getenv("OQS_OID_{{variant['name']|upper}}");
+ {%- for classical_alg in variant['mix_with'] %}
+ {%- set cnt.val = cnt.val + 2 %}
+ if (getenv("OQS_OID_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}")) oqs_oid_alg_list[{{ cnt.val }}] = getenv("OQS_OID_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}");
+ {%- endfor %}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+#ifdef OQS_ENABLE_SIG_{{ variant['oqs_meth']|replace("OQS_SIG_alg_","") }}
+ SIGALG("{{variant['name']}}", {{variant['security']}}, oqs_signature_functions),
+ {%- for classical_alg in variant['mix_with'] %}
+ SIGALG("{{ classical_alg['name'] }}_{{variant['name']}}", {{variant['security']}}, oqs_signature_functions),
+ {%- endfor %}
+#endif
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% set cnt = namespace(val=-1) %}
+{%- for kem in config['kems'] %}
+ {%- set cnt.val = cnt.val + 1 %}
+ if (getenv("OQS_CODEPOINT_{{ kem['name_group']|upper }}")) oqs_group_list[{{ cnt.val }}].group_id = atoi(getenv("OQS_CODEPOINT_{{ kem['name_group']|upper }}"));
+{%- for hybrid in kem['hybrids'] %}
+ {%- set cnt.val = cnt.val + 1 %}
+ if (getenv("OQS_CODEPOINT_{{ hybrid['hybrid_group']|upper }}_{{ kem['name_group']|upper }}")) oqs_group_list[{{ cnt.val }}].group_id = atoi(getenv("OQS_CODEPOINT_{{ hybrid['hybrid_group']|upper }}_{{ kem['name_group']|upper }}"));
+{%- endfor %}
+{%- endfor %}
+{% set cnt = namespace(val=-1) %}
+{%- for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+ {%- set cnt.val = cnt.val + 1 %}
+ if (getenv("OQS_CODEPOINT_{{variant['name']|upper}}")) oqs_sigalg_list[{{ cnt.val }}].code_point = atoi(getenv("OQS_CODEPOINT_{{variant['name']|upper}}"));
+ {%- for classical_alg in variant['mix_with'] %}
+ {%- set cnt.val = cnt.val + 1 %}
+ if (getenv("OQS_CODEPOINT_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}")) oqs_sigalg_list[{{ cnt.val }}].code_point = atoi(getenv("OQS_CODEPOINT_{{ classical_alg['name']|upper }}_{{variant['name']|upper}}"));
+ {%- endfor %}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% for kem in config['kems'] %}
+ { {{ kem['nid'] }}, {{ kem['bit_security'] }}, TLS1_3_VERSION, 0, -1, -1, 1 },
+{% for hybrid in kem['hybrids'] %}
+ { {{ hybrid['nid'] }}, {{ kem['bit_security'] }}, TLS1_3_VERSION, 0, -1, -1, 1 },
+{%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% set cnt = namespace(val=-1) %}
+{% for kem in config['kems'] -%}
+ {%- set cnt.val = cnt.val + 1 %}
+#ifdef OQS_ENABLE_KEM_{{ kem['oqs_alg']|replace("OQS_KEM_alg_","") }}
+ OQS_GROUP_ENTRY({{kem['name_group']}}, {{kem['name_group']}}, {{kem['name_group']}}, {{ cnt.val }}),
+{% for hybrid in kem['hybrids'] %}
+ {%- set cnt.val = cnt.val + 1 %}
+ OQS_GROUP_ENTRY({{hybrid['hybrid_group']}}_{{kem['name_group']}}, {{hybrid['hybrid_group']}}_{{kem['name_group']}}, {{hybrid['hybrid_group']}}_{{kem['name_group']}}, {{ cnt.val }}),
+
+{%- endfor %}
+#endif
+{%- endfor %}
+
--- /dev/null
+{%- for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+ { {{ variant['code_point'] }}, {{variant['security']}}, TLS1_3_VERSION, 0 },
+ {%- for classical_alg in variant['mix_with'] %}
+ { {{ classical_alg['code_point'] }}, {{ variant['security'] }}, TLS1_3_VERSION, 0 },
+ {%- endfor %}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% set cnt = namespace(val=-1) %}
+{%- for sig in config['sigs'] %}
+ {%- for variant in sig['variants'] %}
+ {%- set cnt.val = cnt.val + 1 %}
+#ifdef OQS_ENABLE_SIG_{{ variant['oqs_meth']|replace("OQS_SIG_alg_","") }}
+ OQS_SIGALG_ENTRY({{variant['name']}}, {{variant['name']}}, {{variant['name']}}, "{{ variant['oid'] }}", {{ cnt.val }}),
+ {%- for classical_alg in variant['mix_with'] %}
+ {%- set cnt.val = cnt.val + 1 %}
+ OQS_SIGALG_ENTRY({{ classical_alg['name'] }}_{{variant['name']}}, {{ classical_alg['name'] }}_{{variant['name']}}, {{ classical_alg['name'] }}_{{variant['name']}}, "{{ classical_alg['oid'] }}", {{ cnt.val }}),
+ {%- endfor %}
+#endif
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+{% set count = namespace(val=0) %}
+{%- for sig in config['sigs'] %}
+{%- for variant in sig['variants'] -%}
+{%- set count.val = count.val + 1 -%}
+{%- for classical_alg in variant['mix_with'] %}
+{%- set count.val = count.val + 1 -%}
+{%- endfor -%}
+{%- endfor -%}
+{%- endfor %}
+#define NID_TABLE_LEN {{ count.val }}
+
+static oqs_nid_name_t nid_names[NID_TABLE_LEN] = {
+{%- for sig in config['sigs'] -%}
+ {%- for variant in sig['variants'] %}
+ { 0, "{{variant['name']}}", {{variant['oqs_meth']}}, KEY_TYPE_SIG, {{variant['security']}} },
+ {%- for classical_alg in variant['mix_with'] %}
+ { 0, "{{ classical_alg['name'] }}_{{variant['name']}}", {{variant['oqs_meth']}}, KEY_TYPE_HYB_SIG, {{variant['security']}} },
+ {%- endfor %}
+ {%- endfor %}
+{%- endfor %}
+
--- /dev/null
+Jinja2==3.0.3
+MarkupSafe==2.1.3
+PyYAML==6.0
+tabulate==0.9.0
--- /dev/null
+include(GNUInstallDirs)
+execute_process(
+ COMMAND git log -1 --format=%h
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_COMMIT_HASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+)
+if (USE_ENCODING_LIB)
+ include(ExternalProject)
+ set(encoder_LIBRARY ${CMAKE_BINARY_DIR}/install/lib/${CMAKE_STATIC_LIBRARY_PREFIX}qsc_key_encoder${CMAKE_STATIC_LIBRARY_SUFFIX})
+ set(encoder_LIBRARY_INCLUDE ${CMAKE_BINARY_DIR}/install/include)
+ ExternalProject_Add(encoder
+ GIT_REPOSITORY https://github.com/Quantum-Safe-Collaboration/qsc-key-encoder.git
+ GIT_TAG main
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}/install -DCMAKE_BUILD_TYPE=Release
+ UPDATE_DISCONNECTED 1
+ BUILD_BYPRODUCTS ${encoder_LIBRARY}
+ )
+ add_library(qsc_key_encoder STATIC IMPORTED)
+ set_target_properties(qsc_key_encoder PROPERTIES IMPORTED_LOCATION ${encoder_LIBRARY})
+endif()
+add_definitions(-DOQSPROVIDER_VERSION_TEXT="${OQSPROVIDER_VERSION_TEXT}")
+message(STATUS "Building commit ${GIT_COMMIT_HASH} in ${CMAKE_SOURCE_DIR}")
+add_definitions(-DOQS_PROVIDER_COMMIT=" \(${GIT_COMMIT_HASH}\)")
+set(PROVIDER_SOURCE_FILES
+ oqsprov.c oqsprov_capabilities.c oqsprov_keys.c
+ oqs_kmgmt.c oqs_sig.c oqs_kem.c
+ oqs_encode_key2any.c oqs_endecoder_common.c oqs_decode_der2key.c oqsprov_bio.c
+ oqsprov.def
+)
+set(PROVIDER_HEADER_FILES
+ oqs_prov.h oqs_endecoder_local.h
+)
+
+set(OQS_LIBRARY_TYPE MODULE)
+if(OQS_PROVIDER_BUILD_STATIC)
+ set(OQS_LIBRARY_TYPE STATIC)
+endif()
+
+add_library(oqsprovider ${OQS_LIBRARY_TYPE} ${PROVIDER_SOURCE_FILES})
+if (USE_ENCODING_LIB)
+ add_dependencies(oqsprovider encoder)
+endif()
+set_target_properties(oqsprovider
+ PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "oqsprovider"
+ ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
+ VERSION ${OQSPROVIDER_VERSION_TEXT}
+ SOVERSION 1
+ # Compatibility version (-compatibility_version) and current version
+ # (-current_version) are not compatible with a `MODULE` library.
+ # However, `VERSION` and `SOVERSION` set these two flags.
+ # The following two flags remove them.
+ MACHO_COMPATIBILITY_VERSION OFF
+ MACHO_CURRENT_VERSION OFF
+ # For Windows DLLs
+ RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
+
+if (NOT OQS_PROVIDER_BUILD_STATIC)
+ if (APPLE)
+ # OpenSSL looks for `.dylib` files on XNU-based platforms.
+ # Because `MODULE` writes to a `.so` file by default, we must explicitely
+ # set the suffix here.
+ set_target_properties(oqsprovider
+ PROPERTIES
+ SUFFIX ".dylib"
+ )
+ endif()
+
+ if (CYGWIN OR MSVC)
+ # OpenSSL looks for `.dll` files on Windows platforms.
+ # Because `MODULE` writes to a `.so` file by default, we must explicitely
+ # set the suffix here.
+ set_target_properties(oqsprovider
+ PROPERTIES
+ SUFFIX ".dll"
+ )
+ endif()
+endif()
+
+target_link_libraries(oqsprovider PUBLIC OQS::oqs ${OPENSSL_CRYPTO_LIBRARY} ${OQS_ADDL_SOCKET_LIBS})
+if (USE_ENCODING_LIB)
+ target_link_libraries(oqsprovider PUBLIC qsc_key_encoder)
+ target_include_directories(oqsprovider PRIVATE ${encoder_LIBRARY_INCLUDE})
+endif()
+install(TARGETS oqsprovider
+ LIBRARY DESTINATION "${OPENSSL_MODULES_PATH}"
+ RUNTIME DESTINATION "${OPENSSL_MODULES_PATH}")
+set(CPACK_GENERATOR "DEB")
+set(CPACK_PACKAGE_VENDOR "www.openquantumsafe.org")
+set(CPACK_PACKAGE_VERSION ${OQSPROVIDER_VERSION_TEXT})
+set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, openssl (>= 3.0.0), liboqs (>= 0.8.0)")
+set(CPACK_DEBIAN_PACKAGE_MAINTAINER "www.openquantumsafe.org")
+include(CPack)
+
+if (OQS_PROVIDER_BUILD_STATIC)
+ targets_set_static_provider(oqsprovider)
+endif()
--- /dev/null
+/*
+ * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/core_object.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/params.h>
+#include <openssl/pem.h> /* PEM_BUFSIZE and public PEM functions */
+#include <openssl/pkcs12.h>
+#include <openssl/x509.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/proverr.h>
+//#include "internal/asn1.h"
+//instead just:
+int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); // TBD: OK to use?
+
+#include "oqs_endecoder_local.h"
+
+#ifdef NDEBUG
+#define OQS_DEC_PRINTF(a)
+#define OQS_DEC_PRINTF2(a, b)
+#define OQS_DEC_PRINTF3(a, b, c)
+#else
+#define OQS_DEC_PRINTF(a) if (getenv("OQSDEC")) printf(a)
+#define OQS_DEC_PRINTF2(a, b) if (getenv("OQSDEC")) printf(a, b)
+#define OQS_DEC_PRINTF3(a, b, c) if (getenv("OQSDEC")) printf(a, b, c)
+#endif // NDEBUG
+
+struct der2key_ctx_st; /* Forward declaration */
+typedef int check_key_fn(void *, struct der2key_ctx_st *ctx);
+typedef void adjust_key_fn(void *, struct der2key_ctx_st *ctx);
+typedef void free_key_fn(void *);
+typedef void *d2i_PKCS8_fn(void **, const unsigned char **, long,
+ struct der2key_ctx_st *);
+struct keytype_desc_st {
+ const char *keytype_name;
+ const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */
+
+ /* The input structure name */
+ const char *structure_name;
+
+ /*
+ * The EVP_PKEY_xxx type macro. Should be zero for type specific
+ * structures, non-zero when the outermost structure is PKCS#8 or
+ * SubjectPublicKeyInfo. This determines which of the function
+ * pointers below will be used.
+ */
+ int evp_type;
+
+ /* The selection mask for OSSL_FUNC_decoder_does_selection() */
+ int selection_mask;
+
+ /* For type specific decoders, we use the corresponding d2i */
+ d2i_of_void *d2i_private_key; /* From type-specific DER */
+ d2i_of_void *d2i_public_key; /* From type-specific DER */
+ d2i_of_void *d2i_key_params; /* From type-specific DER */
+ d2i_PKCS8_fn *d2i_PKCS8; /* Wrapped in a PrivateKeyInfo */
+ d2i_of_void *d2i_PUBKEY; /* Wrapped in a SubjectPublicKeyInfo */
+
+ /*
+ * For any key, we may need to check that the key meets expectations.
+ * This is useful when the same functions can decode several variants
+ * of a key.
+ */
+ check_key_fn *check_key;
+
+ /*
+ * For any key, we may need to make provider specific adjustments, such
+ * as ensure the key carries the correct library context.
+ */
+ adjust_key_fn *adjust_key;
+ /* {type}_free() */
+ free_key_fn *free_key;
+};
+
+// Start steal. Alternative: Open up d2i_X509_PUBKEY_INTERNAL
+// as per https://github.com/openssl/openssl/issues/16697 (TBD)
+// stolen from openssl/crypto/x509/x_pubkey.c as ossl_d2i_X509_PUBKEY_INTERNAL not public:
+// dangerous internal struct dependency: Suggest opening up ossl_d2i_X509_PUBKEY_INTERNAL
+// or find out how to decode X509 with own ASN1 calls
+struct X509_pubkey_st {
+ X509_ALGOR *algor;
+ ASN1_BIT_STRING *public_key;
+
+ EVP_PKEY *pkey;
+
+ /* extra data for the callback, used by d2i_PUBKEY_ex */
+ OSSL_LIB_CTX *libctx;
+ char *propq;
+
+ /* Flag to force legacy keys */
+ unsigned int flag_force_legacy : 1;
+};
+
+ASN1_SEQUENCE(X509_PUBKEY_INTERNAL) = {
+ ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
+ ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
+} static_ASN1_SEQUENCE_END_name(X509_PUBKEY, X509_PUBKEY_INTERNAL)
+
+X509_PUBKEY *oqsx_d2i_X509_PUBKEY_INTERNAL(const unsigned char **pp,
+ long len, OSSL_LIB_CTX *libctx)
+{
+ X509_PUBKEY *xpub = OPENSSL_zalloc(sizeof(*xpub));
+
+ if (xpub == NULL)
+ return NULL;
+ return (X509_PUBKEY *)ASN1_item_d2i_ex((ASN1_VALUE **)&xpub, pp, len,
+ ASN1_ITEM_rptr(X509_PUBKEY_INTERNAL),
+ libctx, NULL);
+}
+// end steal TBD
+
+
+/*
+ * Context used for DER to key decoding.
+ */
+struct der2key_ctx_st {
+ PROV_OQS_CTX *provctx;
+ struct keytype_desc_st *desc;
+ /* The selection that is passed to oqs_der2key_decode() */
+ int selection;
+ /* Flag used to signal that a failure is fatal */
+ unsigned int flag_fatal : 1;
+};
+
+int oqs_read_der(PROV_OQS_CTX *provctx, OSSL_CORE_BIO *cin, unsigned char **data,
+ long *len) {
+ OQS_DEC_PRINTF("OQS DEC provider: oqs_read_der called.\n");
+
+ BUF_MEM *mem = NULL;
+ BIO *in = oqs_bio_new_from_core_bio(provctx, cin);
+ int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
+
+ if (ok) {
+ *data = (unsigned char *)mem->data;
+ *len = (long)mem->length;
+ OPENSSL_free(mem);
+ }
+ BIO_free(in);
+ return ok;
+}
+
+typedef void *key_from_pkcs8_t(const PKCS8_PRIV_KEY_INFO *p8inf,
+ OSSL_LIB_CTX *libctx, const char *propq);
+static void *oqs_der2key_decode_p8(const unsigned char **input_der,
+ long input_der_len, struct der2key_ctx_st *ctx,
+ key_from_pkcs8_t *key_from_pkcs8)
+{
+ PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+ const X509_ALGOR *alg = NULL;
+ void *key = NULL;
+
+ OQS_DEC_PRINTF2("OQS DEC provider: oqs_der2key_decode_p8 called. Keytype: %d.\n", ctx->desc->evp_type);
+
+ if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, input_der, input_der_len)) != NULL
+ && PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf)
+ && OBJ_obj2nid(alg->algorithm) == ctx->desc->evp_type)
+ key = key_from_pkcs8(p8inf, PROV_OQS_LIBCTX_OF(ctx->provctx), NULL);
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+
+ return key;
+}
+
+OQSX_KEY *oqsx_d2i_PUBKEY(OQSX_KEY **a,
+ const unsigned char **pp, long length)
+{
+ OQSX_KEY *key = NULL;
+ // taken from internal code for d2i_PUBKEY_int:
+ X509_PUBKEY *xpk;
+
+ OQS_DEC_PRINTF2("OQS DEC provider: oqsx_d2i_PUBKEY called with length %ld\n", length);
+
+ // only way to re-create X509 object?? TBD
+ xpk = oqsx_d2i_X509_PUBKEY_INTERNAL(pp, length, NULL);
+
+ key = oqsx_key_from_x509pubkey(xpk, NULL, NULL);
+
+ if (key == NULL)
+ return NULL;
+
+ if (a != NULL) {
+ oqsx_key_free(*a);
+ *a = key;
+ }
+ return key;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+static OSSL_FUNC_decoder_freectx_fn der2key_freectx;
+static OSSL_FUNC_decoder_decode_fn oqs_der2key_decode;
+static OSSL_FUNC_decoder_export_object_fn der2key_export_object;
+
+static struct der2key_ctx_st *
+der2key_newctx(void *provctx, struct keytype_desc_st *desc, const char* tls_name)
+{
+ struct der2key_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+ OQS_DEC_PRINTF3("OQS DEC provider: der2key_newctx called with tls_name %s. Keytype: %d\n", tls_name, desc->evp_type);
+
+ if (ctx != NULL) {
+ ctx->provctx = provctx;
+ ctx->desc = desc;
+ if (desc->evp_type == 0) {
+ ctx->desc->evp_type = OBJ_sn2nid(tls_name);
+ OQS_DEC_PRINTF2("OQS DEC provider: der2key_newctx set evp_type to %d\n", ctx->desc->evp_type);
+ }
+ }
+ return ctx;
+}
+
+static void der2key_freectx(void *vctx)
+{
+ struct der2key_ctx_st *ctx = vctx;
+
+ OPENSSL_free(ctx);
+}
+
+static int der2key_check_selection(int selection,
+ const struct keytype_desc_st *desc)
+{
+ /*
+ * The selections are kinda sorta "levels", i.e. each selection given
+ * here is assumed to include those following.
+ */
+ int checks[] = {
+ OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
+ OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
+ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
+ };
+ size_t i;
+
+ OQS_DEC_PRINTF3("OQS DEC provider: der2key_check_selection called with selection %d (%d).\n", selection, desc->selection_mask);
+
+ /* The decoder implementations made here support guessing */
+ if (selection == 0)
+ return 1;
+
+ for (i = 0; i < OSSL_NELEM(checks); i++) {
+ int check1 = (selection & checks[i]) != 0;
+ int check2 = (desc->selection_mask & checks[i]) != 0;
+
+ /*
+ * If the caller asked for the currently checked bit(s), return
+ * whether the decoder description says it's supported.
+ */
+ OQS_DEC_PRINTF3("OQS DEC provider: der2key_check_selection returning %d (%d).\n", check1, check2);
+
+ if (check1)
+ return check2;
+ }
+
+ /* This should be dead code, but just to be safe... */
+ return 0;
+}
+
+static int oqs_der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection,
+ OSSL_CALLBACK *data_cb, void *data_cbarg,
+ OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
+{
+ struct der2key_ctx_st *ctx = vctx;
+ unsigned char *der = NULL;
+ const unsigned char *derp;
+ long der_len = 0;
+ void *key = NULL;
+ int ok = 0;
+
+ OQS_DEC_PRINTF("OQS DEC provider: oqs_der2key_decode called.\n");
+
+ ctx->selection = selection;
+ /*
+ * The caller is allowed to specify 0 as a selection mark, to have the
+ * structure and key type guessed. For type-specific structures, this
+ * is not recommended, as some structures are very similar.
+ * Note that 0 isn't the same as OSSL_KEYMGMT_SELECT_ALL, as the latter
+ * signifies a private key structure, where everything else is assumed
+ * to be present as well.
+ */
+ if (selection == 0)
+ selection = ctx->desc->selection_mask;
+ if ((selection & ctx->desc->selection_mask) == 0) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT);
+ return 0;
+ }
+
+ ok = oqs_read_der(ctx->provctx, cin, &der, &der_len);
+ if (!ok)
+ goto next;
+
+ ok = 0; /* Assume that we fail */
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ derp = der;
+ if (ctx->desc->d2i_PKCS8 != NULL) {
+ key = ctx->desc->d2i_PKCS8(NULL, &derp, der_len, ctx);
+ if (ctx->flag_fatal)
+ goto end;
+ } else if (ctx->desc->d2i_private_key != NULL) {
+ key = ctx->desc->d2i_private_key(NULL, &derp, der_len);
+ }
+ if (key == NULL && ctx->selection != 0)
+ goto next;
+ }
+ if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ derp = der;
+ if (ctx->desc->d2i_PUBKEY != NULL)
+ key = ctx->desc->d2i_PUBKEY(NULL, &derp, der_len);
+ else
+ key = ctx->desc->d2i_public_key(NULL, &derp, der_len);
+ if (key == NULL && ctx->selection != 0)
+ goto next;
+ }
+ if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) {
+ derp = der;
+ if (ctx->desc->d2i_key_params != NULL)
+ key = ctx->desc->d2i_key_params(NULL, &derp, der_len);
+ if (key == NULL && ctx->selection != 0)
+ goto next;
+ }
+
+ /*
+ * Last minute check to see if this was the correct type of key. This
+ * should never lead to a fatal error, i.e. the decoding itself was
+ * correct, it was just an unexpected key type. This is generally for
+ * classes of key types that have subtle variants, like RSA-PSS keys as
+ * opposed to plain RSA keys.
+ */
+ if (key != NULL
+ && ctx->desc->check_key != NULL
+ && !ctx->desc->check_key(key, ctx)) {
+ ctx->desc->free_key(key);
+ key = NULL;
+ }
+
+ if (key != NULL && ctx->desc->adjust_key != NULL)
+ ctx->desc->adjust_key(key, ctx);
+
+ next:
+ /*
+ * Indicated that we successfully decoded something, or not at all.
+ * Ending up "empty handed" is not an error.
+ */
+ ok = 1;
+
+ /*
+ * We free memory here so it's not held up during the callback, because
+ * we know the process is recursive and the allocated chunks of memory
+ * add up.
+ */
+ OPENSSL_free(der);
+ der = NULL;
+
+ if (key != NULL) {
+ OSSL_PARAM params[4];
+ int object_type = OSSL_OBJECT_PKEY;
+
+ params[0] =
+ OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type);
+ params[1] =
+ OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE,
+ (char *)ctx->desc->keytype_name,
+ 0);
+ /* The address of the key becomes the octet string */
+ params[2] =
+ OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE,
+ &key, sizeof(key));
+ params[3] = OSSL_PARAM_construct_end();
+
+ ok = data_cb(params, data_cbarg);
+ }
+
+ end:
+ ctx->desc->free_key(key);
+ OPENSSL_free(der);
+
+ return ok;
+}
+
+static int der2key_export_object(void *vctx,
+ const void *reference, size_t reference_sz,
+ OSSL_CALLBACK *export_cb, void *export_cbarg)
+{
+ struct der2key_ctx_st *ctx = vctx;
+ OSSL_FUNC_keymgmt_export_fn *export =
+ oqs_prov_get_keymgmt_export(ctx->desc->fns);
+ void *keydata;
+
+ OQS_DEC_PRINTF("OQS DEC provider: der2key_export_object called.\n");
+
+ if (reference_sz == sizeof(keydata) && export != NULL) {
+ /* The contents of the reference is the address to our object */
+ keydata = *(void **)reference;
+
+ return export(keydata, ctx->selection, export_cb, export_cbarg);
+ }
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void *oqsx_d2i_PKCS8(void **key, const unsigned char **der, long der_len,
+ struct der2key_ctx_st *ctx)
+{
+ OQS_DEC_PRINTF("OQS DEC provider: oqsx_d2i_PKCS8 called.\n");
+
+ return oqs_der2key_decode_p8(der, der_len, ctx,
+ (key_from_pkcs8_t *)oqsx_key_from_pkcs8);
+}
+
+static void oqsx_key_adjust(void *key, struct der2key_ctx_st *ctx)
+{
+ OQS_DEC_PRINTF("OQS DEC provider: oqsx_key_adjust called.\n");
+
+ oqsx_key_set0_libctx(key, PROV_OQS_LIBCTX_OF(ctx->provctx));
+}
+
+
+// OQS provider uses NIDs generated at load time as EVP_type identifiers
+// so initially this must be 0 and set to a real value by OBJ_sn2nid later
+
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * The DO_ macros help define the selection mask and the method functions
+ * for each kind of object we want to decode.
+ */
+#define DO_type_specific_keypair(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_KEYPAIR ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ oqsx_key_adjust, \
+ (free_key_fn *)oqsx_key_free
+
+#define DO_type_specific_pub(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_PUBLIC_KEY ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ oqsx_key_adjust, \
+ (free_key_fn *)oqsx_key_free
+
+#define DO_type_specific_priv(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ oqsx_key_adjust, \
+ (free_key_fn *)oqsx_key_free
+
+#define DO_type_specific_params(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_ALL_PARAMETERS ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ oqsx_key_adjust, \
+ (free_key_fn *)oqsx_key_free
+
+#define DO_type_specific(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_ALL ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ oqsx_key_adjust, \
+ (free_key_fn *)oqsx_key_free
+
+#define DO_type_specific_no_pub(keytype) \
+ "type-specific", 0, \
+ ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY \
+ | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ oqsx_key_adjust, \
+ (free_key_fn *)oqsx_key_free
+
+#define DO_PrivateKeyInfo(keytype) \
+ "PrivateKeyInfo", 0, \
+ ( OSSL_KEYMGMT_SELECT_PRIVATE_KEY ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ oqsx_d2i_PKCS8, \
+ NULL, \
+ NULL, \
+ oqsx_key_adjust, \
+ (free_key_fn *)oqsx_key_free
+
+#define DO_SubjectPublicKeyInfo(keytype) \
+ "SubjectPublicKeyInfo", 0, \
+ ( OSSL_KEYMGMT_SELECT_PUBLIC_KEY ), \
+ NULL, \
+ NULL, \
+ NULL, \
+ NULL, \
+ (d2i_of_void *)oqsx_d2i_PUBKEY, \
+ NULL, \
+ oqsx_key_adjust, \
+ (free_key_fn *)oqsx_key_free
+
+/*
+ * MAKE_DECODER is the single driver for creating OSSL_DISPATCH tables.
+ * It takes the following arguments:
+ *
+ * keytype_name The implementation key type as a string.
+ * keytype The implementation key type. This must correspond exactly
+ * to our existing keymgmt keytype names... in other words,
+ * there must exist an ossl_##keytype##_keymgmt_functions.
+ * type The type name for the set of functions that implement the
+ * decoder for the key type. This isn't necessarily the same
+ * as keytype. For example, the key types ed25519, ed448,
+ * x25519 and x448 are all handled by the same functions with
+ * the common type name ecx.
+ * kind The kind of support to implement. This translates into
+ * the DO_##kind macros above, to populate the keytype_desc_st
+ * structure.
+ */
+// reverted const to be able to change NID/evp_type after assignment
+#define MAKE_DECODER(keytype_name, keytype, type, kind) \
+ static struct keytype_desc_st kind##_##keytype##_desc = \
+ { keytype_name, oqs_##keytype##_keymgmt_functions, \
+ DO_##kind(keytype) }; \
+ \
+ static OSSL_FUNC_decoder_newctx_fn kind##_der2##keytype##_newctx; \
+ \
+ static void *kind##_der2##keytype##_newctx(void *provctx) \
+ { \
+ OQS_DEC_PRINTF("OQS DEC provider: _newctx called.\n"); \
+ return der2key_newctx(provctx, &kind##_##keytype##_desc, keytype_name ); \
+ } \
+ static int kind##_der2##keytype##_does_selection(void *provctx, \
+ int selection) \
+ { \
+ OQS_DEC_PRINTF("OQS DEC provider: _does_selection called.\n"); \
+ return der2key_check_selection(selection, \
+ &kind##_##keytype##_desc); \
+ } \
+ const OSSL_DISPATCH \
+ oqs_##kind##_der_to_##keytype##_decoder_functions[] = { \
+ { OSSL_FUNC_DECODER_NEWCTX, \
+ (void (*)(void))kind##_der2##keytype##_newctx }, \
+ { OSSL_FUNC_DECODER_FREECTX, \
+ (void (*)(void))der2key_freectx }, \
+ { OSSL_FUNC_DECODER_DOES_SELECTION, \
+ (void (*)(void))kind##_der2##keytype##_does_selection }, \
+ { OSSL_FUNC_DECODER_DECODE, \
+ (void (*)(void))oqs_der2key_decode }, \
+ { OSSL_FUNC_DECODER_EXPORT_OBJECT, \
+ (void (*)(void))der2key_export_object }, \
+ { 0, NULL } \
+ }
+
+///// OQS_TEMPLATE_FRAGMENT_DECODER_MAKE_START
+MAKE_DECODER("dilithium2", dilithium2, oqsx, PrivateKeyInfo);
+MAKE_DECODER("dilithium2", dilithium2, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("p256_dilithium2", p256_dilithium2, oqsx, PrivateKeyInfo);
+MAKE_DECODER("p256_dilithium2", p256_dilithium2, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("rsa3072_dilithium2", rsa3072_dilithium2, oqsx, PrivateKeyInfo);
+MAKE_DECODER("rsa3072_dilithium2", rsa3072_dilithium2, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("dilithium3", dilithium3, oqsx, PrivateKeyInfo);
+MAKE_DECODER("dilithium3", dilithium3, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("p384_dilithium3", p384_dilithium3, oqsx, PrivateKeyInfo);
+MAKE_DECODER("p384_dilithium3", p384_dilithium3, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("dilithium5", dilithium5, oqsx, PrivateKeyInfo);
+MAKE_DECODER("dilithium5", dilithium5, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("p521_dilithium5", p521_dilithium5, oqsx, PrivateKeyInfo);
+MAKE_DECODER("p521_dilithium5", p521_dilithium5, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("falcon512", falcon512, oqsx, PrivateKeyInfo);
+MAKE_DECODER("falcon512", falcon512, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("p256_falcon512", p256_falcon512, oqsx, PrivateKeyInfo);
+MAKE_DECODER("p256_falcon512", p256_falcon512, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("rsa3072_falcon512", rsa3072_falcon512, oqsx, PrivateKeyInfo);
+MAKE_DECODER("rsa3072_falcon512", rsa3072_falcon512, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("falcon1024", falcon1024, oqsx, PrivateKeyInfo);
+MAKE_DECODER("falcon1024", falcon1024, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("p521_falcon1024", p521_falcon1024, oqsx, PrivateKeyInfo);
+MAKE_DECODER("p521_falcon1024", p521_falcon1024, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("sphincssha2128fsimple", sphincssha2128fsimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("sphincssha2128fsimple", sphincssha2128fsimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("p256_sphincssha2128fsimple", p256_sphincssha2128fsimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("p256_sphincssha2128fsimple", p256_sphincssha2128fsimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("rsa3072_sphincssha2128fsimple", rsa3072_sphincssha2128fsimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("rsa3072_sphincssha2128fsimple", rsa3072_sphincssha2128fsimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("sphincssha2128ssimple", sphincssha2128ssimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("sphincssha2128ssimple", sphincssha2128ssimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("p256_sphincssha2128ssimple", p256_sphincssha2128ssimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("p256_sphincssha2128ssimple", p256_sphincssha2128ssimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("rsa3072_sphincssha2128ssimple", rsa3072_sphincssha2128ssimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("rsa3072_sphincssha2128ssimple", rsa3072_sphincssha2128ssimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("sphincssha2192fsimple", sphincssha2192fsimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("sphincssha2192fsimple", sphincssha2192fsimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("p384_sphincssha2192fsimple", p384_sphincssha2192fsimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("p384_sphincssha2192fsimple", p384_sphincssha2192fsimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("sphincsshake128fsimple", sphincsshake128fsimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("sphincsshake128fsimple", sphincsshake128fsimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("p256_sphincsshake128fsimple", p256_sphincsshake128fsimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("p256_sphincsshake128fsimple", p256_sphincsshake128fsimple, oqsx, SubjectPublicKeyInfo);
+MAKE_DECODER("rsa3072_sphincsshake128fsimple", rsa3072_sphincsshake128fsimple, oqsx, PrivateKeyInfo);
+MAKE_DECODER("rsa3072_sphincsshake128fsimple", rsa3072_sphincsshake128fsimple, oqsx, SubjectPublicKeyInfo);
+///// OQS_TEMPLATE_FRAGMENT_DECODER_MAKE_END
+
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider
+ *
+ * Code strongly inspired by OpenSSL endecoder.
+ *
+ * ToDo: Adding hybrid alg support
+ */
+
+#include <openssl/core.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/crypto.h>
+#include <openssl/params.h>
+#include <openssl/asn1.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs12.h> /* PKCS8_encrypt() */
+#include <openssl/proverr.h>
+#include <string.h>
+#include "oqs_endecoder_local.h"
+
+#ifdef NDEBUG
+#define OQS_ENC_PRINTF(a)
+#define OQS_ENC_PRINTF2(a, b)
+#define OQS_ENC_PRINTF3(a, b, c)
+#else
+#define OQS_ENC_PRINTF(a) if (getenv("OQSENC")) printf(a)
+#define OQS_ENC_PRINTF2(a, b) if (getenv("OQSENC")) printf(a, b)
+#define OQS_ENC_PRINTF3(a, b, c) if (getenv("OQSENC")) printf(a, b, c)
+#endif // NDEBUG
+
+struct key2any_ctx_st {
+ PROV_OQS_CTX *provctx;
+
+ /* Set to 0 if parameters should not be saved (dsa only) */
+ int save_parameters;
+
+ /* Set to 1 if intending to encrypt/decrypt, otherwise 0 */
+ int cipher_intent;
+
+ EVP_CIPHER *cipher;
+
+ OSSL_PASSPHRASE_CALLBACK *pwcb;
+ void *pwcbarg;
+};
+
+typedef int check_key_type_fn(const void *key, int nid);
+typedef int key_to_paramstring_fn(const void *key, int nid, int save,
+ void **str, int *strtype);
+typedef int key_to_der_fn(BIO *out, const void *key,
+ int key_nid, const char *pemname,
+ key_to_paramstring_fn *p2s, i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx);
+typedef int write_bio_of_void_fn(BIO *bp, const void *x);
+
+
+/* Free the blob allocated during key_to_paramstring_fn */
+static void free_asn1_data(int type, void *data)
+{
+ switch(type) {
+ case V_ASN1_OBJECT:
+ ASN1_OBJECT_free(data);
+ break;
+ case V_ASN1_SEQUENCE:
+ ASN1_STRING_free(data);
+ break;
+ }
+}
+
+static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid,
+ void *params, int params_type,
+ i2d_of_void *k2d)
+{
+ /* der, derlen store the key DER output and its length */
+ unsigned char *der = NULL;
+ int derlen;
+ /* The final PKCS#8 info */
+ PKCS8_PRIV_KEY_INFO *p8info = NULL;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_p8info called\n");
+
+ if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL
+ || (derlen = k2d(key, &der)) <= 0
+ || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(key_nid), 0,
+ // doesn't work with oqs-openssl:
+ // params_type, params,
+ // does work/interop:
+ V_ASN1_UNDEF, NULL,
+ der, derlen)) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ PKCS8_PRIV_KEY_INFO_free(p8info);
+ OPENSSL_free(der);
+ p8info = NULL;
+ }
+
+ return p8info;
+}
+
+static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info,
+ struct key2any_ctx_st *ctx)
+{
+ X509_SIG *p8 = NULL;
+ char kstr[PEM_BUFSIZE];
+ size_t klen = 0;
+ OSSL_LIB_CTX *libctx = PROV_OQS_LIBCTX_OF(ctx->provctx);
+
+ OQS_ENC_PRINTF("OQS ENC provider: p8info_to_encp8 called\n");
+
+ if (ctx->cipher == NULL || ctx->pwcb == NULL)
+ return NULL;
+
+ if (!ctx->pwcb(kstr, PEM_BUFSIZE, &klen, NULL, ctx->pwcbarg)) {
+ ERR_raise(ERR_LIB_USER, PROV_R_UNABLE_TO_GET_PASSPHRASE);
+ return NULL;
+ }
+ /* First argument == -1 means "standard" */
+ p8 = PKCS8_encrypt_ex(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info, libctx, NULL);
+ OPENSSL_cleanse(kstr, klen);
+ return p8;
+}
+
+static X509_SIG *key_to_encp8(const void *key, int key_nid,
+ void *params, int params_type,
+ i2d_of_void *k2d, struct key2any_ctx_st *ctx)
+{
+ PKCS8_PRIV_KEY_INFO *p8info =
+ key_to_p8info(key, key_nid, params, params_type, k2d);
+ X509_SIG *p8 = NULL;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_encp8 called\n");
+
+ if (p8info == NULL) {
+ free_asn1_data(params_type, params);
+ } else {
+ p8 = p8info_to_encp8(p8info, ctx);
+ PKCS8_PRIV_KEY_INFO_free(p8info);
+ }
+ return p8;
+}
+
+static X509_PUBKEY *oqsx_key_to_pubkey(const void *key, int key_nid,
+ void *params, int params_type,
+ i2d_of_void k2d)
+{
+ /* der, derlen store the key DER output and its length */
+ unsigned char *der = NULL;
+ int derlen;
+ /* The final X509_PUBKEY */
+ X509_PUBKEY *xpk = NULL;
+
+ OQS_ENC_PRINTF2("OQS ENC provider: oqsx_key_to_pubkey called for NID %d\n", key_nid);
+
+ if ((xpk = X509_PUBKEY_new()) == NULL
+ || (derlen = k2d(key, &der)) <= 0
+ || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(key_nid),
+ V_ASN1_UNDEF, NULL, // as per logic in oqs_meth.c in oqs-openssl
+ der, derlen)) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ X509_PUBKEY_free(xpk);
+ OPENSSL_free(der);
+ xpk = NULL;
+ }
+
+ return xpk;
+}
+
+/*
+ * key_to_epki_* produce encoded output with the private key data in a
+ * EncryptedPrivateKeyInfo structure (defined by PKCS#8). They require
+ * that there's an intent to encrypt, anything else is an error.
+ *
+ * key_to_pki_* primarly produce encoded output with the private key data
+ * in a PrivateKeyInfo structure (also defined by PKCS#8). However, if
+ * there is an intent to encrypt the data, the corresponding key_to_epki_*
+ * function is used instead.
+ *
+ * key_to_spki_* produce encoded output with the public key data in an
+ * X.509 SubjectPublicKeyInfo.
+ *
+ * Key parameters don't have any defined envelopment of this kind, but are
+ * included in some manner in the output from the functions described above,
+ * either in the AlgorithmIdentifier's parameter field, or as part of the
+ * key data itself.
+ */
+
+static int key_to_epki_der_priv_bio(BIO *out, const void *key,
+ int key_nid,
+ ossl_unused const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ int ret = 0;
+ void *str = NULL;
+ int strtype = V_ASN1_UNDEF;
+ X509_SIG *p8;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_epki_der_priv_bio called\n");
+
+ if (!ctx->cipher_intent)
+ return 0;
+
+ if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
+ &str, &strtype))
+ return 0;
+
+ p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
+ if (p8 != NULL)
+ ret = i2d_PKCS8_bio(out, p8);
+
+ X509_SIG_free(p8);
+
+ return ret;
+}
+
+static int key_to_epki_pem_priv_bio(BIO *out, const void *key,
+ int key_nid,
+ ossl_unused const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ int ret = 0;
+ void *str = NULL;
+ int strtype = V_ASN1_UNDEF;
+ X509_SIG *p8;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_epki_pem_priv_bio called\n");
+
+ if (!ctx->cipher_intent)
+ return 0;
+
+ if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
+ &str, &strtype))
+ return 0;
+
+ p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
+ if (p8 != NULL)
+ ret = PEM_write_bio_PKCS8(out, p8);
+
+ X509_SIG_free(p8);
+
+ return ret;
+}
+
+static int key_to_pki_der_priv_bio(BIO *out, const void *key,
+ int key_nid,
+ ossl_unused const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ int ret = 0;
+ void *str = NULL;
+ int strtype = V_ASN1_UNDEF;
+ PKCS8_PRIV_KEY_INFO *p8info;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_pki_der_priv_bio called\n");
+
+ if (ctx->cipher_intent)
+ return key_to_epki_der_priv_bio(out, key, key_nid, pemname,
+ p2s, k2d, ctx);
+
+ if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
+ &str, &strtype))
+ return 0;
+
+ p8info = key_to_p8info(key, key_nid, str, strtype, k2d);
+
+ if (p8info != NULL)
+ ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info);
+ else
+ free_asn1_data(strtype, str);
+
+ PKCS8_PRIV_KEY_INFO_free(p8info);
+
+ return ret;
+}
+
+static int key_to_pki_pem_priv_bio(BIO *out, const void *key,
+ int key_nid,
+ ossl_unused const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ int ret = 0;
+ void *str = NULL;
+ int strtype = V_ASN1_UNDEF;
+ PKCS8_PRIV_KEY_INFO *p8info;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_pki_pem_priv_bio called\n");
+
+ if (ctx->cipher_intent)
+ return key_to_epki_pem_priv_bio(out, key, key_nid, pemname,
+ p2s, k2d, ctx);
+
+ if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
+ &str, &strtype))
+ return 0;
+
+ p8info = key_to_p8info(key, key_nid, str, strtype, k2d);
+
+ if (p8info != NULL)
+ ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info);
+ else
+ free_asn1_data(strtype, str);
+
+ PKCS8_PRIV_KEY_INFO_free(p8info);
+
+ return ret;
+}
+
+static int key_to_spki_der_pub_bio(BIO *out, const void *key,
+ int key_nid,
+ ossl_unused const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ int ret = 0;
+ OQSX_KEY* okey = (OQSX_KEY*)key;
+ X509_PUBKEY *xpk = NULL;
+ void *str = NULL;
+ int strtype = V_ASN1_UNDEF;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_spki_der_pub_bio called\n");
+
+ if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
+ &str, &strtype))
+ return 0;
+
+ xpk = oqsx_key_to_pubkey(key, key_nid, str, strtype, k2d);
+
+ if (xpk != NULL)
+ ret = i2d_X509_PUBKEY_bio(out, xpk);
+
+ X509_PUBKEY_free(xpk);
+ return ret;
+}
+
+static int key_to_spki_pem_pub_bio(BIO *out, const void *key,
+ int key_nid,
+ ossl_unused const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ int ret = 0;
+ X509_PUBKEY *xpk = NULL;
+ void *str = NULL;
+ int strtype = V_ASN1_UNDEF;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_spki_pem_pub_bio called\n");
+
+ if (p2s != NULL && !p2s(key, key_nid, ctx->save_parameters,
+ &str, &strtype))
+ return 0;
+
+ xpk = oqsx_key_to_pubkey(key, key_nid, str, strtype, k2d);
+
+ if (xpk != NULL)
+ ret = PEM_write_bio_X509_PUBKEY(out, xpk);
+ else
+ free_asn1_data(strtype, str);
+
+ /* Also frees |str| */
+ X509_PUBKEY_free(xpk);
+ return ret;
+}
+
+/*
+ * key_to_type_specific_* produce encoded output with type specific key data,
+ * no envelopment; the same kind of output as the type specific i2d_ and
+ * PEM_write_ functions, which is often a simple SEQUENCE of INTEGER.
+ *
+ * OpenSSL tries to discourage production of new keys in this form, because
+ * of the ambiguity when trying to recognise them, but can't deny that PKCS#1
+ * et al still are live standards.
+ *
+ * Note that these functions completely ignore p2s, and rather rely entirely
+ * on k2d to do the complete work.
+ */
+/*
+static int key_to_type_specific_der_bio(BIO *out, const void *key,
+ int key_nid,
+ ossl_unused const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ unsigned char *der = NULL;
+ int derlen;
+ int ret;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_type_specific_der_bio called\n");
+
+ if ((derlen = k2d(key, &der)) <= 0) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ ret = BIO_write(out, der, derlen);
+ OPENSSL_free(der);
+ return ret > 0;
+}
+#define key_to_type_specific_der_priv_bio key_to_type_specific_der_bio
+#define key_to_type_specific_der_pub_bio key_to_type_specific_der_bio
+#define key_to_type_specific_der_param_bio key_to_type_specific_der_bio
+
+static int key_to_type_specific_pem_bio_cb(BIO *out, const void *key,
+ int key_nid, const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_type_specific_pem_bio_cb called \n");
+
+ return PEM_ASN1_write_bio(k2d, pemname, out, key, ctx->cipher,
+ NULL, 0, ctx->pwcb, ctx->pwcbarg) > 0;
+}
+
+static int key_to_type_specific_pem_priv_bio(BIO *out, const void *key,
+ int key_nid, const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_type_specific_pem_priv_bio called\n");
+
+ return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname,
+ p2s, k2d, ctx, ctx->pwcb, ctx->pwcbarg);
+
+}
+
+static int key_to_type_specific_pem_pub_bio(BIO *out, const void *key,
+ int key_nid, const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_type_specific_pem_pub_bio called\n");
+
+ return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname,
+ p2s, k2d, ctx, NULL, NULL);
+}
+
+#ifndef OPENSSL_NO_KEYPARAMS
+static int key_to_type_specific_pem_param_bio(BIO *out, const void *key,
+ int key_nid, const char *pemname,
+ key_to_paramstring_fn *p2s,
+ i2d_of_void *k2d,
+ struct key2any_ctx_st *ctx)
+{
+ OQS_ENC_PRINTF("OQS ENC provider: key_to_type_specific_pem_param_bio called\n");
+
+ return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname,
+ p2s, k2d, ctx, NULL, NULL);
+}
+#endif
+*/
+/* ---------------------------------------------------------------------- */
+
+static int prepare_oqsx_params(const void *oqsxkey, int nid, int save,
+ void **pstr, int *pstrtype)
+{
+ ASN1_OBJECT *params = NULL;
+ OQSX_KEY *k = (OQSX_KEY*)oqsxkey;
+
+ OQS_ENC_PRINTF3("OQS ENC provider: prepare_oqsx_params called with nid %d (tlsname: %s)\n", nid, k->tls_name);
+
+ if (k->tls_name && OBJ_sn2nid(k->tls_name) != nid) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_KEY);
+ return 0;
+ }
+
+ if (nid != NID_undef) {
+ params = OBJ_nid2obj(nid);
+ if (params == NULL)
+ return 0;
+ }
+ else {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_MISSING_OID);
+ return 0;
+ }
+
+
+ if (OBJ_length(params) == 0) {
+ /* unexpected error */
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_MISSING_OID);
+ ASN1_OBJECT_free(params);
+ return 0;
+ }
+ *pstr = params;
+ *pstrtype = V_ASN1_OBJECT;
+ return 1;
+}
+
+
+static int oqsx_spki_pub_to_der(const void *vxkey, unsigned char **pder)
+{
+ const OQSX_KEY *oqsxkey = vxkey;
+ unsigned char *keyblob;
+ int ret = 0;
+
+ OQS_ENC_PRINTF("OQS ENC provider: oqsx_spki_pub_to_der called\n");
+
+ if (oqsxkey == NULL || oqsxkey->pubkey == NULL) {
+ ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+#ifdef USE_ENCODING_LIB
+ if (oqsxkey->oqsx_encoding_ctx.encoding_ctx != NULL && oqsxkey->oqsx_encoding_ctx.encoding_impl != NULL) {
+ unsigned char *buf;
+ int buflen;
+ int ret = 0;
+ const OQSX_ENCODING_CTX* encoding_ctx = &oqsxkey->oqsx_encoding_ctx;
+ buflen = encoding_ctx->encoding_impl->crypto_publickeybytes;
+
+ buf = OPENSSL_secure_zalloc(buflen);
+ ret = qsc_encode(encoding_ctx->encoding_ctx, encoding_ctx->encoding_impl, oqsxkey->pubkey, &buf, 0, 0, 1);
+ if (ret != QSC_ENC_OK) return -1;
+
+ *pder = buf;
+ return buflen;
+ } else {
+#endif
+ keyblob = OPENSSL_memdup(oqsxkey->pubkey, oqsxkey->pubkeylen);
+ if (keyblob == NULL) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ *pder = keyblob;
+ return oqsxkey->pubkeylen;
+#ifdef USE_ENCODING_LIB
+ }
+#endif
+}
+
+static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder)
+{
+ OQSX_KEY *oqsxkey = (OQSX_KEY *)vxkey;
+ unsigned char* buf = NULL;
+ int buflen = 0, privkeylen;
+ ASN1_OCTET_STRING oct;
+ int keybloblen;
+
+ OQS_ENC_PRINTF("OQS ENC provider: oqsx_pki_priv_to_der called\n");
+
+ // Encoding private _and_ public key concatenated ... seems unlogical and unnecessary,
+ // but is what oqs-openssl does, so we repeat it for interop... also from a security
+ // perspective not really smart to copy key material (side channel attacks, anyone?),
+ // but so be it for now (TBC).
+ if (oqsxkey == NULL || oqsxkey->privkey == NULL
+#ifndef NOPUBKEY_IN_PRIVKEY
+ || oqsxkey->pubkey == NULL
+#endif
+ ) {
+ ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ // only concatenate private classic key (if any) and OQS private and public key
+ // NOT saving public classic key component (if any)
+ privkeylen = oqsxkey->privkeylen;
+ if (oqsxkey->numkeys > 1) { // hybrid
+ int actualprivkeylen;
+ DECODE_UINT32(actualprivkeylen, oqsxkey->privkey);
+ if (actualprivkeylen > oqsxkey->evp_info->length_private_key) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ return 0;
+ }
+ privkeylen -= (oqsxkey->evp_info->length_private_key - actualprivkeylen);
+ }
+#ifdef USE_ENCODING_LIB
+ if (oqsxkey->oqsx_encoding_ctx.encoding_ctx != NULL && oqsxkey->oqsx_encoding_ctx.encoding_impl != NULL) {
+ const OQSX_ENCODING_CTX* encoding_ctx = &oqsxkey->oqsx_encoding_ctx;
+ int ret = 0;
+#ifdef NOPUBKEY_IN_PRIVKEY
+ int withoptional = (encoding_ctx->encoding_ctx->raw_private_key_encodes_public_key ? 1 : 0);
+#else
+ int withoptional = 1;
+#endif
+ buflen = (withoptional ? encoding_ctx->encoding_impl->crypto_secretkeybytes :
+ encoding_ctx->encoding_impl->crypto_secretkeybytes_nooptional);
+ buf = OPENSSL_secure_zalloc(buflen);
+
+ ret = qsc_encode(encoding_ctx->encoding_ctx, encoding_ctx->encoding_impl,
+ oqsxkey->comp_pubkey[oqsxkey->numkeys-1], 0,
+ oqsxkey->privkey, &buf, withoptional);
+ if (ret != QSC_ENC_OK) return -1;
+ } else {
+#endif
+#ifdef NOPUBKEY_IN_PRIVKEY
+ buflen = privkeylen;
+ buf = OPENSSL_secure_malloc(buflen);
+ OQS_ENC_PRINTF2("OQS ENC provider: saving privkey of length %d\n", buflen);
+ memcpy(buf, oqsxkey->privkey, privkeylen);
+#else
+ buflen = privkeylen+oqsx_key_get_oqs_public_key_len(oqsxkey);
+ buf = OPENSSL_secure_malloc(buflen);
+ OQS_ENC_PRINTF2("OQS ENC provider: saving priv+pubkey of length %d\n", buflen);
+ memcpy(buf, oqsxkey->privkey, privkeylen);
+ memcpy(buf+privkeylen, oqsxkey->comp_pubkey[oqsxkey->numkeys-1], oqsx_key_get_oqs_public_key_len(oqsxkey));
+#endif
+#ifdef USE_ENCODING_LIB
+ }
+#endif
+
+ oct.data = buf;
+ oct.length = buflen;
+ // more logical:
+ //oct.data = oqsxkey->privkey;
+ //oct.length = oqsxkey->privkeylen;
+ oct.flags = 0;
+
+ keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder);
+ if (keybloblen < 0) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ keybloblen = 0; // signal error
+ }
+
+ OPENSSL_secure_clear_free(buf, buflen);
+ return keybloblen;
+}
+
+# define oqsx_epki_priv_to_der oqsx_pki_priv_to_der
+
+/*
+ * OQSX only has PKCS#8 / SubjectPublicKeyInfo
+ * representation, so we don't define oqsx_type_specific_[priv,pub,params]_to_der.
+ */
+
+# define oqsx_check_key_type NULL
+
+// OQS provider uses NIDs generated at load time as EVP_type identifiers
+// so initially this must be 0 and set to a real value by OBJ_sn2nid later
+///// OQS_TEMPLATE_FRAGMENT_ENCODER_DEFINES_START
+# define dilithium2_evp_type 0
+# define dilithium2_input_type "dilithium2"
+# define dilithium2_pem_type "dilithium2"
+# define p256_dilithium2_evp_type 0
+# define p256_dilithium2_input_type "p256_dilithium2"
+# define p256_dilithium2_pem_type "p256_dilithium2"
+# define rsa3072_dilithium2_evp_type 0
+# define rsa3072_dilithium2_input_type "rsa3072_dilithium2"
+# define rsa3072_dilithium2_pem_type "rsa3072_dilithium2"
+# define dilithium3_evp_type 0
+# define dilithium3_input_type "dilithium3"
+# define dilithium3_pem_type "dilithium3"
+# define p384_dilithium3_evp_type 0
+# define p384_dilithium3_input_type "p384_dilithium3"
+# define p384_dilithium3_pem_type "p384_dilithium3"
+# define dilithium5_evp_type 0
+# define dilithium5_input_type "dilithium5"
+# define dilithium5_pem_type "dilithium5"
+# define p521_dilithium5_evp_type 0
+# define p521_dilithium5_input_type "p521_dilithium5"
+# define p521_dilithium5_pem_type "p521_dilithium5"
+# define falcon512_evp_type 0
+# define falcon512_input_type "falcon512"
+# define falcon512_pem_type "falcon512"
+# define p256_falcon512_evp_type 0
+# define p256_falcon512_input_type "p256_falcon512"
+# define p256_falcon512_pem_type "p256_falcon512"
+# define rsa3072_falcon512_evp_type 0
+# define rsa3072_falcon512_input_type "rsa3072_falcon512"
+# define rsa3072_falcon512_pem_type "rsa3072_falcon512"
+# define falcon1024_evp_type 0
+# define falcon1024_input_type "falcon1024"
+# define falcon1024_pem_type "falcon1024"
+# define p521_falcon1024_evp_type 0
+# define p521_falcon1024_input_type "p521_falcon1024"
+# define p521_falcon1024_pem_type "p521_falcon1024"
+# define sphincssha2128fsimple_evp_type 0
+# define sphincssha2128fsimple_input_type "sphincssha2128fsimple"
+# define sphincssha2128fsimple_pem_type "sphincssha2128fsimple"
+# define p256_sphincssha2128fsimple_evp_type 0
+# define p256_sphincssha2128fsimple_input_type "p256_sphincssha2128fsimple"
+# define p256_sphincssha2128fsimple_pem_type "p256_sphincssha2128fsimple"
+# define rsa3072_sphincssha2128fsimple_evp_type 0
+# define rsa3072_sphincssha2128fsimple_input_type "rsa3072_sphincssha2128fsimple"
+# define rsa3072_sphincssha2128fsimple_pem_type "rsa3072_sphincssha2128fsimple"
+# define sphincssha2128ssimple_evp_type 0
+# define sphincssha2128ssimple_input_type "sphincssha2128ssimple"
+# define sphincssha2128ssimple_pem_type "sphincssha2128ssimple"
+# define p256_sphincssha2128ssimple_evp_type 0
+# define p256_sphincssha2128ssimple_input_type "p256_sphincssha2128ssimple"
+# define p256_sphincssha2128ssimple_pem_type "p256_sphincssha2128ssimple"
+# define rsa3072_sphincssha2128ssimple_evp_type 0
+# define rsa3072_sphincssha2128ssimple_input_type "rsa3072_sphincssha2128ssimple"
+# define rsa3072_sphincssha2128ssimple_pem_type "rsa3072_sphincssha2128ssimple"
+# define sphincssha2192fsimple_evp_type 0
+# define sphincssha2192fsimple_input_type "sphincssha2192fsimple"
+# define sphincssha2192fsimple_pem_type "sphincssha2192fsimple"
+# define p384_sphincssha2192fsimple_evp_type 0
+# define p384_sphincssha2192fsimple_input_type "p384_sphincssha2192fsimple"
+# define p384_sphincssha2192fsimple_pem_type "p384_sphincssha2192fsimple"
+# define sphincsshake128fsimple_evp_type 0
+# define sphincsshake128fsimple_input_type "sphincsshake128fsimple"
+# define sphincsshake128fsimple_pem_type "sphincsshake128fsimple"
+# define p256_sphincsshake128fsimple_evp_type 0
+# define p256_sphincsshake128fsimple_input_type "p256_sphincsshake128fsimple"
+# define p256_sphincsshake128fsimple_pem_type "p256_sphincsshake128fsimple"
+# define rsa3072_sphincsshake128fsimple_evp_type 0
+# define rsa3072_sphincsshake128fsimple_input_type "rsa3072_sphincsshake128fsimple"
+# define rsa3072_sphincsshake128fsimple_pem_type "rsa3072_sphincsshake128fsimple"
+///// OQS_TEMPLATE_FRAGMENT_ENCODER_DEFINES_END
+
+/* ---------------------------------------------------------------------- */
+
+static OSSL_FUNC_decoder_newctx_fn key2any_newctx;
+static OSSL_FUNC_decoder_freectx_fn key2any_freectx;
+
+static void *key2any_newctx(void *provctx)
+{
+ struct key2any_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+ OQS_ENC_PRINTF("OQS ENC provider: key2any_newctx called\n");
+
+ if (ctx != NULL) {
+ ctx->provctx = provctx;
+ ctx->save_parameters = 1;
+ }
+
+ return ctx;
+}
+
+static void key2any_freectx(void *vctx)
+{
+ struct key2any_ctx_st *ctx = vctx;
+
+ OQS_ENC_PRINTF("OQS ENC provider: key2any_freectx called\n");
+
+ EVP_CIPHER_free(ctx->cipher);
+ OPENSSL_free(ctx);
+}
+
+static const OSSL_PARAM *key2any_settable_ctx_params(ossl_unused void *provctx)
+{
+ static const OSSL_PARAM settables[] = {
+ OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, NULL, 0),
+ OSSL_PARAM_END,
+ };
+
+ OQS_ENC_PRINTF("OQS ENC provider: key2any_settable_ctx_params called\n");
+
+ return settables;
+}
+
+static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+ struct key2any_ctx_st *ctx = vctx;
+ OSSL_LIB_CTX *libctx = ctx->provctx->libctx;
+ const OSSL_PARAM *cipherp =
+ OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER);
+ const OSSL_PARAM *propsp =
+ OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
+ const OSSL_PARAM *save_paramsp =
+ OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_SAVE_PARAMETERS);
+
+ OQS_ENC_PRINTF("OQS ENC provider: key2any_set_ctx_params called\n");
+
+ if (cipherp != NULL) {
+ const char *ciphername = NULL;
+ const char *props = NULL;
+
+ if (!OSSL_PARAM_get_utf8_string_ptr(cipherp, &ciphername))
+ return 0;
+ OQS_ENC_PRINTF2(" setting cipher: %s\n", ciphername);
+ if (propsp != NULL && !OSSL_PARAM_get_utf8_string_ptr(propsp, &props))
+ return 0;
+
+ EVP_CIPHER_free(ctx->cipher);
+ ctx->cipher = NULL;
+ ctx->cipher_intent = ciphername != NULL;
+ if (ciphername != NULL
+ && ((ctx->cipher =
+ EVP_CIPHER_fetch(libctx, ciphername, props)) == NULL)) {
+ return 0;
+ }
+ }
+
+ if (save_paramsp != NULL) {
+ if (!OSSL_PARAM_get_int(save_paramsp, &ctx->save_parameters)) {
+ return 0;
+ }
+ }
+ OQS_ENC_PRINTF2(" cipher set to %p: \n", ctx->cipher);
+ return 1;
+}
+
+static int key2any_check_selection(int selection, int selection_mask)
+{
+ /*
+ * The selections are kinda sorta "levels", i.e. each selection given
+ * here is assumed to include those following.
+ */
+ int checks[] = {
+ OSSL_KEYMGMT_SELECT_PRIVATE_KEY,
+ OSSL_KEYMGMT_SELECT_PUBLIC_KEY,
+ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
+ };
+ size_t i;
+
+ OQS_ENC_PRINTF3("OQS ENC provider: key2any_check_selection called with selection %d (%d)\n",selection, selection_mask);
+
+ /* The decoder implementations made here support guessing */
+ if (selection == 0)
+ return 1;
+
+ for (i = 0; i < OSSL_NELEM(checks); i++) {
+ int check1 = (selection & checks[i]) != 0;
+ int check2 = (selection_mask & checks[i]) != 0;
+
+ /*
+ * If the caller asked for the currently checked bit(s), return
+ * whether the decoder description says it's supported.
+ */
+ if (check1) {
+ OQS_ENC_PRINTF2("OQS ENC provider: key2any_check_selection returns %d\n", check2);
+ return check2;
+ }
+ }
+
+ /* This should be dead code, but just to be safe... */
+ return 0;
+}
+
+static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout,
+ const void *key, const char* typestr, const char *pemname,
+ key_to_der_fn *writer,
+ OSSL_PASSPHRASE_CALLBACK *pwcb, void *pwcbarg,
+ key_to_paramstring_fn *key2paramstring,
+ i2d_of_void *key2der)
+{
+ int ret = 0;
+ int type = OBJ_sn2nid(typestr);
+ OQSX_KEY *oqsk = (OQSX_KEY*)key;
+
+ OQS_ENC_PRINTF3("OQS ENC provider: key2any_encode called with type %d (%s)\n", type, typestr);
+ OQS_ENC_PRINTF2("OQS ENC provider: key2any_encode called with pemname %s\n", pemname);
+
+ if (key == NULL || type <= 0) {
+ ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER);
+ } else if (writer != NULL) {
+ // Is ref counting really needed? For now, do it as per https://beta.openssl.org/docs/manmaster/man3/BIO_new_from_core_bio.html:
+ BIO *out = oqs_bio_new_from_core_bio(ctx->provctx, cout);
+
+ if (out != NULL) {
+ ctx->pwcb = pwcb;
+ ctx->pwcbarg = pwcbarg;
+
+ ret = writer(out, key, type, pemname, key2paramstring, key2der, ctx);
+ }
+
+ BIO_free(out);
+ } else {
+ ERR_raise(ERR_LIB_USER, ERR_R_PASSED_INVALID_ARGUMENT);
+ }
+ OQS_ENC_PRINTF2(" encode result: %d\n", ret);
+ return ret;
+}
+
+#define DO_PRIVATE_KEY_selection_mask OSSL_KEYMGMT_SELECT_PRIVATE_KEY
+#define DO_PRIVATE_KEY(impl, type, kind, output) \
+ if ((selection & DO_PRIVATE_KEY_selection_mask) != 0) \
+ return key2any_encode(ctx, cout, key, impl##_pem_type, \
+ impl##_pem_type " PRIVATE KEY", \
+ key_to_##kind##_##output##_priv_bio, \
+ cb, cbarg, prepare_##type##_params, \
+ type##_##kind##_priv_to_der);
+
+#define DO_PUBLIC_KEY_selection_mask OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+#define DO_PUBLIC_KEY(impl, type, kind, output) \
+ if ((selection & DO_PUBLIC_KEY_selection_mask) != 0) \
+ return key2any_encode(ctx, cout, key, impl##_pem_type, \
+ impl##_pem_type " PUBLIC KEY", \
+ key_to_##kind##_##output##_pub_bio, \
+ cb, cbarg, prepare_##type##_params, \
+ type##_##kind##_pub_to_der);
+
+#define DO_PARAMETERS_selection_mask OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
+#define DO_PARAMETERS(impl, type, kind, output) \
+ if ((selection & DO_PARAMETERS_selection_mask) != 0) \
+ return key2any_encode(ctx, cout, key, impl##_pem_type, \
+ impl##_pem_type " PARAMETERS", \
+ key_to_##kind##_##output##_param_bio, \
+ NULL, NULL, NULL, \
+ type##_##kind##_params_to_der);
+
+/*-
+ * Implement the kinds of output structure that can be produced. They are
+ * referred to by name, and for each name, the following macros are defined
+ * (braces not included):
+ *
+ * DO_{kind}_selection_mask
+ *
+ * A mask of selection bits that must not be zero. This is used as a
+ * selection criterion for each implementation.
+ * This mask must never be zero.
+ *
+ * DO_{kind}
+ *
+ * The performing macro. It must use the DO_ macros defined above,
+ * always in this order:
+ *
+ * - DO_PRIVATE_KEY
+ * - DO_PUBLIC_KEY
+ * - DO_PARAMETERS
+ *
+ * Any of those may be omitted, but the relative order must still be
+ * the same.
+ */
+
+/*
+ * PKCS#8 defines two structures for private keys only:
+ * - PrivateKeyInfo (raw unencrypted form)
+ * - EncryptedPrivateKeyInfo (encrypted wrapping)
+ *
+ * To allow a certain amount of flexibility, we allow the routines
+ * for PrivateKeyInfo to also produce EncryptedPrivateKeyInfo if a
+ * passphrase callback has been passed to them.
+ */
+#define DO_PrivateKeyInfo_selection_mask DO_PRIVATE_KEY_selection_mask
+#define DO_PrivateKeyInfo(impl, type, output) \
+ DO_PRIVATE_KEY(impl, type, pki, output)
+
+#define DO_EncryptedPrivateKeyInfo_selection_mask DO_PRIVATE_KEY_selection_mask
+#define DO_EncryptedPrivateKeyInfo(impl, type, output) \
+ DO_PRIVATE_KEY(impl, type, epki, output)
+
+/* SubjectPublicKeyInfo is a structure for public keys only */
+#define DO_SubjectPublicKeyInfo_selection_mask DO_PUBLIC_KEY_selection_mask
+#define DO_SubjectPublicKeyInfo(impl, type, output) \
+ DO_PUBLIC_KEY(impl, type, spki, output)
+
+/*
+ * "type-specific" is a uniform name for key type specific output for private
+ * and public keys as well as key parameters. This is used internally in
+ * libcrypto so it doesn't have to have special knowledge about select key
+ * types, but also when no better name has been found. If there are more
+ * expressive DO_ names above, those are preferred.
+ *
+ * Three forms exist:
+ *
+ * - type_specific_keypair Only supports private and public key
+ * - type_specific_params Only supports parameters
+ * - type_specific Supports all parts of an EVP_PKEY
+ * - type_specific_no_pub Supports all parts of an EVP_PKEY
+ * except public key
+ */
+#define DO_type_specific_params_selection_mask DO_PARAMETERS_selection_mask
+#define DO_type_specific_params(impl, type, output) \
+ DO_PARAMETERS(impl, type, type_specific, output)
+#define DO_type_specific_keypair_selection_mask \
+ ( DO_PRIVATE_KEY_selection_mask | DO_PUBLIC_KEY_selection_mask )
+#define DO_type_specific_keypair(impl, type, output) \
+ DO_PRIVATE_KEY(impl, type, type_specific, output) \
+ DO_PUBLIC_KEY(impl, type, type_specific, output)
+#define DO_type_specific_selection_mask \
+ ( DO_type_specific_keypair_selection_mask \
+ | DO_type_specific_params_selection_mask )
+#define DO_type_specific(impl, type, output) \
+ DO_type_specific_keypair(impl, type, output) \
+ DO_type_specific_params(impl, type, output)
+#define DO_type_specific_no_pub_selection_mask \
+ ( DO_PRIVATE_KEY_selection_mask | DO_PARAMETERS_selection_mask)
+#define DO_type_specific_no_pub(impl, type, output) \
+ DO_PRIVATE_KEY(impl, type, type_specific, output) \
+ DO_type_specific_params(impl, type, output)
+
+/*
+ * MAKE_ENCODER is the single driver for creating OSSL_DISPATCH tables.
+ * It takes the following arguments:
+ *
+ * impl This is the key type name that's being implemented.
+ * type This is the type name for the set of functions that implement
+ * the key type. For example, ed25519, ed448, x25519 and x448
+ * are all implemented with the exact same set of functions.
+ * kind What kind of support to implement. These translate into
+ * the DO_##kind macros above.
+ * output The output type to implement. may be der or pem.
+ *
+ * The resulting OSSL_DISPATCH array gets the following name (expressed in
+ * C preprocessor terms) from those arguments:
+ *
+ * oqs_##impl##_to_##kind##_##output##_encoder_functions
+ */
+#define MAKE_ENCODER(impl, type, kind, output) \
+ static OSSL_FUNC_encoder_import_object_fn \
+ impl##_to_##kind##_##output##_import_object; \
+ static OSSL_FUNC_encoder_free_object_fn \
+ impl##_to_##kind##_##output##_free_object; \
+ static OSSL_FUNC_encoder_encode_fn \
+ impl##_to_##kind##_##output##_encode; \
+ \
+ static void * \
+ impl##_to_##kind##_##output##_import_object(void *vctx, int selection, \
+ const OSSL_PARAM params[]) \
+ { \
+ struct key2any_ctx_st *ctx = vctx; \
+ \
+ OQS_ENC_PRINTF("OQS ENC provider: _import_object called\n"); \
+ return oqs_prov_import_key(oqs_##impl##_keymgmt_functions, \
+ ctx->provctx, selection, params); \
+ } \
+ static void impl##_to_##kind##_##output##_free_object(void *key) \
+ { \
+ OQS_ENC_PRINTF("OQS ENC provider: _free_object called\n"); \
+ oqs_prov_free_key(oqs_##impl##_keymgmt_functions, key); \
+ } \
+ static int impl##_to_##kind##_##output##_does_selection(void *ctx, \
+ int selection) \
+ { \
+ OQS_ENC_PRINTF("OQS ENC provider: _does_selection called\n"); \
+ return key2any_check_selection(selection, \
+ DO_##kind##_selection_mask); \
+ } \
+ static int \
+ impl##_to_##kind##_##output##_encode(void *ctx, OSSL_CORE_BIO *cout, \
+ const void *key, \
+ const OSSL_PARAM key_abstract[], \
+ int selection, \
+ OSSL_PASSPHRASE_CALLBACK *cb, \
+ void *cbarg) \
+ { \
+ /* We don't deal with abstract objects */ \
+ OQS_ENC_PRINTF("OQS ENC provider: _encode called\n"); \
+ if (key_abstract != NULL) { \
+ ERR_raise(ERR_LIB_USER, ERR_R_PASSED_INVALID_ARGUMENT); \
+ return 0; \
+ } \
+ DO_##kind(impl, type, output) \
+ \
+ ERR_raise(ERR_LIB_USER, ERR_R_PASSED_INVALID_ARGUMENT); \
+ return 0; \
+ } \
+ const OSSL_DISPATCH \
+ oqs_##impl##_to_##kind##_##output##_encoder_functions[] = { \
+ { OSSL_FUNC_ENCODER_NEWCTX, \
+ (void (*)(void))key2any_newctx }, \
+ { OSSL_FUNC_ENCODER_FREECTX, \
+ (void (*)(void))key2any_freectx }, \
+ { OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS, \
+ (void (*)(void))key2any_settable_ctx_params }, \
+ { OSSL_FUNC_ENCODER_SET_CTX_PARAMS, \
+ (void (*)(void))key2any_set_ctx_params }, \
+ { OSSL_FUNC_ENCODER_DOES_SELECTION, \
+ (void (*)(void))impl##_to_##kind##_##output##_does_selection }, \
+ { OSSL_FUNC_ENCODER_IMPORT_OBJECT, \
+ (void (*)(void))impl##_to_##kind##_##output##_import_object }, \
+ { OSSL_FUNC_ENCODER_FREE_OBJECT, \
+ (void (*)(void))impl##_to_##kind##_##output##_free_object }, \
+ { OSSL_FUNC_ENCODER_ENCODE, \
+ (void (*)(void))impl##_to_##kind##_##output##_encode }, \
+ { 0, NULL } \
+ }
+
+
+/* ---------------------------------------------------------------------- */
+
+/* steal from openssl/providers/implementations/encode_decode/encode_key2text.c */
+
+#define LABELED_BUF_PRINT_WIDTH 15
+
+static int print_labeled_buf(BIO *out, const char *label,
+ const unsigned char *buf, size_t buflen)
+{
+ size_t i;
+
+ if (BIO_printf(out, "%s\n", label) <= 0)
+ return 0;
+
+ for (i = 0; i < buflen; i++) {
+ if ((i % LABELED_BUF_PRINT_WIDTH) == 0) {
+ if (i > 0 && BIO_printf(out, "\n") <= 0)
+ return 0;
+ if (BIO_printf(out, " ") <= 0)
+ return 0;
+ }
+
+ if (BIO_printf(out, "%02x%s", buf[i],
+ (i == buflen - 1) ? "" : ":") <= 0)
+ return 0;
+ }
+ if (BIO_printf(out, "\n") <= 0)
+ return 0;
+
+ return 1;
+}
+
+static int oqsx_to_text(BIO *out, const void *key, int selection)
+{
+ OQSX_KEY* okey = (OQSX_KEY*)key;
+ int is_hybrid = 0;
+
+ if (out == NULL || okey == NULL) {
+ ERR_raise(ERR_LIB_USER, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ if (okey->privkey == NULL) {
+ ERR_raise(ERR_LIB_USER, PROV_R_NOT_A_PRIVATE_KEY);
+ return 0;
+ }
+
+ switch (okey->keytype) {
+ case KEY_TYPE_SIG:
+ case KEY_TYPE_KEM:
+ if (BIO_printf(out, "%s private key:\n", okey->tls_name) <= 0)
+ return 0;
+ break;
+ case KEY_TYPE_ECP_HYB_KEM:
+ case KEY_TYPE_ECX_HYB_KEM:
+ case KEY_TYPE_HYB_SIG:
+ is_hybrid = 1;
+ if (BIO_printf(out, "%s hybrid private key:\n", okey->tls_name) <= 0)
+ return 0;
+ break;
+ default:
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_KEY);
+ return 0;
+ }
+ } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ if (okey->pubkey == NULL) {
+ ERR_raise(ERR_LIB_USER, PROV_R_NOT_A_PUBLIC_KEY);
+ return 0;
+ }
+
+ switch (okey->keytype) {
+ case KEY_TYPE_SIG:
+ case KEY_TYPE_KEM:
+ if (BIO_printf(out, "%s public key:\n", okey->tls_name) <= 0)
+ return 0;
+ break;
+ case KEY_TYPE_ECP_HYB_KEM:
+ case KEY_TYPE_ECX_HYB_KEM:
+ case KEY_TYPE_HYB_SIG:
+ is_hybrid = 1;
+ if (BIO_printf(out, "%s hybrid public key:\n", okey->tls_name) <= 0)
+ return 0;
+ break;
+ default:
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_KEY);
+ return 0;
+ }
+ }
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ int classic_key_len = 0;
+
+ if (okey->numkeys > 1) {
+ char classic_label[200];
+ sprintf(classic_label, "%s key material:", OBJ_nid2sn(okey->evp_info->nid));
+ DECODE_UINT32(classic_key_len, okey->privkey);
+ if (!print_labeled_buf(out, classic_label,
+ okey->comp_privkey[0],
+ classic_key_len))
+ return 0;
+ }
+ /* finally print pure PQ key */
+ if (!print_labeled_buf(out, "PQ key material:", okey->comp_privkey[okey->numkeys-1],
+ okey->privkeylen-classic_key_len-SIZE_OF_UINT32))
+ return 0;
+ }
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ int classic_key_len = 0;
+
+ if (okey->numkeys > 1) {
+ char classic_label[200];
+ DECODE_UINT32(classic_key_len, okey->pubkey);
+ sprintf(classic_label, "%s key material:", OBJ_nid2sn(okey->evp_info->nid));
+ if (!print_labeled_buf(out, classic_label,
+ okey->comp_pubkey[0],
+ classic_key_len))
+ return 0;
+ }
+ /* finally print pure PQ key */
+ if (!print_labeled_buf(out, "PQ key material:", okey->comp_pubkey[okey->numkeys-1],
+ okey->pubkeylen-classic_key_len-SIZE_OF_UINT32))
+ return 0;
+ }
+
+ return 1;
+}
+
+static void *key2text_newctx(void *provctx)
+{
+ return provctx;
+}
+
+static void key2text_freectx(ossl_unused void *vctx)
+{
+}
+
+static int key2text_encode(void *vctx, const void *key, int selection,
+ OSSL_CORE_BIO *cout,
+ int (*key2text)(BIO *out, const void *key,
+ int selection),
+ OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
+{
+ BIO *out = oqs_bio_new_from_core_bio(vctx, cout);
+ int ret;
+
+ if (out == NULL)
+ return 0;
+
+ ret = key2text(out, key, selection);
+ BIO_free(out);
+
+ return ret;
+}
+
+#define MAKE_TEXT_ENCODER(impl) \
+ static OSSL_FUNC_encoder_import_object_fn \
+ impl##2text_import_object; \
+ static OSSL_FUNC_encoder_free_object_fn \
+ impl##2text_free_object; \
+ static OSSL_FUNC_encoder_encode_fn impl##2text_encode; \
+ \
+ static void *impl##2text_import_object(void *ctx, int selection, \
+ const OSSL_PARAM params[]) \
+ { \
+ return oqs_prov_import_key(oqs_##impl##_keymgmt_functions, \
+ ctx, selection, params); \
+ } \
+ static void impl##2text_free_object(void *key) \
+ { \
+ oqs_prov_free_key(oqs_##impl##_keymgmt_functions, key); \
+ } \
+ static int impl##2text_encode(void *vctx, OSSL_CORE_BIO *cout, \
+ const void *key, \
+ const OSSL_PARAM key_abstract[], \
+ int selection, \
+ OSSL_PASSPHRASE_CALLBACK *cb, \
+ void *cbarg) \
+ { \
+ /* We don't deal with abstract objects */ \
+ if (key_abstract != NULL) { \
+ ERR_raise(ERR_LIB_USER, ERR_R_PASSED_INVALID_ARGUMENT); \
+ return 0; \
+ } \
+ return key2text_encode(vctx, key, selection, cout, \
+ oqsx_to_text, cb, cbarg); \
+ } \
+ const OSSL_DISPATCH oqs_##impl##_to_text_encoder_functions[] = { \
+ { OSSL_FUNC_ENCODER_NEWCTX, \
+ (void (*)(void))key2text_newctx }, \
+ { OSSL_FUNC_ENCODER_FREECTX, \
+ (void (*)(void))key2text_freectx }, \
+ { OSSL_FUNC_ENCODER_IMPORT_OBJECT, \
+ (void (*)(void))impl##2text_import_object }, \
+ { OSSL_FUNC_ENCODER_FREE_OBJECT, \
+ (void (*)(void))impl##2text_free_object }, \
+ { OSSL_FUNC_ENCODER_ENCODE, \
+ (void (*)(void))impl##2text_encode }, \
+ { 0, NULL } \
+ }
+
+/*
+ * Replacements for i2d_{TYPE}PrivateKey, i2d_{TYPE}PublicKey,
+ * i2d_{TYPE}params, as they exist.
+ */
+
+/*
+ * PKCS#8 and SubjectPublicKeyInfo support. This may duplicate some of the
+ * implementations specified above, but are more specific.
+ * The SubjectPublicKeyInfo implementations also replace the
+ * PEM_write_bio_{TYPE}_PUBKEY functions.
+ * For PEM, these are expected to be used by PEM_write_bio_PrivateKey(),
+ * PEM_write_bio_PUBKEY() and PEM_write_bio_Parameters().
+ */
+///// OQS_TEMPLATE_FRAGMENT_ENCODER_MAKE_START
+MAKE_ENCODER(dilithium2, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(dilithium2, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(dilithium2, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(dilithium2, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(dilithium2, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(dilithium2, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(dilithium2);
+MAKE_ENCODER(p256_dilithium2, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(p256_dilithium2, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(p256_dilithium2, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(p256_dilithium2, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(p256_dilithium2, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(p256_dilithium2, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(p256_dilithium2);
+MAKE_ENCODER(rsa3072_dilithium2, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_dilithium2, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_dilithium2, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_dilithium2, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_dilithium2, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(rsa3072_dilithium2, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(rsa3072_dilithium2);
+MAKE_ENCODER(dilithium3, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(dilithium3, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(dilithium3, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(dilithium3, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(dilithium3, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(dilithium3, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(dilithium3);
+MAKE_ENCODER(p384_dilithium3, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(p384_dilithium3, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(p384_dilithium3, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(p384_dilithium3, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(p384_dilithium3, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(p384_dilithium3, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(p384_dilithium3);
+MAKE_ENCODER(dilithium5, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(dilithium5, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(dilithium5, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(dilithium5, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(dilithium5, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(dilithium5, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(dilithium5);
+MAKE_ENCODER(p521_dilithium5, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(p521_dilithium5, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(p521_dilithium5, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(p521_dilithium5, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(p521_dilithium5, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(p521_dilithium5, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(p521_dilithium5);
+MAKE_ENCODER(falcon512, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(falcon512, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(falcon512, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(falcon512, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(falcon512, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(falcon512, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(falcon512);
+MAKE_ENCODER(p256_falcon512, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(p256_falcon512, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(p256_falcon512, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(p256_falcon512, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(p256_falcon512, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(p256_falcon512, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(p256_falcon512);
+MAKE_ENCODER(rsa3072_falcon512, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_falcon512, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_falcon512, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_falcon512, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_falcon512, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(rsa3072_falcon512, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(rsa3072_falcon512);
+MAKE_ENCODER(falcon1024, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(falcon1024, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(falcon1024, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(falcon1024, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(falcon1024, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(falcon1024, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(falcon1024);
+MAKE_ENCODER(p521_falcon1024, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(p521_falcon1024, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(p521_falcon1024, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(p521_falcon1024, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(p521_falcon1024, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(p521_falcon1024, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(p521_falcon1024);
+MAKE_ENCODER(sphincssha2128fsimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(sphincssha2128fsimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(sphincssha2128fsimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(sphincssha2128fsimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(sphincssha2128fsimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(sphincssha2128fsimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(sphincssha2128fsimple);
+MAKE_ENCODER(p256_sphincssha2128fsimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(p256_sphincssha2128fsimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(p256_sphincssha2128fsimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(p256_sphincssha2128fsimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(p256_sphincssha2128fsimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(p256_sphincssha2128fsimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(p256_sphincssha2128fsimple);
+MAKE_ENCODER(rsa3072_sphincssha2128fsimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_sphincssha2128fsimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_sphincssha2128fsimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_sphincssha2128fsimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_sphincssha2128fsimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(rsa3072_sphincssha2128fsimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(rsa3072_sphincssha2128fsimple);
+MAKE_ENCODER(sphincssha2128ssimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(sphincssha2128ssimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(sphincssha2128ssimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(sphincssha2128ssimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(sphincssha2128ssimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(sphincssha2128ssimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(sphincssha2128ssimple);
+MAKE_ENCODER(p256_sphincssha2128ssimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(p256_sphincssha2128ssimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(p256_sphincssha2128ssimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(p256_sphincssha2128ssimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(p256_sphincssha2128ssimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(p256_sphincssha2128ssimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(p256_sphincssha2128ssimple);
+MAKE_ENCODER(rsa3072_sphincssha2128ssimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_sphincssha2128ssimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_sphincssha2128ssimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_sphincssha2128ssimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_sphincssha2128ssimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(rsa3072_sphincssha2128ssimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(rsa3072_sphincssha2128ssimple);
+MAKE_ENCODER(sphincssha2192fsimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(sphincssha2192fsimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(sphincssha2192fsimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(sphincssha2192fsimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(sphincssha2192fsimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(sphincssha2192fsimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(sphincssha2192fsimple);
+MAKE_ENCODER(p384_sphincssha2192fsimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(p384_sphincssha2192fsimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(p384_sphincssha2192fsimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(p384_sphincssha2192fsimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(p384_sphincssha2192fsimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(p384_sphincssha2192fsimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(p384_sphincssha2192fsimple);
+MAKE_ENCODER(sphincsshake128fsimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(sphincsshake128fsimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(sphincsshake128fsimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(sphincsshake128fsimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(sphincsshake128fsimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(sphincsshake128fsimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(sphincsshake128fsimple);
+MAKE_ENCODER(p256_sphincsshake128fsimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(p256_sphincsshake128fsimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(p256_sphincsshake128fsimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(p256_sphincsshake128fsimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(p256_sphincsshake128fsimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(p256_sphincsshake128fsimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(p256_sphincsshake128fsimple);
+MAKE_ENCODER(rsa3072_sphincsshake128fsimple, oqsx, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_sphincsshake128fsimple, oqsx, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_sphincsshake128fsimple, oqsx, PrivateKeyInfo, der);
+MAKE_ENCODER(rsa3072_sphincsshake128fsimple, oqsx, PrivateKeyInfo, pem);
+MAKE_ENCODER(rsa3072_sphincsshake128fsimple, oqsx, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(rsa3072_sphincsshake128fsimple, oqsx, SubjectPublicKeyInfo, pem);
+MAKE_TEXT_ENCODER(rsa3072_sphincsshake128fsimple);
+///// OQS_TEMPLATE_FRAGMENT_ENCODER_MAKE_END
+
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider
+ *
+ * Code strongly inspired by OpenSSL endecoder.
+ *
+ * ToDo: Adding hybrid alg support
+ */
+
+#include <openssl/core.h>
+#include <openssl/buffer.h>
+#include <openssl/bio.h>
+#include "oqs_endecoder_local.h"
+
+OSSL_FUNC_keymgmt_new_fn *
+oqs_prov_get_keymgmt_new(const OSSL_DISPATCH *fns)
+{
+ /* Pilfer the keymgmt dispatch table */
+ for (; fns->function_id != 0; fns++)
+ if (fns->function_id == OSSL_FUNC_KEYMGMT_NEW)
+ return OSSL_FUNC_keymgmt_new(fns);
+
+ return NULL;
+}
+
+OSSL_FUNC_keymgmt_free_fn *
+oqs_prov_get_keymgmt_free(const OSSL_DISPATCH *fns)
+{
+ /* Pilfer the keymgmt dispatch table */
+ for (; fns->function_id != 0; fns++)
+ if (fns->function_id == OSSL_FUNC_KEYMGMT_FREE)
+ return OSSL_FUNC_keymgmt_free(fns);
+
+ return NULL;
+}
+
+OSSL_FUNC_keymgmt_import_fn *
+oqs_prov_get_keymgmt_import(const OSSL_DISPATCH *fns)
+{
+ /* Pilfer the keymgmt dispatch table */
+ for (; fns->function_id != 0; fns++)
+ if (fns->function_id == OSSL_FUNC_KEYMGMT_IMPORT)
+ return OSSL_FUNC_keymgmt_import(fns);
+
+ return NULL;
+}
+
+OSSL_FUNC_keymgmt_export_fn *
+oqs_prov_get_keymgmt_export(const OSSL_DISPATCH *fns)
+{
+ /* Pilfer the keymgmt dispatch table */
+ for (; fns->function_id != 0; fns++)
+ if (fns->function_id == OSSL_FUNC_KEYMGMT_EXPORT)
+ return OSSL_FUNC_keymgmt_export(fns);
+
+ return NULL;
+}
+
+void *oqs_prov_import_key(const OSSL_DISPATCH *fns, void *provctx,
+ int selection, const OSSL_PARAM params[])
+{
+ OSSL_FUNC_keymgmt_new_fn *kmgmt_new = oqs_prov_get_keymgmt_new(fns);
+ OSSL_FUNC_keymgmt_free_fn *kmgmt_free = oqs_prov_get_keymgmt_free(fns);
+ OSSL_FUNC_keymgmt_import_fn *kmgmt_import =
+ oqs_prov_get_keymgmt_import(fns);
+ void *key = NULL;
+
+ if (kmgmt_new != NULL && kmgmt_import != NULL && kmgmt_free != NULL) {
+ if ((key = kmgmt_new(provctx)) == NULL
+ || !kmgmt_import(key, selection, params)) {
+ kmgmt_free(key);
+ key = NULL;
+ }
+ }
+ return key;
+}
+
+void oqs_prov_free_key(const OSSL_DISPATCH *fns, void *key)
+{
+ OSSL_FUNC_keymgmt_free_fn *kmgmt_free = oqs_prov_get_keymgmt_free(fns);
+
+ if (kmgmt_free != NULL)
+ kmgmt_free(key);
+}
+
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider
+ *
+ * Code strongly inspired by OpenSSL endecoder.
+ *
+ */
+
+#include <openssl/core.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/types.h>
+#include "oqs_prov.h"
+
+OSSL_FUNC_keymgmt_new_fn *oqs_prov_get_keymgmt_new(const OSSL_DISPATCH *fns);
+OSSL_FUNC_keymgmt_free_fn *oqs_prov_get_keymgmt_free(const OSSL_DISPATCH *fns);
+OSSL_FUNC_keymgmt_import_fn *oqs_prov_get_keymgmt_import(const OSSL_DISPATCH *fns);
+OSSL_FUNC_keymgmt_export_fn *oqs_prov_get_keymgmt_export(const OSSL_DISPATCH *fns);
+
+int oqs_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
+ unsigned char *input_der, long input_der_len,
+ OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);
+
+void *oqs_prov_import_key(const OSSL_DISPATCH *fns, void *provctx,
+ int selection, const OSSL_PARAM params[]);
+void oqs_prov_free_key(const OSSL_DISPATCH *fns, void *key);
+int oqs_read_der(PROV_OQS_CTX *provctx, OSSL_CORE_BIO *cin, unsigned char **data,
+ long *len);
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider
+ *
+ * Code strongly inspired by OpenSSL rsa kem.
+ *
+ * ToDo: Adding hybrid alg support; More testing with more key types.
+ */
+
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/ec.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/err.h>
+#include <string.h>
+#include "oqs_prov.h"
+
+#ifdef NDEBUG
+#define OQS_KEM_PRINTF(a)
+#define OQS_KEM_PRINTF2(a, b)
+#define OQS_KEM_PRINTF3(a, b, c)
+#else
+#define OQS_KEM_PRINTF(a) if (getenv("OQSKEM")) printf(a)
+#define OQS_KEM_PRINTF2(a, b) if (getenv("OQSKEM")) printf(a, b)
+#define OQS_KEM_PRINTF3(a, b, c) if (getenv("OQSKEM")) printf(a, b, c)
+#endif // NDEBUG
+
+
+static OSSL_FUNC_kem_newctx_fn oqs_kem_newctx;
+static OSSL_FUNC_kem_encapsulate_init_fn oqs_kem_encaps_init;
+static OSSL_FUNC_kem_encapsulate_fn oqs_qs_kem_encaps;
+static OSSL_FUNC_kem_encapsulate_fn oqs_hyb_kem_encaps;
+static OSSL_FUNC_kem_decapsulate_fn oqs_qs_kem_decaps;
+static OSSL_FUNC_kem_decapsulate_fn oqs_hyb_kem_decaps;
+static OSSL_FUNC_kem_freectx_fn oqs_kem_freectx;
+
+/*
+ * What's passed as an actual key is defined by the KEYMGMT interface.
+ */
+typedef struct {
+ OSSL_LIB_CTX *libctx;
+ OQSX_KEY *kem;
+} PROV_OQSKEM_CTX;
+
+/// Common KEM functions
+
+static void *oqs_kem_newctx(void *provctx)
+{
+ PROV_OQSKEM_CTX *pkemctx = OPENSSL_zalloc(sizeof(PROV_OQSKEM_CTX));
+
+ OQS_KEM_PRINTF("OQS KEM provider called: newctx\n");
+ if (pkemctx == NULL)
+ return NULL;
+ pkemctx->libctx = PROV_OQS_LIBCTX_OF(provctx);
+ // kem will only be set in init
+
+ return pkemctx;
+}
+
+static void oqs_kem_freectx(void *vpkemctx)
+{
+ PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
+
+ OQS_KEM_PRINTF("OQS KEM provider called: freectx\n");
+ oqsx_key_free(pkemctx->kem);
+ OPENSSL_free(pkemctx);
+}
+
+static int oqs_kem_decapsencaps_init(void *vpkemctx, void *vkem, int operation)
+{
+ PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
+
+ OQS_KEM_PRINTF3("OQS KEM provider called: _init : New: %p; old: %p \n", vkem, pkemctx->kem);
+ if (pkemctx == NULL || vkem == NULL || !oqsx_key_up_ref(vkem))
+ return 0;
+ oqsx_key_free(pkemctx->kem);
+ pkemctx->kem = vkem;
+
+ return 1;
+}
+
+static int oqs_kem_encaps_init(void *vpkemctx, void *vkem, const OSSL_PARAM params[])
+{
+ OQS_KEM_PRINTF("OQS KEM provider called: encaps_init\n");
+ return oqs_kem_decapsencaps_init(vpkemctx, vkem, EVP_PKEY_OP_ENCAPSULATE);
+}
+
+static int oqs_kem_decaps_init(void *vpkemctx, void *vkem, const OSSL_PARAM params[])
+{
+ OQS_KEM_PRINTF("OQS KEM provider called: decaps_init\n");
+ return oqs_kem_decapsencaps_init(vpkemctx, vkem, EVP_PKEY_OP_DECAPSULATE);
+}
+
+/// Quantum-Safe KEM functions (OQS)
+
+static int oqs_qs_kem_encaps_keyslot(void *vpkemctx, unsigned char *out, size_t *outlen,
+ unsigned char *secret, size_t *secretlen, int keyslot)
+{
+ const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
+ const OQS_KEM *kem_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_qs_ctx.kem;
+
+ OQS_KEM_PRINTF("OQS KEM provider called: encaps\n");
+ if (pkemctx->kem == NULL) {
+ OQS_KEM_PRINTF("OQS Warning: OQS_KEM not initialized\n");
+ return -1;
+ }
+ *outlen = kem_ctx->length_ciphertext;
+ *secretlen = kem_ctx->length_shared_secret;
+ if (out == NULL || secret == NULL) {
+ OQS_KEM_PRINTF3("KEM returning lengths %ld and %ld\n", *outlen, *secretlen);
+ return 1;
+ }
+ return OQS_SUCCESS == OQS_KEM_encaps(kem_ctx, out, secret, pkemctx->kem->comp_pubkey[keyslot]);
+}
+
+static int oqs_qs_kem_decaps_keyslot(void *vpkemctx, unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen, int keyslot)
+{
+ const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
+ const OQS_KEM *kem_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_qs_ctx.kem;
+
+ OQS_KEM_PRINTF("OQS KEM provider called: decaps\n");
+ if (pkemctx->kem == NULL) {
+ OQS_KEM_PRINTF("OQS Warning: OQS_KEM not initialized\n");
+ return -1;
+ }
+ *outlen = kem_ctx->length_shared_secret;
+ if (out == NULL) return 1;
+
+ return OQS_SUCCESS == OQS_KEM_decaps(kem_ctx, out, in, pkemctx->kem->comp_privkey[keyslot]);
+}
+
+static int oqs_qs_kem_encaps(void *vpkemctx, unsigned char *out, size_t *outlen,
+ unsigned char *secret, size_t *secretlen)
+{
+ return oqs_qs_kem_encaps_keyslot(vpkemctx, out, outlen, secret, secretlen, 0);
+}
+
+static int oqs_qs_kem_decaps(void *vpkemctx, unsigned char *out, size_t *outlen,
+ const unsigned char *in, size_t inlen)
+{
+ return oqs_qs_kem_decaps_keyslot(vpkemctx, out, outlen, in, inlen, 0);
+}
+
+/// EVP KEM functions
+
+static int oqs_evp_kem_encaps_keyslot(void *vpkemctx, unsigned char *ct, size_t *ctlen,
+ unsigned char *secret, size_t *secretlen, int keyslot)
+{
+ int ret = OQS_SUCCESS, ret2 = 0;
+
+ const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
+ const OQSX_EVP_CTX *evp_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_evp_ctx;
+
+ size_t pubkey_kexlen = 0;
+ size_t kexDeriveLen = 0, pkeylen = 0;
+ unsigned char *pubkey_kex = pkemctx->kem->comp_pubkey[keyslot];
+
+ // Free at err:
+ EVP_PKEY_CTX *ctx = NULL, *kgctx = NULL;;
+ EVP_PKEY *pkey = NULL, *peerpk = NULL;
+ unsigned char *ctkex_encoded = NULL;
+
+ pubkey_kexlen = evp_ctx->evp_info->length_public_key;
+ kexDeriveLen = evp_ctx->evp_info->kex_length_secret;
+
+ *ctlen = pubkey_kexlen;
+ *secretlen = kexDeriveLen;
+
+ if (ct == NULL || secret == NULL) {
+ OQS_KEM_PRINTF3("EVP KEM returning lengths %ld and %ld\n", *ctlen, *secretlen);
+ return 1;
+ }
+
+ peerpk = EVP_PKEY_new();
+ ON_ERR_SET_GOTO(!peerpk, ret, -1, err);
+
+ ret2 = EVP_PKEY_copy_parameters(peerpk, evp_ctx->keyParam);
+ ON_ERR_SET_GOTO(ret2 <= 0, ret, -1, err);
+
+ ret2 = EVP_PKEY_set1_encoded_public_key(peerpk, pubkey_kex, pubkey_kexlen);
+ ON_ERR_SET_GOTO(ret2 <= 0, ret, -1, err);
+
+ kgctx = EVP_PKEY_CTX_new(evp_ctx->keyParam, NULL);
+ ON_ERR_SET_GOTO(!kgctx, ret, -1, err);
+
+ ret2 = EVP_PKEY_keygen_init(kgctx);
+ ON_ERR_SET_GOTO(ret2 != 1, ret, -1, err);
+
+ ret2 = EVP_PKEY_keygen(kgctx, &pkey);
+ ON_ERR_SET_GOTO(ret2 != 1, ret, -1, err);
+
+ ctx = EVP_PKEY_CTX_new(pkey, NULL);
+ ON_ERR_SET_GOTO(!ctx, ret, -1, err);
+
+ ret = EVP_PKEY_derive_init(ctx);
+ ON_ERR_SET_GOTO(ret <= 0, ret, -1, err);
+
+ ret = EVP_PKEY_derive_set_peer(ctx, peerpk);
+ ON_ERR_SET_GOTO(ret <= 0, ret, -1, err);
+
+ ret = EVP_PKEY_derive(ctx, secret, &kexDeriveLen);
+ ON_ERR_SET_GOTO(ret <= 0, ret, -1, err);
+
+ pkeylen = EVP_PKEY_get1_encoded_public_key(pkey, &ctkex_encoded);
+ ON_ERR_SET_GOTO(pkeylen <= 0 || !ctkex_encoded || pkeylen != pubkey_kexlen, ret, -1, err);
+
+ memcpy(ct, ctkex_encoded, pkeylen);
+
+ err:
+ EVP_PKEY_CTX_free(ctx);
+ EVP_PKEY_CTX_free(kgctx);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(peerpk);
+ OPENSSL_free(ctkex_encoded);
+ return ret;
+}
+
+static int oqs_evp_kem_decaps_keyslot(void *vpkemctx, unsigned char *secret, size_t *secretlen,
+ const unsigned char *ct, size_t ctlen, int keyslot)
+{
+ OQS_KEM_PRINTF("OQS KEM provider called: oqs_hyb_kem_decaps\n");
+
+ int ret = OQS_SUCCESS, ret2 = 0;
+ const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
+ const OQSX_EVP_CTX *evp_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_evp_ctx;
+
+ size_t pubkey_kexlen = evp_ctx->evp_info->length_public_key;
+ size_t kexDeriveLen = evp_ctx->evp_info->kex_length_secret;
+ unsigned char *privkey_kex = pkemctx->kem->comp_privkey[keyslot];
+ size_t privkey_kexlen = evp_ctx->evp_info->length_private_key;
+
+ // Free at err:
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *pkey = NULL, *peerpkey = NULL;
+
+ *secretlen = kexDeriveLen;
+ if (secret == NULL) return 1;
+
+ if (evp_ctx->evp_info->raw_key_support) {
+ pkey = EVP_PKEY_new_raw_private_key(evp_ctx->evp_info->keytype, NULL, privkey_kex, privkey_kexlen);
+ ON_ERR_SET_GOTO(!pkey, ret, -10, err);
+ } else {
+ pkey = d2i_AutoPrivateKey(&pkey, (const unsigned char **)&privkey_kex, privkey_kexlen);
+ ON_ERR_SET_GOTO(!pkey, ret, -2, err);
+ }
+
+ peerpkey = EVP_PKEY_new();
+ ON_ERR_SET_GOTO(!peerpkey, ret, -3, err);
+
+ ret2 = EVP_PKEY_copy_parameters(peerpkey, evp_ctx->keyParam);
+ ON_ERR_SET_GOTO(ret2 <= 0, ret, -4, err);
+
+ ret2 = EVP_PKEY_set1_encoded_public_key(peerpkey, ct, pubkey_kexlen);
+ ON_ERR_SET_GOTO(ret2 <= 0 || !peerpkey, ret, -5, err);
+
+ ctx = EVP_PKEY_CTX_new(pkey, NULL);
+ ON_ERR_SET_GOTO(!ctx, ret, -6, err);
+
+ ret = EVP_PKEY_derive_init(ctx);
+ ON_ERR_SET_GOTO(ret <= 0, ret, -7, err);
+ ret = EVP_PKEY_derive_set_peer(ctx, peerpkey);
+ ON_ERR_SET_GOTO(ret <= 0, ret, -8, err);
+
+ ret = EVP_PKEY_derive(ctx, secret, &kexDeriveLen);
+ ON_ERR_SET_GOTO(ret <= 0, ret, -9, err);
+
+ err:
+ EVP_PKEY_free(peerpkey);
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_CTX_free(ctx);
+ return ret;
+}
+
+/// Hybrid KEM functions
+
+static int oqs_hyb_kem_encaps(void *vpkemctx, unsigned char *ct, size_t *ctlen,
+ unsigned char *secret, size_t *secretlen)
+{
+ int ret = OQS_SUCCESS;
+ const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
+ size_t secretLen0 = 0, secretLen1 = 0;
+ size_t ctLen0 = 0, ctLen1 = 0;
+ unsigned char *ct0, *ct1, *secret0, *secret1;
+
+ ret = oqs_evp_kem_encaps_keyslot(vpkemctx, NULL, &ctLen0, NULL, &secretLen0, 0);
+ ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
+ ret = oqs_qs_kem_encaps_keyslot(vpkemctx, NULL, &ctLen1, NULL, &secretLen1, 1);
+ ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
+
+
+ *ctlen = ctLen0 + ctLen1;
+ *secretlen = secretLen0 + secretLen1;
+
+ if (ct == NULL || secret == NULL) {
+ OQS_KEM_PRINTF3("HYB KEM returning lengths %ld and %ld\n", *ctlen, *secretlen);
+ return 1;
+ }
+
+ ct0 = ct;
+ ct1 = ct + ctLen0;
+ secret0 = secret;
+ secret1 = secret + secretLen0;
+
+ ret = oqs_evp_kem_encaps_keyslot(vpkemctx, ct0, &ctLen0, secret0, &secretLen0, 0);
+ ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
+
+ ret = oqs_qs_kem_encaps_keyslot(vpkemctx, ct1, &ctLen1, secret1, &secretLen1, 1);
+ ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
+
+ err:
+ return ret;
+}
+
+static int oqs_hyb_kem_decaps(void *vpkemctx, unsigned char *secret, size_t *secretlen,
+ const unsigned char *ct, size_t ctlen)
+{
+ int ret = OQS_SUCCESS;
+ const PROV_OQSKEM_CTX *pkemctx = (PROV_OQSKEM_CTX *)vpkemctx;
+ const OQSX_EVP_CTX *evp_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_evp_ctx;
+ const OQS_KEM *qs_ctx = pkemctx->kem->oqsx_provider_ctx.oqsx_qs_ctx.kem;
+
+ size_t secretLen0 = 0, secretLen1 = 0;
+ size_t ctLen0 = 0, ctLen1 = 0;
+ const unsigned char *ct0, *ct1;
+ unsigned char *secret0, *secret1;
+
+ ret = oqs_evp_kem_decaps_keyslot(vpkemctx, NULL, &secretLen0, NULL, 0, 0);
+ ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
+ ret = oqs_qs_kem_decaps_keyslot(vpkemctx, NULL, &secretLen1, NULL, 0, 1);
+ ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
+
+ *secretlen = secretLen0 + secretLen1;
+
+ if (secret == NULL) return 1;
+
+ ctLen0 = evp_ctx->evp_info->length_public_key;
+ ctLen1 = qs_ctx->length_ciphertext;
+
+ ON_ERR_SET_GOTO(ctLen0 + ctLen1 != ctlen, ret, OQS_ERROR, err);
+
+ ct0 = ct;
+ ct1 = ct + ctLen0;
+ secret0 = secret;
+ secret1 = secret + secretLen0;
+
+ ret = oqs_evp_kem_decaps_keyslot(vpkemctx, secret0, &secretLen0, ct0, ctLen0, 0);
+ ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
+ ret = oqs_qs_kem_decaps_keyslot(vpkemctx, secret1, &secretLen1, ct1, ctLen1, 1);
+ ON_ERR_SET_GOTO(ret <= 0, ret, OQS_ERROR, err);
+
+ err:
+ return ret;
+}
+
+#define MAKE_KEM_FUNCTIONS(alg) \
+ const OSSL_DISPATCH oqs_##alg##_kem_functions[] = { \
+ { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))oqs_kem_newctx }, \
+ { OSSL_FUNC_KEM_ENCAPSULATE_INIT, (void (*)(void))oqs_kem_encaps_init }, \
+ { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))oqs_qs_kem_encaps }, \
+ { OSSL_FUNC_KEM_DECAPSULATE_INIT, (void (*)(void))oqs_kem_decaps_init }, \
+ { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))oqs_qs_kem_decaps }, \
+ { OSSL_FUNC_KEM_FREECTX, (void (*)(void))oqs_kem_freectx }, \
+ { 0, NULL } \
+ };
+
+#define MAKE_HYB_KEM_FUNCTIONS(alg) \
+ const OSSL_DISPATCH oqs_##alg##_kem_functions[] = { \
+ { OSSL_FUNC_KEM_NEWCTX, (void (*)(void))oqs_kem_newctx }, \
+ { OSSL_FUNC_KEM_ENCAPSULATE_INIT, (void (*)(void))oqs_kem_encaps_init }, \
+ { OSSL_FUNC_KEM_ENCAPSULATE, (void (*)(void))oqs_hyb_kem_encaps }, \
+ { OSSL_FUNC_KEM_DECAPSULATE_INIT, (void (*)(void))oqs_kem_decaps_init }, \
+ { OSSL_FUNC_KEM_DECAPSULATE, (void (*)(void))oqs_hyb_kem_decaps }, \
+ { OSSL_FUNC_KEM_FREECTX, (void (*)(void))oqs_kem_freectx }, \
+ { 0, NULL } \
+ };
+
+// keep this just in case we need to become ALG-specific at some point in time
+MAKE_KEM_FUNCTIONS(generic)
+MAKE_HYB_KEM_FUNCTIONS(hybrid)
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider
+ *
+ * Code strongly inspired by OpenSSL ecx key management.
+ *
+ * ToDo: More testing in non-KEM cases
+ */
+
+#include <assert.h>
+
+#include <string.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include "openssl/param_build.h"
+#include "oqs_prov.h"
+
+// stolen from openssl/crypto/param_build_set.c as ossl_param_build_set_octet_string not public API:
+
+int oqsx_param_build_set_octet_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key,
+ const unsigned char *data,
+ size_t data_len)
+{
+ if (bld != NULL)
+ return OSSL_PARAM_BLD_push_octet_string(bld, key, data, data_len);
+
+ p = OSSL_PARAM_locate(p, key);
+ if (p != NULL)
+ return OSSL_PARAM_set_octet_string(p, data, data_len);
+ return 1;
+}
+
+
+
+#ifdef NDEBUG
+#define OQS_KM_PRINTF(a)
+#define OQS_KM_PRINTF2(a, b)
+#define OQS_KM_PRINTF3(a, b, c)
+#else
+#define OQS_KM_PRINTF(a) if (getenv("OQSKM")) printf(a)
+#define OQS_KM_PRINTF2(a, b) if (getenv("OQSKM")) printf(a, b)
+#define OQS_KM_PRINTF3(a, b, c) if (getenv("OQSKM")) printf(a, b, c)
+#endif // NDEBUG
+
+// our own error codes:
+#define OQSPROV_UNEXPECTED_NULL 1
+
+static OSSL_FUNC_keymgmt_gen_cleanup_fn oqsx_gen_cleanup;
+static OSSL_FUNC_keymgmt_load_fn oqsx_load;
+static OSSL_FUNC_keymgmt_get_params_fn oqsx_get_params;
+static OSSL_FUNC_keymgmt_gettable_params_fn oqs_gettable_params;
+static OSSL_FUNC_keymgmt_set_params_fn oqsx_set_params;
+static OSSL_FUNC_keymgmt_settable_params_fn oqsx_settable_params;
+static OSSL_FUNC_keymgmt_has_fn oqsx_has;
+static OSSL_FUNC_keymgmt_match_fn oqsx_match;
+static OSSL_FUNC_keymgmt_import_fn oqsx_import;
+static OSSL_FUNC_keymgmt_import_types_fn oqs_imexport_types;
+static OSSL_FUNC_keymgmt_export_fn oqsx_export;
+static OSSL_FUNC_keymgmt_export_types_fn oqs_imexport_types;
+
+struct oqsx_gen_ctx {
+ OSSL_LIB_CTX *libctx;
+ char *propq;
+ char *oqs_name;
+ char *tls_name;
+ int primitive;
+ int selection;
+ int bit_security;
+ int alg_idx;
+};
+
+static int oqsx_has(const void *keydata, int selection)
+{
+ const OQSX_KEY *key = keydata;
+ int ok = 0;
+
+ OQS_KM_PRINTF("OQSKEYMGMT: has called\n");
+ if (key != NULL) {
+ /*
+ * OQSX keys always have all the parameters they need (i.e. none).
+ * Therefore we always return with 1, if asked about parameters.
+ */
+ ok = 1;
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
+ ok = ok && key->pubkey != NULL;
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
+ ok = ok && key->privkey != NULL;
+ }
+ if (!ok) OQS_KM_PRINTF2("OQSKM: has returning FALSE on selection %2x\n", selection);
+ return ok;
+}
+
+/*
+ * Key matching has a problem in OQS world: OpenSSL assumes all keys to (also)
+ * contain public key material (https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_eq.html).
+ * This is not the case with decoded private keys: Not all algorithms permit re-creating
+ * public key material from private keys (https://github.com/PQClean/PQClean/issues/415#issuecomment-910377682).
+ * Thus we implement the following logic:
+ * 1) Private keys are matched binary if available in both keys; only one key having private key material
+ * will be considered a mismatch
+ * 2) Public keys are matched binary if available in both keys; only one key having public key material
+ * will NOT be considered a mismatch if both private keys are present and match: The latter logic will
+ * only be triggered if domain parameter matching is requested to distinguish between a pure-play
+ * public key match/test and one checking OpenSSL-type "EVP-PKEY-equality". This is possible as domain
+ * parameters don't really play a role in OQS, so we consider them as a proxy for private key matching.
+ */
+
+static int oqsx_match(const void *keydata1, const void *keydata2, int selection)
+{
+ const OQSX_KEY *key1 = keydata1;
+ const OQSX_KEY *key2 = keydata2;
+ int ok = 1;
+
+ OQS_KM_PRINTF3("OQSKEYMGMT: match called for %p and %p\n", keydata1, keydata2);
+ OQS_KM_PRINTF2("OQSKEYMGMT: match called for selection %d\n", selection);
+
+#ifdef NOPUBKEY_IN_PRIVKEY
+ /* Now this is a "leap of faith" logic: If a public-only PKEY and a private-only PKEY
+ * are tested for equality we cannot do anything other than saying OK (as per
+ * https://github.com/PQClean/PQClean/issues/415#issuecomment-910377682) if at
+ * least the key type name matches. Potential actual key mismatches will only
+ * be discovered later.
+ */
+ if (((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) && ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)) {
+ if ((key1->privkey == NULL && key2->pubkey == NULL)
+ || (key1->pubkey == NULL && key2->privkey == NULL)
+ || ((key1->tls_name!=NULL && key2->tls_name!=NULL) && !strcmp(key1->tls_name, key2->tls_name))) {
+ OQS_KM_PRINTF("OQSKEYMGMT: leap-of-faith match\n");
+ return 1;
+ }
+ }
+#endif
+
+ if (((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) && ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)) {
+ if ((key1->privkey == NULL && key2->privkey != NULL)
+ || (key1->privkey != NULL && key2->privkey == NULL)
+ || ((key1->tls_name!=NULL && key2->tls_name!=NULL) && strcmp(key1->tls_name, key2->tls_name)))
+ ok = 0;
+ else
+ ok = ( (key1->privkey==NULL && key2->privkey==NULL) || ((key1->privkey != NULL) && CRYPTO_memcmp(key1->privkey, key2->privkey, key1->privkeylen) == 0) );
+ }
+
+ if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ if ((key1->pubkey == NULL && key2->pubkey != NULL) ||
+ (key1->pubkey != NULL && key2->pubkey == NULL) ||
+ ((key1->tls_name!=NULL && key2->tls_name!=NULL) && strcmp(key1->tls_name, key2->tls_name)))
+ // special case now: If domain parameter matching requested, consider private key match sufficient:
+ ok = ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) &&
+ (key1->privkey != NULL && key2->privkey != NULL) &&
+ (CRYPTO_memcmp(key1->privkey, key2->privkey, key1->privkeylen) == 0);
+ else
+ ok = ok && ( (key1->pubkey==NULL && key2->pubkey==NULL) || ((key1->pubkey != NULL) && CRYPTO_memcmp(key1->pubkey, key2->pubkey, key1->pubkeylen) == 0) );
+ }
+ if (!ok) OQS_KM_PRINTF("OQSKEYMGMT: match failed!\n");
+ return ok;
+}
+
+static int oqsx_import(void *keydata, int selection, const OSSL_PARAM params[])
+{
+ OQSX_KEY *key = keydata;
+ int ok = 0;
+
+ OQS_KM_PRINTF("OQSKEYMGMT: import called \n");
+ if (key == NULL) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_UNEXPECTED_NULL);
+ return ok;
+ }
+
+ if (((selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) &&
+ (oqsx_key_fromdata(key, params, 1)))
+ ok = 1;
+ return ok;
+}
+
+int oqsx_key_to_params(const OQSX_KEY *key, OSSL_PARAM_BLD *tmpl,
+ OSSL_PARAM params[], int include_private)
+{
+ int ret = 0;
+
+ if (key == NULL)
+ return 0;
+
+ if (key->pubkey != NULL) {
+ OSSL_PARAM *p = NULL;
+
+ if (tmpl == NULL) {
+ p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
+ }
+
+ if (p != NULL || tmpl != NULL) {
+ if ( key->pubkeylen == 0
+ || !oqsx_param_build_set_octet_string(tmpl, p,
+ OSSL_PKEY_PARAM_PUB_KEY,
+ key->pubkey, key->pubkeylen))
+ goto err;
+ }
+ }
+ if (key->privkey != NULL && include_private) {
+ OSSL_PARAM *p = NULL;
+
+ /*
+ * Key import/export should never leak the bit length of the secret
+ * scalar in the key. Conceptually. OQS is not production strength
+ * so does not care. TBD.
+ *
+ */
+
+ if (tmpl == NULL) {
+ p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PRIV_KEY);
+ }
+
+ if (p != NULL || tmpl != NULL) {
+ if ( key->privkeylen == 0
+ || !oqsx_param_build_set_octet_string(tmpl, p,
+ OSSL_PKEY_PARAM_PRIV_KEY,
+ key->privkey, key->privkeylen))
+ goto err;
+ }
+ }
+ ret = 1;
+ err:
+ return ret;
+}
+
+static int oqsx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
+ void *cbarg)
+{
+ OQSX_KEY *key = keydata;
+ OSSL_PARAM_BLD *tmpl;
+ OSSL_PARAM *params = NULL;
+ OSSL_PARAM *p;
+ int ok = 1;
+
+ OQS_KM_PRINTF("OQSKEYMGMT: export called\n");
+
+ /*
+ * In this implementation, only public and private keys can be exported, nothing else
+ */
+ if (key == NULL) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_UNEXPECTED_NULL);
+ return 0;
+ }
+
+ tmpl = OSSL_PARAM_BLD_new();
+ if (tmpl == NULL) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_UNEXPECTED_NULL);
+ return 0;
+ }
+
+ if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+ int include_private =
+ selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
+
+ ok = ok && oqsx_key_to_params(key, tmpl, NULL, include_private);
+ }
+
+ params = OSSL_PARAM_BLD_to_param(tmpl);
+ if (params == NULL) {
+ ok = 0;
+ goto err;
+ }
+
+ ok = ok & param_cb(params, cbarg);
+ OSSL_PARAM_free(params);
+err:
+ OSSL_PARAM_BLD_free(tmpl);
+ return ok;
+}
+
+#define OQS_KEY_TYPES() \
+OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
+OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
+
+static const OSSL_PARAM oqsx_key_types[] = {
+ OQS_KEY_TYPES(),
+ OSSL_PARAM_END
+};
+static const OSSL_PARAM *oqs_imexport_types(int selection)
+{
+ OQS_KM_PRINTF("OQSKEYMGMT: imexport called\n");
+ if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
+ return oqsx_key_types;
+ return NULL;
+}
+
+// must handle param requests for KEM and SIG keys...
+static int oqsx_get_params(void *key, OSSL_PARAM params[])
+{
+ OQSX_KEY *oqsxk = key;
+ OSSL_PARAM *p;
+
+ OQS_KM_PRINTF2("OQSKEYMGMT: get_params called for %s\n", params[0].key);
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
+ && !OSSL_PARAM_set_int(p, oqsx_key_secbits(oqsxk)))
+ return 0;
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
+ && !OSSL_PARAM_set_int(p, oqsx_key_secbits(oqsxk)))
+ return 0;
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
+ && !OSSL_PARAM_set_int(p, oqsx_key_maxsize(oqsxk)))
+ return 0;
+
+ /* add as temporary workaround TBC */
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL
+ && !OSSL_PARAM_set_utf8_string(p, SN_undef))
+ return 0;
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MANDATORY_DIGEST)) != NULL
+ && !OSSL_PARAM_set_utf8_string(p, SN_undef))
+ return 0;
+ /* end workaround */
+
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) {
+ // hybrid KEMs are special in that the classic length information shall not be passed out:
+ if (oqsxk->keytype == KEY_TYPE_ECP_HYB_KEM || oqsxk->keytype == KEY_TYPE_ECX_HYB_KEM) {
+ if (!OSSL_PARAM_set_octet_string(p, (char*)oqsxk->pubkey+SIZE_OF_UINT32, oqsxk->pubkeylen-SIZE_OF_UINT32))
+ return 0;
+ }
+ else {
+ if (!OSSL_PARAM_set_octet_string(p, oqsxk->pubkey, oqsxk->pubkeylen))
+ return 0;
+ }
+ }
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY)) != NULL) {
+ if (!OSSL_PARAM_set_octet_string(p, oqsxk->pubkey, oqsxk->pubkeylen))
+ return 0;
+ }
+ if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PRIV_KEY)) != NULL) {
+ if (!OSSL_PARAM_set_octet_string(p, oqsxk->privkey, oqsxk->privkeylen))
+ return 0;
+ }
+
+ return 1;
+}
+
+static const OSSL_PARAM oqsx_gettable_params[] = {
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
+ OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
+ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
+ OQS_KEY_TYPES(),
+ OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *oqs_gettable_params(void *provctx)
+{
+ OQS_KM_PRINTF("OQSKEYMGMT: gettable_params called\n");
+ return oqsx_gettable_params;
+}
+
+static int set_property_query(OQSX_KEY *oqsxkey, const char *propq)
+{
+ OPENSSL_free(oqsxkey->propq);
+ oqsxkey->propq = NULL;
+ OQS_KM_PRINTF("OQSKEYMGMT: property_query called\n");
+ if (propq != NULL) {
+ oqsxkey->propq = OPENSSL_strdup(propq);
+ if (oqsxkey->propq == NULL) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int oqsx_set_params(void *key, const OSSL_PARAM params[])
+{
+ OQSX_KEY *oqsxkey = key;
+ const OSSL_PARAM *p;
+
+ OQS_KM_PRINTF("OQSKEYMGMT: set_params called\n");
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
+ if (p != NULL) {
+ size_t used_len;
+ int classic_pubkey_len;
+ if (oqsxkey->keytype == KEY_TYPE_ECP_HYB_KEM || oqsxkey->keytype == KEY_TYPE_ECX_HYB_KEM) {
+ // classic key len already stored by key setup; only data needs to be filled in
+ if (p->data_size != oqsxkey->pubkeylen-SIZE_OF_UINT32
+ || !OSSL_PARAM_get_octet_string(p, &oqsxkey->comp_pubkey[0], oqsxkey->pubkeylen-SIZE_OF_UINT32,
+ &used_len)) {
+ return 0;
+ }
+ }
+ else {
+ if (p->data_size != oqsxkey->pubkeylen
+ || !OSSL_PARAM_get_octet_string(p, &oqsxkey->pubkey, oqsxkey->pubkeylen,
+ &used_len)) {
+ return 0;
+ }
+ }
+ OPENSSL_clear_free(oqsxkey->privkey, oqsxkey->privkeylen);
+ oqsxkey->privkey = NULL;
+ }
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PROPERTIES);
+ if (p != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING
+ || !set_property_query(oqsxkey, p->data)) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static const OSSL_PARAM oqs_settable_params[] = {
+ OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0),
+ OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *oqsx_settable_params(void *provctx)
+{
+ OQS_KM_PRINTF("OQSKEYMGMT: settable_params called\n");
+ return oqs_settable_params;
+}
+
+static void *oqsx_gen_init(void *provctx, int selection, char* oqs_name, char* tls_name, int primitive, int bit_security, int alg_idx)
+{
+ OSSL_LIB_CTX *libctx = PROV_OQS_LIBCTX_OF(provctx);
+ struct oqsx_gen_ctx *gctx = NULL;
+
+ OQS_KM_PRINTF2("OQSKEYMGMT: gen_init called for key %s \n", oqs_name);
+
+ if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
+ gctx->libctx = libctx;
+ gctx->oqs_name = OPENSSL_strdup(oqs_name);
+ gctx->tls_name = OPENSSL_strdup(tls_name);
+ gctx->primitive = primitive;
+ gctx->selection = selection;
+ gctx->bit_security = bit_security;
+ gctx->alg_idx = alg_idx;
+ }
+ return gctx;
+}
+
+static void *oqsx_genkey(struct oqsx_gen_ctx *gctx)
+{
+ OQSX_KEY *key;
+
+ OQS_KM_PRINTF3("OQSKEYMGMT: gen called for %s (%s)\n", gctx->oqs_name, gctx->tls_name);
+ if (gctx == NULL)
+ return NULL;
+ if ((key = oqsx_key_new(gctx->libctx, gctx->oqs_name, gctx->tls_name, gctx->primitive, gctx->propq, gctx->bit_security, gctx->alg_idx)) == NULL) {
+ OQS_KM_PRINTF2("OQSKM: Error generating key for %s\n", gctx->tls_name);
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (oqsx_key_gen(key)) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_UNEXPECTED_NULL);
+ return NULL;
+ }
+ return key;
+}
+
+static void *oqsx_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
+{
+ struct oqsx_gen_ctx *gctx = genctx;
+
+ OQS_KM_PRINTF("OQSKEYMGMT: gen called\n");
+
+ return oqsx_genkey(gctx);
+}
+
+static void oqsx_gen_cleanup(void *genctx)
+{
+ struct oqsx_gen_ctx *gctx = genctx;
+
+ OQS_KM_PRINTF("OQSKEYMGMT: gen_cleanup called\n");
+ OPENSSL_free(gctx->oqs_name);
+ OPENSSL_free(gctx->tls_name);
+ OPENSSL_free(gctx->propq);
+ OPENSSL_free(gctx);
+}
+
+void *oqsx_load(const void *reference, size_t reference_sz)
+{
+ OQSX_KEY *key = NULL;
+
+ OQS_KM_PRINTF("OQSKEYMGMT: load called\n");
+ if (reference_sz == sizeof(key)) {
+ /* The contents of the reference is the address to our object */
+ key = *(OQSX_KEY **)reference;
+ /* We grabbed, so we detach it */
+ *(OQSX_KEY **)reference = NULL;
+ return key;
+ }
+ return NULL;
+}
+
+static const OSSL_PARAM *oqsx_gen_settable_params(void *provctx)
+{
+ static OSSL_PARAM settable[] = {
+ OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_KDF_PARAM_PROPERTIES, NULL, 0),
+ OSSL_PARAM_END
+ };
+ return settable;
+}
+
+static int oqsx_gen_set_params(void *genctx, const OSSL_PARAM params[])
+{
+ struct oqsx_gen_ctx *gctx = genctx;
+ const OSSL_PARAM *p;
+
+ OQS_KM_PRINTF("OQSKEYMGMT: gen_set_params called\n");
+ if (gctx == NULL)
+ return 0;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
+ if (p != NULL) {
+ const char *algname = (char*)p->data;
+
+ OPENSSL_free(gctx->tls_name);
+ gctx->tls_name = OPENSSL_strdup(algname);
+ }
+ p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PROPERTIES);
+ if (p != NULL) {
+ if (p->data_type != OSSL_PARAM_UTF8_STRING)
+ return 0;
+ OPENSSL_free(gctx->propq);
+ gctx->propq = OPENSSL_strdup(p->data);
+ if (gctx->propq == NULL)
+ return 0;
+ }
+ return 1;
+}
+
+
+///// OQS_TEMPLATE_FRAGMENT_KEYMGMT_CONSTRUCTORS_START
+static void *dilithium2_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_dilithium_2, "dilithium2", KEY_TYPE_SIG, NULL, 128, 0);
+}
+
+static void *dilithium2_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_dilithium_2, "dilithium2", 0, 128, 0);
+}
+static void *p256_dilithium2_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_dilithium_2, "p256_dilithium2", KEY_TYPE_HYB_SIG, NULL, 128, 1);
+}
+
+static void *p256_dilithium2_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_dilithium_2, "p256_dilithium2", KEY_TYPE_HYB_SIG, 128, 1);
+}
+static void *rsa3072_dilithium2_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_dilithium_2, "rsa3072_dilithium2", KEY_TYPE_HYB_SIG, NULL, 128, 2);
+}
+
+static void *rsa3072_dilithium2_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_dilithium_2, "rsa3072_dilithium2", KEY_TYPE_HYB_SIG, 128, 2);
+}
+static void *dilithium3_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_dilithium_3, "dilithium3", KEY_TYPE_SIG, NULL, 192, 3);
+}
+
+static void *dilithium3_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_dilithium_3, "dilithium3", 0, 192, 3);
+}
+static void *p384_dilithium3_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_dilithium_3, "p384_dilithium3", KEY_TYPE_HYB_SIG, NULL, 192, 4);
+}
+
+static void *p384_dilithium3_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_dilithium_3, "p384_dilithium3", KEY_TYPE_HYB_SIG, 192, 4);
+}
+static void *dilithium5_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_dilithium_5, "dilithium5", KEY_TYPE_SIG, NULL, 256, 5);
+}
+
+static void *dilithium5_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_dilithium_5, "dilithium5", 0, 256, 5);
+}
+static void *p521_dilithium5_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_dilithium_5, "p521_dilithium5", KEY_TYPE_HYB_SIG, NULL, 256, 6);
+}
+
+static void *p521_dilithium5_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_dilithium_5, "p521_dilithium5", KEY_TYPE_HYB_SIG, 256, 6);
+}
+
+static void *falcon512_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_512, "falcon512", KEY_TYPE_SIG, NULL, 128, 7);
+}
+
+static void *falcon512_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_512, "falcon512", 0, 128, 7);
+}
+static void *p256_falcon512_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_512, "p256_falcon512", KEY_TYPE_HYB_SIG, NULL, 128, 8);
+}
+
+static void *p256_falcon512_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_512, "p256_falcon512", KEY_TYPE_HYB_SIG, 128, 8);
+}
+static void *rsa3072_falcon512_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_512, "rsa3072_falcon512", KEY_TYPE_HYB_SIG, NULL, 128, 9);
+}
+
+static void *rsa3072_falcon512_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_512, "rsa3072_falcon512", KEY_TYPE_HYB_SIG, 128, 9);
+}
+static void *falcon1024_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_1024, "falcon1024", KEY_TYPE_SIG, NULL, 256, 10);
+}
+
+static void *falcon1024_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_1024, "falcon1024", 0, 256, 10);
+}
+static void *p521_falcon1024_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_falcon_1024, "p521_falcon1024", KEY_TYPE_HYB_SIG, NULL, 256, 11);
+}
+
+static void *p521_falcon1024_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_falcon_1024, "p521_falcon1024", KEY_TYPE_HYB_SIG, 256, 11);
+}
+
+
+static void *sphincssha2128fsimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128f_simple, "sphincssha2128fsimple", KEY_TYPE_SIG, NULL, 128, 12);
+}
+
+static void *sphincssha2128fsimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_128f_simple, "sphincssha2128fsimple", 0, 128, 12);
+}
+static void *p256_sphincssha2128fsimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128f_simple, "p256_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 13);
+}
+
+static void *p256_sphincssha2128fsimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_128f_simple, "p256_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, 128, 13);
+}
+static void *rsa3072_sphincssha2128fsimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128f_simple, "rsa3072_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 14);
+}
+
+static void *rsa3072_sphincssha2128fsimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_128f_simple, "rsa3072_sphincssha2128fsimple", KEY_TYPE_HYB_SIG, 128, 14);
+}
+static void *sphincssha2128ssimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128s_simple, "sphincssha2128ssimple", KEY_TYPE_SIG, NULL, 128, 15);
+}
+
+static void *sphincssha2128ssimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_128s_simple, "sphincssha2128ssimple", 0, 128, 15);
+}
+static void *p256_sphincssha2128ssimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128s_simple, "p256_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, NULL, 128, 16);
+}
+
+static void *p256_sphincssha2128ssimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_128s_simple, "p256_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, 128, 16);
+}
+static void *rsa3072_sphincssha2128ssimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_128s_simple, "rsa3072_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, NULL, 128, 17);
+}
+
+static void *rsa3072_sphincssha2128ssimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_128s_simple, "rsa3072_sphincssha2128ssimple", KEY_TYPE_HYB_SIG, 128, 17);
+}
+static void *sphincssha2192fsimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_192f_simple, "sphincssha2192fsimple", KEY_TYPE_SIG, NULL, 192, 18);
+}
+
+static void *sphincssha2192fsimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_192f_simple, "sphincssha2192fsimple", 0, 192, 18);
+}
+static void *p384_sphincssha2192fsimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_sha2_192f_simple, "p384_sphincssha2192fsimple", KEY_TYPE_HYB_SIG, NULL, 192, 19);
+}
+
+static void *p384_sphincssha2192fsimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_sha2_192f_simple, "p384_sphincssha2192fsimple", KEY_TYPE_HYB_SIG, 192, 19);
+}
+
+static void *sphincsshake128fsimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_shake_128f_simple, "sphincsshake128fsimple", KEY_TYPE_SIG, NULL, 128, 20);
+}
+
+static void *sphincsshake128fsimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_shake_128f_simple, "sphincsshake128fsimple", 0, 128, 20);
+}
+static void *p256_sphincsshake128fsimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_shake_128f_simple, "p256_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 21);
+}
+
+static void *p256_sphincsshake128fsimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_shake_128f_simple, "p256_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, 128, 21);
+}
+static void *rsa3072_sphincsshake128fsimple_new_key(void *provctx)
+{
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), OQS_SIG_alg_sphincs_shake_128f_simple, "rsa3072_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, NULL, 128, 22);
+}
+
+static void *rsa3072_sphincsshake128fsimple_gen_init(void *provctx, int selection)
+{
+ return oqsx_gen_init(provctx, selection, OQS_SIG_alg_sphincs_shake_128f_simple, "rsa3072_sphincsshake128fsimple", KEY_TYPE_HYB_SIG, 128, 22);
+}
+
+///// OQS_TEMPLATE_FRAGMENT_KEYMGMT_CONSTRUCTORS_END
+
+#define MAKE_SIG_KEYMGMT_FUNCTIONS(alg) \
+\
+ const OSSL_DISPATCH oqs_##alg##_keymgmt_functions[] = { \
+ { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))alg##_new_key }, \
+ { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))oqsx_key_free }, \
+ { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))oqsx_get_params }, \
+ { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))oqsx_settable_params }, \
+ { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))oqs_gettable_params }, \
+ { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))oqsx_set_params }, \
+ { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))oqsx_has }, \
+ { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))oqsx_match }, \
+ { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))oqsx_import }, \
+ { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))oqs_imexport_types }, \
+ { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))oqsx_export }, \
+ { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))oqs_imexport_types }, \
+ { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))alg##_gen_init }, \
+ { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))oqsx_gen }, \
+ { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))oqsx_gen_cleanup }, \
+ { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))oqsx_gen_set_params }, \
+ { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))oqsx_gen_settable_params }, \
+ { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))oqsx_load }, \
+ { 0, NULL } \
+ };
+
+#define MAKE_KEM_KEYMGMT_FUNCTIONS(tokalg, tokoqsalg, bit_security) \
+\
+ static void *tokalg##_new_key(void *provctx) \
+ { \
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), tokoqsalg, "" #tokalg "", KEY_TYPE_KEM, NULL, bit_security, -1); \
+ } \
+ \
+ static void *tokalg##_gen_init(void *provctx, int selection) \
+ { \
+ return oqsx_gen_init(provctx, selection, tokoqsalg, "" #tokalg "", KEY_TYPE_KEM, bit_security, -1); \
+ } \
+ \
+ const OSSL_DISPATCH oqs_##tokalg##_keymgmt_functions[] = { \
+ { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))tokalg##_new_key }, \
+ { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))oqsx_key_free }, \
+ { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))oqsx_get_params }, \
+ { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))oqsx_settable_params }, \
+ { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))oqs_gettable_params }, \
+ { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))oqsx_set_params }, \
+ { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))oqsx_has }, \
+ { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))oqsx_match }, \
+ { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))oqsx_import }, \
+ { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))oqs_imexport_types }, \
+ { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))oqsx_export }, \
+ { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))oqs_imexport_types }, \
+ { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))tokalg##_gen_init }, \
+ { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))oqsx_gen }, \
+ { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))oqsx_gen_cleanup }, \
+ { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))oqsx_gen_set_params }, \
+ { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))oqsx_gen_settable_params }, \
+ { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))oqsx_load }, \
+ { 0, NULL } \
+ };
+
+#define MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(tokalg, tokoqsalg, bit_security) \
+ \
+ static void *ecp_##tokalg##_new_key(void *provctx) \
+ { \
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), tokoqsalg, "" #tokalg "", KEY_TYPE_ECP_HYB_KEM, NULL, bit_security, -1); \
+ } \
+ \
+ static void *ecp_##tokalg##_gen_init(void *provctx, int selection) \
+ { \
+ return oqsx_gen_init(provctx, selection, tokoqsalg, "" #tokalg "", KEY_TYPE_ECP_HYB_KEM, bit_security, -1); \
+ } \
+ \
+ const OSSL_DISPATCH oqs_ecp_##tokalg##_keymgmt_functions[] = { \
+ { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ecp_##tokalg##_new_key }, \
+ { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))oqsx_key_free }, \
+ { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))oqsx_get_params }, \
+ { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))oqsx_settable_params }, \
+ { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))oqs_gettable_params }, \
+ { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))oqsx_set_params }, \
+ { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))oqsx_has }, \
+ { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))oqsx_match }, \
+ { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))oqsx_import }, \
+ { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))oqs_imexport_types }, \
+ { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))oqsx_export }, \
+ { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))oqs_imexport_types }, \
+ { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ecp_##tokalg##_gen_init }, \
+ { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))oqsx_gen }, \
+ { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))oqsx_gen_cleanup }, \
+ { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))oqsx_gen_set_params }, \
+ { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))oqsx_gen_settable_params }, \
+ { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))oqsx_load }, \
+ { 0, NULL } \
+ };
+
+#define MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(tokalg, tokoqsalg, bit_security) \
+ static void *ecx_##tokalg##_new_key(void *provctx) \
+ { \
+ return oqsx_key_new(PROV_OQS_LIBCTX_OF(provctx), tokoqsalg, "" #tokalg "", KEY_TYPE_ECX_HYB_KEM, NULL, bit_security, -1); \
+ } \
+ \
+ static void *ecx_##tokalg##_gen_init(void *provctx, int selection) \
+ { \
+ return oqsx_gen_init(provctx, selection, tokoqsalg, "" #tokalg "", KEY_TYPE_ECX_HYB_KEM, bit_security, -1); \
+ } \
+ \
+ const OSSL_DISPATCH oqs_ecx_##tokalg##_keymgmt_functions[] = { \
+ { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ecx_##tokalg##_new_key }, \
+ { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))oqsx_key_free }, \
+ { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))oqsx_get_params }, \
+ { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))oqsx_settable_params }, \
+ { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))oqs_gettable_params }, \
+ { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))oqsx_set_params }, \
+ { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))oqsx_has }, \
+ { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))oqsx_match }, \
+ { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))oqsx_import }, \
+ { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))oqs_imexport_types }, \
+ { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))oqsx_export }, \
+ { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))oqs_imexport_types }, \
+ { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))ecx_##tokalg##_gen_init }, \
+ { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))oqsx_gen }, \
+ { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))oqsx_gen_cleanup }, \
+ { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))oqsx_gen_set_params }, \
+ { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))oqsx_gen_settable_params }, \
+ { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))oqsx_load }, \
+ { 0, NULL } \
+ };
+
+///// OQS_TEMPLATE_FRAGMENT_KEYMGMT_FUNCTIONS_START
+MAKE_SIG_KEYMGMT_FUNCTIONS(dilithium2)
+MAKE_SIG_KEYMGMT_FUNCTIONS(p256_dilithium2)
+MAKE_SIG_KEYMGMT_FUNCTIONS(rsa3072_dilithium2)
+MAKE_SIG_KEYMGMT_FUNCTIONS(dilithium3)
+MAKE_SIG_KEYMGMT_FUNCTIONS(p384_dilithium3)
+MAKE_SIG_KEYMGMT_FUNCTIONS(dilithium5)
+MAKE_SIG_KEYMGMT_FUNCTIONS(p521_dilithium5)
+MAKE_SIG_KEYMGMT_FUNCTIONS(falcon512)
+MAKE_SIG_KEYMGMT_FUNCTIONS(p256_falcon512)
+MAKE_SIG_KEYMGMT_FUNCTIONS(rsa3072_falcon512)
+MAKE_SIG_KEYMGMT_FUNCTIONS(falcon1024)
+MAKE_SIG_KEYMGMT_FUNCTIONS(p521_falcon1024)
+MAKE_SIG_KEYMGMT_FUNCTIONS(sphincssha2128fsimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(p256_sphincssha2128fsimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(rsa3072_sphincssha2128fsimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(sphincssha2128ssimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(p256_sphincssha2128ssimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(rsa3072_sphincssha2128ssimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(sphincssha2192fsimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(p384_sphincssha2192fsimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(sphincsshake128fsimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(p256_sphincsshake128fsimple)
+MAKE_SIG_KEYMGMT_FUNCTIONS(rsa3072_sphincsshake128fsimple)
+
+MAKE_KEM_KEYMGMT_FUNCTIONS(frodo640aes, OQS_KEM_alg_frodokem_640_aes, 128)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p256_frodo640aes, OQS_KEM_alg_frodokem_640_aes, 128)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x25519_frodo640aes, OQS_KEM_alg_frodokem_640_aes, 128)
+MAKE_KEM_KEYMGMT_FUNCTIONS(frodo640shake, OQS_KEM_alg_frodokem_640_shake, 128)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p256_frodo640shake, OQS_KEM_alg_frodokem_640_shake, 128)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x25519_frodo640shake, OQS_KEM_alg_frodokem_640_shake, 128)
+MAKE_KEM_KEYMGMT_FUNCTIONS(frodo976aes, OQS_KEM_alg_frodokem_976_aes, 192)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p384_frodo976aes, OQS_KEM_alg_frodokem_976_aes, 192)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x448_frodo976aes, OQS_KEM_alg_frodokem_976_aes, 192)
+MAKE_KEM_KEYMGMT_FUNCTIONS(frodo976shake, OQS_KEM_alg_frodokem_976_shake, 192)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p384_frodo976shake, OQS_KEM_alg_frodokem_976_shake, 192)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x448_frodo976shake, OQS_KEM_alg_frodokem_976_shake, 192)
+MAKE_KEM_KEYMGMT_FUNCTIONS(frodo1344aes, OQS_KEM_alg_frodokem_1344_aes, 256)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p521_frodo1344aes, OQS_KEM_alg_frodokem_1344_aes, 256)
+MAKE_KEM_KEYMGMT_FUNCTIONS(frodo1344shake, OQS_KEM_alg_frodokem_1344_shake, 256)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p521_frodo1344shake, OQS_KEM_alg_frodokem_1344_shake, 256)
+MAKE_KEM_KEYMGMT_FUNCTIONS(kyber512, OQS_KEM_alg_kyber_512, 128)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p256_kyber512, OQS_KEM_alg_kyber_512, 128)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x25519_kyber512, OQS_KEM_alg_kyber_512, 128)
+MAKE_KEM_KEYMGMT_FUNCTIONS(kyber768, OQS_KEM_alg_kyber_768, 192)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p384_kyber768, OQS_KEM_alg_kyber_768, 192)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x448_kyber768, OQS_KEM_alg_kyber_768, 192)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x25519_kyber768, OQS_KEM_alg_kyber_768, 128)
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p256_kyber768, OQS_KEM_alg_kyber_768, 128)
+MAKE_KEM_KEYMGMT_FUNCTIONS(kyber1024, OQS_KEM_alg_kyber_1024, 256)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p521_kyber1024, OQS_KEM_alg_kyber_1024, 256)
+MAKE_KEM_KEYMGMT_FUNCTIONS(bikel1, OQS_KEM_alg_bike_l1, 128)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p256_bikel1, OQS_KEM_alg_bike_l1, 128)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x25519_bikel1, OQS_KEM_alg_bike_l1, 128)
+MAKE_KEM_KEYMGMT_FUNCTIONS(bikel3, OQS_KEM_alg_bike_l3, 192)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p384_bikel3, OQS_KEM_alg_bike_l3, 192)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x448_bikel3, OQS_KEM_alg_bike_l3, 192)
+MAKE_KEM_KEYMGMT_FUNCTIONS(bikel5, OQS_KEM_alg_bike_l5, 256)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p521_bikel5, OQS_KEM_alg_bike_l5, 256)
+MAKE_KEM_KEYMGMT_FUNCTIONS(hqc128, OQS_KEM_alg_hqc_128, 128)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p256_hqc128, OQS_KEM_alg_hqc_128, 128)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x25519_hqc128, OQS_KEM_alg_hqc_128, 128)
+MAKE_KEM_KEYMGMT_FUNCTIONS(hqc192, OQS_KEM_alg_hqc_192, 192)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p384_hqc192, OQS_KEM_alg_hqc_192, 192)
+
+MAKE_KEM_ECX_KEYMGMT_FUNCTIONS(x448_hqc192, OQS_KEM_alg_hqc_192, 192)
+MAKE_KEM_KEYMGMT_FUNCTIONS(hqc256, OQS_KEM_alg_hqc_256, 256)
+
+MAKE_KEM_ECP_KEYMGMT_FUNCTIONS(p521_hqc256, OQS_KEM_alg_hqc_256, 256)
+///// OQS_TEMPLATE_FRAGMENT_KEYMGMT_FUNCTIONS_END
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * Main oqsprovider header file
+ *
+ * Code strongly inspired by OpenSSL crypto/ecx key handler.
+ *
+ */
+
+/* Internal OQS functions for other submodules: not for application use */
+
+#ifndef OQSX_H
+# define OQSX_H
+
+#ifndef OQS_PROVIDER_NOATOMIC
+# include <stdatomic.h>
+#endif
+
+# include <openssl/opensslconf.h>
+# include <openssl/bio.h>
+
+# include <openssl/core.h>
+# include <openssl/e_os2.h>
+
+#define OQS_PROVIDER_VERSION_STR OQSPROVIDER_VERSION_TEXT
+
+/* internal, but useful OSSL define */
+# define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0]))
+
+#ifdef _MSC_VER
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#endif
+
+/* oqsprovider error codes */
+#define OQSPROV_R_INVALID_DIGEST 1
+#define OQSPROV_R_INVALID_SIZE 2
+#define OQSPROV_R_INVALID_KEY 3
+#define OQSPROV_R_UNSUPPORTED 4
+#define OQSPROV_R_MISSING_OID 5
+#define OQSPROV_R_OBJ_CREATE_ERR 6
+#define OQSPROV_R_INVALID_ENCODING 7
+#define OQSPROV_R_SIGN_ERROR 8
+#define OQSPROV_R_LIB_CREATE_ERR 9
+#define OQSPROV_R_NO_PRIVATE_KEY 10
+#define OQSPROV_R_BUFFER_LENGTH_WRONG 11
+#define OQSPROV_R_SIGNING_FAILED 12
+#define OQSPROV_R_WRONG_PARAMETERS 13
+#define OQSPROV_R_VERIFY_ERROR 14
+#define OQSPROV_R_EVPINFO_MISSING 15
+
+/* Extras for OQS extension */
+
+// Helpers for (classic) key length storage
+#define SIZE_OF_UINT32 4
+#define ENCODE_UINT32(pbuf, i) (pbuf)[0] = (unsigned char)((i>>24) & 0xff); \
+ (pbuf)[1] = (unsigned char)((i>>16) & 0xff); \
+ (pbuf)[2] = (unsigned char)((i>> 8) & 0xff); \
+ (pbuf)[3] = (unsigned char)((i ) & 0xff)
+#define DECODE_UINT32(i, pbuf) i = ((uint32_t) ((unsigned char*)pbuf)[0]) << 24; \
+ i |= ((uint32_t) ((unsigned char*)pbuf)[1]) << 16; \
+ i |= ((uint32_t) ((unsigned char*)pbuf)[2]) << 8; \
+ i |= ((uint32_t) ((unsigned char*)pbuf)[3])
+
+
+#define ON_ERR_SET_GOTO(condition, ret, code, gt) \
+ if ((condition)) { \
+ (ret) = (code); \
+ goto gt; \
+ }
+
+#define ON_ERR_GOTO(condition, gt) \
+ if ((condition)) { \
+ goto gt; \
+ }
+
+typedef struct prov_oqs_ctx_st {
+ const OSSL_CORE_HANDLE *handle;
+ OSSL_LIB_CTX *libctx; /* For all provider modules */
+ BIO_METHOD *corebiometh;
+} PROV_OQS_CTX;
+
+PROV_OQS_CTX *oqsx_newprovctx(OSSL_LIB_CTX *libctx, const OSSL_CORE_HANDLE *handle, BIO_METHOD *bm);
+void oqsx_freeprovctx(PROV_OQS_CTX *ctx);
+# define PROV_OQS_LIBCTX_OF(provctx) (((PROV_OQS_CTX *)provctx)->libctx)
+
+#include "oqs/oqs.h"
+#ifdef USE_ENCODING_LIB
+#include <qsc_encoding.h>
+#endif
+
+/* helper structure for classic key components in hybrid keys.
+ * Actual tables in oqsprov_keys.c
+ */
+struct oqsx_evp_info_st {
+ int keytype;
+ int nid;
+ int raw_key_support;
+ size_t length_public_key;
+ size_t length_private_key;
+ size_t kex_length_secret;
+ size_t length_signature;
+};
+
+typedef struct oqsx_evp_info_st OQSX_EVP_INFO;
+
+struct oqsx_evp_ctx_st {
+ EVP_PKEY_CTX *ctx;
+ EVP_PKEY *keyParam;
+ const OQSX_EVP_INFO *evp_info;
+};
+
+typedef struct oqsx_evp_ctx_st OQSX_EVP_CTX;
+
+typedef union {
+ OQS_SIG *sig;
+ OQS_KEM *kem;
+} OQSX_QS_CTX;
+
+struct oqsx_provider_ctx_st {
+ OQSX_QS_CTX oqsx_qs_ctx;
+ OQSX_EVP_CTX *oqsx_evp_ctx;
+};
+
+typedef struct oqsx_provider_ctx_st OQSX_PROVIDER_CTX;
+
+#ifdef USE_ENCODING_LIB
+struct oqsx_provider_encoding_ctx_st {
+ const qsc_encoding_t* encoding_ctx;
+ const qsc_encoding_impl_t* encoding_impl;
+};
+
+typedef struct oqsx_provider_encoding_ctx_st OQSX_ENCODING_CTX;
+#endif
+
+enum oqsx_key_type_en {
+ KEY_TYPE_SIG, KEY_TYPE_KEM, KEY_TYPE_ECP_HYB_KEM, KEY_TYPE_ECX_HYB_KEM, KEY_TYPE_HYB_SIG
+};
+
+typedef enum oqsx_key_type_en OQSX_KEY_TYPE;
+
+struct oqsx_key_st {
+ OSSL_LIB_CTX *libctx;
+#ifdef OQS_PROVIDER_NOATOMIC
+ CRYPTO_RWLOCK *lock;
+#endif
+ char *propq;
+ OQSX_KEY_TYPE keytype;
+ OQSX_PROVIDER_CTX oqsx_provider_ctx;
+#ifdef USE_ENCODING_LIB
+ OQSX_ENCODING_CTX oqsx_encoding_ctx;
+#endif
+ EVP_PKEY *classical_pkey; // for hybrid sigs
+ const OQSX_EVP_INFO *evp_info;
+ size_t numkeys;
+
+ /* key lengths including size fields for classic key length information: (numkeys-1)*SIZE_OF_UINT32
+ */
+ size_t privkeylen;
+ size_t pubkeylen;
+ size_t bit_security;
+ char *tls_name;
+#ifndef OQS_PROVIDER_NOATOMIC
+ _Atomic
+#endif
+ int references;
+
+ /* point to actual priv key material -- classic key, if present, first
+ * i.e., OQS key always at comp_*key[numkeys-1]
+ */
+ void **comp_privkey;
+ void **comp_pubkey;
+
+ /* contain key material: First SIZE_OF_UINT32 bytes indicating actual classic
+ * key length in case of hybrid keys (if numkeys>1)
+ */
+ void *privkey;
+ void *pubkey;
+};
+
+typedef struct oqsx_key_st OQSX_KEY;
+
+/* Register given NID with tlsname in OSSL3 registry */
+int oqs_set_nid(char* tlsname, int nid);
+
+/* Create OQSX_KEY data structure based on parameters; key material allocated separately */
+OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char* oqs_name, char* tls_name, int is_kem, const char *propq, int bit_security, int alg_idx);
+
+/* allocate key material; component pointers need to be set separately */
+int oqsx_key_allocate_keymaterial(OQSX_KEY *key, int include_private);
+
+/* free all data structures, incl. key material */
+void oqsx_key_free(OQSX_KEY *key);
+
+/* increase reference count of given key */
+int oqsx_key_up_ref(OQSX_KEY *key);
+
+/* do (composite) key generation */
+int oqsx_key_gen(OQSX_KEY *key);
+
+/* create OQSX_KEY from pkcs8 data structure */
+OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, OSSL_LIB_CTX *libctx, const char *propq);
+
+/* create OQSX_KEY (public key material only) from X509 data structure */
+OQSX_KEY *oqsx_key_from_x509pubkey(const X509_PUBKEY *xpk, OSSL_LIB_CTX *libctx, const char *propq);
+
+/* Backend support */
+/* populate key material from parameters */
+int oqsx_key_fromdata(OQSX_KEY *oqsxk, const OSSL_PARAM params[],
+ int include_private);
+/* retrieve security bit count for key */
+int oqsx_key_secbits(OQSX_KEY *k);
+/* retrieve pure OQS key len */
+int oqsx_key_get_oqs_public_key_len(OQSX_KEY *k);
+/* retrieve maximum size of generated artifact (shared secret or signature, respectively) */
+int oqsx_key_maxsize(OQSX_KEY *k);
+void oqsx_key_set0_libctx(OQSX_KEY *key, OSSL_LIB_CTX *libctx);
+int oqs_patch_codepoints(void);
+
+/* Function prototypes */
+
+extern const OSSL_DISPATCH oqs_generic_kem_functions[];
+extern const OSSL_DISPATCH oqs_hybrid_kem_functions[];
+extern const OSSL_DISPATCH oqs_signature_functions[];
+
+///// OQS_TEMPLATE_FRAGMENT_ENDECODER_FUNCTIONS_START
+extern const OSSL_DISPATCH oqs_dilithium2_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium2_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium2_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium2_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium2_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium2_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium2_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_dilithium2_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_dilithium2_decoder_functions[];extern const OSSL_DISPATCH oqs_p256_dilithium2_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_dilithium2_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_dilithium2_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_dilithium2_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_dilithium2_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_dilithium2_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_dilithium2_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p256_dilithium2_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p256_dilithium2_decoder_functions[];extern const OSSL_DISPATCH oqs_rsa3072_dilithium2_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_dilithium2_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_dilithium2_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_dilithium2_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_dilithium2_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_dilithium2_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_dilithium2_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_rsa3072_dilithium2_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_rsa3072_dilithium2_decoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium3_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium3_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium3_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium3_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium3_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium3_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium3_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_dilithium3_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_dilithium3_decoder_functions[];extern const OSSL_DISPATCH oqs_p384_dilithium3_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_dilithium3_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_dilithium3_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_dilithium3_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_dilithium3_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_dilithium3_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_dilithium3_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p384_dilithium3_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p384_dilithium3_decoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium5_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium5_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium5_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium5_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium5_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium5_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_dilithium5_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_dilithium5_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_dilithium5_decoder_functions[];extern const OSSL_DISPATCH oqs_p521_dilithium5_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_dilithium5_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_dilithium5_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_dilithium5_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_dilithium5_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_dilithium5_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_dilithium5_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p521_dilithium5_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p521_dilithium5_decoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon512_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon512_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon512_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon512_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon512_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon512_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_falcon512_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_falcon512_decoder_functions[];extern const OSSL_DISPATCH oqs_p256_falcon512_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_falcon512_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_falcon512_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_falcon512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_falcon512_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_falcon512_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_falcon512_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p256_falcon512_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p256_falcon512_decoder_functions[];extern const OSSL_DISPATCH oqs_rsa3072_falcon512_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_falcon512_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_falcon512_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_falcon512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_falcon512_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_falcon512_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_falcon512_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_rsa3072_falcon512_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_rsa3072_falcon512_decoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon1024_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon1024_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon1024_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon1024_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon1024_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon1024_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_falcon1024_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_falcon1024_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_falcon1024_decoder_functions[];extern const OSSL_DISPATCH oqs_p521_falcon1024_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_falcon1024_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_falcon1024_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_falcon1024_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_falcon1024_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_falcon1024_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p521_falcon1024_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p521_falcon1024_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p521_falcon1024_decoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128fsimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128fsimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128fsimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128fsimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128fsimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128fsimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128fsimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_sphincssha2128fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_sphincssha2128fsimple_decoder_functions[];extern const OSSL_DISPATCH oqs_p256_sphincssha2128fsimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128fsimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128fsimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128fsimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128fsimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128fsimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128fsimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p256_sphincssha2128fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p256_sphincssha2128fsimple_decoder_functions[];extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128fsimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128fsimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128fsimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128fsimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128fsimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128fsimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128fsimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_rsa3072_sphincssha2128fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_rsa3072_sphincssha2128fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128ssimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128ssimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128ssimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128ssimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128ssimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128ssimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128ssimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_sphincssha2128ssimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_sphincssha2128ssimple_decoder_functions[];extern const OSSL_DISPATCH oqs_p256_sphincssha2128ssimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128ssimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128ssimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128ssimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128ssimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128ssimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincssha2128ssimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p256_sphincssha2128ssimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p256_sphincssha2128ssimple_decoder_functions[];extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128ssimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128ssimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128ssimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128ssimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128ssimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128ssimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128ssimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_rsa3072_sphincssha2128ssimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_rsa3072_sphincssha2128ssimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2192fsimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2192fsimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2192fsimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2192fsimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2192fsimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2192fsimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2192fsimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_sphincssha2192fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_sphincssha2192fsimple_decoder_functions[];extern const OSSL_DISPATCH oqs_p384_sphincssha2192fsimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_sphincssha2192fsimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_sphincssha2192fsimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_sphincssha2192fsimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_sphincssha2192fsimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_sphincssha2192fsimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p384_sphincssha2192fsimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p384_sphincssha2192fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p384_sphincssha2192fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincsshake128fsimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincsshake128fsimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincsshake128fsimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincsshake128fsimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincsshake128fsimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincsshake128fsimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_sphincsshake128fsimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_sphincsshake128fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_sphincsshake128fsimple_decoder_functions[];extern const OSSL_DISPATCH oqs_p256_sphincsshake128fsimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincsshake128fsimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincsshake128fsimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincsshake128fsimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincsshake128fsimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincsshake128fsimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_p256_sphincsshake128fsimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_p256_sphincsshake128fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_p256_sphincsshake128fsimple_decoder_functions[];extern const OSSL_DISPATCH oqs_rsa3072_sphincsshake128fsimple_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincsshake128fsimple_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincsshake128fsimple_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincsshake128fsimple_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincsshake128fsimple_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincsshake128fsimple_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH oqs_rsa3072_sphincsshake128fsimple_to_text_encoder_functions[];
+extern const OSSL_DISPATCH oqs_PrivateKeyInfo_der_to_rsa3072_sphincsshake128fsimple_decoder_functions[];
+extern const OSSL_DISPATCH oqs_SubjectPublicKeyInfo_der_to_rsa3072_sphincsshake128fsimple_decoder_functions[];
+///// OQS_TEMPLATE_FRAGMENT_ENDECODER_FUNCTIONS_END
+
+///// OQS_TEMPLATE_FRAGMENT_ALG_FUNCTIONS_START
+extern const OSSL_DISPATCH oqs_dilithium2_keymgmt_functions[];extern const OSSL_DISPATCH oqs_p256_dilithium2_keymgmt_functions[];extern const OSSL_DISPATCH oqs_rsa3072_dilithium2_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_dilithium3_keymgmt_functions[];extern const OSSL_DISPATCH oqs_p384_dilithium3_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_dilithium5_keymgmt_functions[];extern const OSSL_DISPATCH oqs_p521_dilithium5_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_falcon512_keymgmt_functions[];extern const OSSL_DISPATCH oqs_p256_falcon512_keymgmt_functions[];extern const OSSL_DISPATCH oqs_rsa3072_falcon512_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_falcon1024_keymgmt_functions[];extern const OSSL_DISPATCH oqs_p521_falcon1024_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128fsimple_keymgmt_functions[];extern const OSSL_DISPATCH oqs_p256_sphincssha2128fsimple_keymgmt_functions[];extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128fsimple_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2128ssimple_keymgmt_functions[];extern const OSSL_DISPATCH oqs_p256_sphincssha2128ssimple_keymgmt_functions[];extern const OSSL_DISPATCH oqs_rsa3072_sphincssha2128ssimple_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_sphincssha2192fsimple_keymgmt_functions[];extern const OSSL_DISPATCH oqs_p384_sphincssha2192fsimple_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_sphincsshake128fsimple_keymgmt_functions[];extern const OSSL_DISPATCH oqs_p256_sphincsshake128fsimple_keymgmt_functions[];extern const OSSL_DISPATCH oqs_rsa3072_sphincsshake128fsimple_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_frodo640aes_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p256_frodo640aes_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x25519_frodo640aes_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_frodo640shake_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p256_frodo640shake_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x25519_frodo640shake_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_frodo976aes_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p384_frodo976aes_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x448_frodo976aes_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_frodo976shake_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p384_frodo976shake_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x448_frodo976shake_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_frodo1344aes_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p521_frodo1344aes_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_frodo1344shake_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p521_frodo1344shake_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_kyber512_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p256_kyber512_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x25519_kyber512_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_kyber768_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p384_kyber768_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x448_kyber768_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x25519_kyber768_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecp_p256_kyber768_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_kyber1024_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p521_kyber1024_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_bikel1_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p256_bikel1_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x25519_bikel1_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_bikel3_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p384_bikel3_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x448_bikel3_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_bikel5_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p521_bikel5_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_hqc128_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p256_hqc128_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x25519_hqc128_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_hqc192_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p384_hqc192_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_ecx_x448_hqc192_keymgmt_functions[];
+extern const OSSL_DISPATCH oqs_hqc256_keymgmt_functions[];
+
+extern const OSSL_DISPATCH oqs_ecp_p521_hqc256_keymgmt_functions[];
+///// OQS_TEMPLATE_FRAGMENT_ALG_FUNCTIONS_END
+
+/* BIO function declarations */
+int oqs_prov_bio_from_dispatch(const OSSL_DISPATCH *fns);
+
+OSSL_CORE_BIO *oqs_prov_bio_new_file(const char *filename, const char *mode);
+OSSL_CORE_BIO *oqs_prov_bio_new_membuf(const char *filename, int len);
+int oqs_prov_bio_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len,
+ size_t *bytes_read);
+int oqs_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len,
+ size_t *written);
+int oqs_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size);
+int oqs_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str);
+int oqs_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr);
+int oqs_prov_bio_up_ref(OSSL_CORE_BIO *bio);
+int oqs_prov_bio_free(OSSL_CORE_BIO *bio);
+int oqs_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap);
+int oqs_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...);
+
+BIO_METHOD *oqs_bio_prov_init_bio_method(void);
+BIO *oqs_bio_new_from_core_bio(PROV_OQS_CTX *provctx, OSSL_CORE_BIO *corebio);
+
+#endif
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider
+ *
+ * Code strongly inspired by OpenSSL DSA signature provider.
+ *
+ */
+
+#include "oqs/sig.h"
+
+#include <string.h>
+
+#include <openssl/asn1.h>
+#include <openssl/crypto.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/err.h>
+#include <openssl/params.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include "oqs_prov.h"
+
+// TBD: Review what we really need/want: For now go with OSSL settings:
+#define OSSL_MAX_NAME_SIZE 50
+#define OSSL_MAX_PROPQUERY_SIZE 256 /* Property query strings */
+
+#ifdef NDEBUG
+#define OQS_SIG_PRINTF(a)
+#define OQS_SIG_PRINTF2(a, b)
+#define OQS_SIG_PRINTF3(a, b, c)
+#else
+#define OQS_SIG_PRINTF(a) if (getenv("OQSSIG")) printf(a)
+#define OQS_SIG_PRINTF2(a, b) if (getenv("OQSSIG")) printf(a, b)
+#define OQS_SIG_PRINTF3(a, b, c) if (getenv("OQSSIG")) printf(a, b, c)
+#endif // NDEBUG
+
+static OSSL_FUNC_signature_newctx_fn oqs_sig_newctx;
+static OSSL_FUNC_signature_sign_init_fn oqs_sig_sign_init;
+static OSSL_FUNC_signature_verify_init_fn oqs_sig_verify_init;
+static OSSL_FUNC_signature_sign_fn oqs_sig_sign;
+static OSSL_FUNC_signature_verify_fn oqs_sig_verify;
+static OSSL_FUNC_signature_digest_sign_init_fn oqs_sig_digest_sign_init;
+static OSSL_FUNC_signature_digest_sign_update_fn oqs_sig_digest_signverify_update;
+static OSSL_FUNC_signature_digest_sign_final_fn oqs_sig_digest_sign_final;
+static OSSL_FUNC_signature_digest_verify_init_fn oqs_sig_digest_verify_init;
+static OSSL_FUNC_signature_digest_verify_update_fn oqs_sig_digest_signverify_update;
+static OSSL_FUNC_signature_digest_verify_final_fn oqs_sig_digest_verify_final;
+static OSSL_FUNC_signature_freectx_fn oqs_sig_freectx;
+static OSSL_FUNC_signature_dupctx_fn oqs_sig_dupctx;
+static OSSL_FUNC_signature_get_ctx_params_fn oqs_sig_get_ctx_params;
+static OSSL_FUNC_signature_gettable_ctx_params_fn oqs_sig_gettable_ctx_params;
+static OSSL_FUNC_signature_set_ctx_params_fn oqs_sig_set_ctx_params;
+static OSSL_FUNC_signature_settable_ctx_params_fn oqs_sig_settable_ctx_params;
+static OSSL_FUNC_signature_get_ctx_md_params_fn oqs_sig_get_ctx_md_params;
+static OSSL_FUNC_signature_gettable_ctx_md_params_fn oqs_sig_gettable_ctx_md_params;
+static OSSL_FUNC_signature_set_ctx_md_params_fn oqs_sig_set_ctx_md_params;
+static OSSL_FUNC_signature_settable_ctx_md_params_fn oqs_sig_settable_ctx_md_params;
+
+// OIDS:
+static int get_aid(unsigned char** oidbuf, const char *tls_name) {
+ X509_ALGOR *algor = X509_ALGOR_new();
+ int aidlen = 0;
+
+ X509_ALGOR_set0(algor, OBJ_txt2obj(tls_name, 0), V_ASN1_UNDEF, NULL);
+
+ aidlen = i2d_X509_ALGOR(algor, oidbuf);
+ X509_ALGOR_free(algor);
+ return(aidlen);
+}
+
+/*
+ * What's passed as an actual key is defined by the KEYMGMT interface.
+ */
+
+typedef struct {
+ OSSL_LIB_CTX *libctx;
+ char *propq;
+ OQSX_KEY *sig;
+
+ /*
+ * Flag to determine if the hash function can be changed (1) or not (0)
+ * Because it's dangerous to change during a DigestSign or DigestVerify
+ * operation, this flag is cleared by their Init function, and set again
+ * by their Final function.
+ */
+ unsigned int flag_allow_md : 1;
+
+ char mdname[OSSL_MAX_NAME_SIZE];
+
+ /* The Algorithm Identifier of the combined signature algorithm */
+ unsigned char *aid;
+ size_t aid_len;
+
+ /* main digest */
+ EVP_MD *md;
+ EVP_MD_CTX *mdctx;
+ size_t mdsize;
+ // for collecting data if no MD is active:
+ unsigned char* mddata;
+ int operation;
+} PROV_OQSSIG_CTX;
+
+static void *oqs_sig_newctx(void *provctx, const char *propq)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx;
+
+ OQS_SIG_PRINTF2("OQS SIG provider: newctx called with propq %s\n", propq);
+
+ poqs_sigctx = OPENSSL_zalloc(sizeof(PROV_OQSSIG_CTX));
+ if (poqs_sigctx == NULL)
+ return NULL;
+
+ poqs_sigctx->libctx = ((PROV_OQS_CTX*)provctx)->libctx;
+ if (propq != NULL && (poqs_sigctx->propq = OPENSSL_strdup(propq)) == NULL) {
+ OPENSSL_free(poqs_sigctx);
+ poqs_sigctx = NULL;
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ }
+ return poqs_sigctx;
+}
+
+static int oqs_sig_setup_md(PROV_OQSSIG_CTX *ctx,
+ const char *mdname, const char *mdprops)
+{
+ OQS_SIG_PRINTF3("OQS SIG provider: setup_md called for MD %s (alg %s)\n", mdname, ctx->sig->tls_name);
+ if (mdprops == NULL)
+ mdprops = ctx->propq;
+
+ if (mdname != NULL) {
+ EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
+
+ if ((md == NULL)||(EVP_MD_nid(md)==NID_undef)) {
+ if (md == NULL)
+ ERR_raise_data(ERR_LIB_USER, OQSPROV_R_INVALID_DIGEST,
+ "%s could not be fetched", mdname);
+ EVP_MD_free(md);
+ return 0;
+ }
+
+ EVP_MD_CTX_free(ctx->mdctx);
+ ctx->mdctx = NULL;
+ EVP_MD_free(ctx->md);
+ ctx->md = NULL;
+
+ if (ctx->aid)
+ OPENSSL_free(ctx->aid);
+ ctx->aid = NULL; // ensure next function allocates memory
+ ctx->aid_len = get_aid(&(ctx->aid), ctx->sig->tls_name);
+
+ ctx->md = md;
+ OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname));
+ }
+ return 1;
+}
+
+static int oqs_sig_signverify_init(void *vpoqs_sigctx, void *voqssig, int operation)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+
+ OQS_SIG_PRINTF("OQS SIG provider: signverify_init called\n");
+ if ( poqs_sigctx == NULL
+ || voqssig == NULL
+ || !oqsx_key_up_ref(voqssig))
+ return 0;
+ oqsx_key_free(poqs_sigctx->sig);
+ poqs_sigctx->sig = voqssig;
+ poqs_sigctx->operation = operation;
+ poqs_sigctx->flag_allow_md = 1; /* change permitted until first use */
+ if ( (operation==EVP_PKEY_OP_SIGN && !poqs_sigctx->sig->privkey) ||
+ (operation==EVP_PKEY_OP_VERIFY && !poqs_sigctx->sig->pubkey)) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_KEY);
+ return 0;
+ }
+ return 1;
+}
+
+static int oqs_sig_sign_init(void *vpoqs_sigctx, void *voqssig, const OSSL_PARAM params[])
+{
+ OQS_SIG_PRINTF("OQS SIG provider: sign_init called\n");
+ return oqs_sig_signverify_init(vpoqs_sigctx, voqssig, EVP_PKEY_OP_SIGN);
+}
+
+static int oqs_sig_verify_init(void *vpoqs_sigctx, void *voqssig, const OSSL_PARAM params[])
+{
+ OQS_SIG_PRINTF("OQS SIG provider: verify_init called\n");
+ return oqs_sig_signverify_init(vpoqs_sigctx, voqssig, EVP_PKEY_OP_VERIFY);
+}
+
+/* On entry to this function, data to be signed (tbs) might have been hashed already:
+ * this would be the case if poqs_sigctx->mdctx != NULL; if that is NULL, we have to hash
+ * in case of hybrid signatures
+ */
+static int oqs_sig_sign(void *vpoqs_sigctx, unsigned char *sig, size_t *siglen,
+ size_t sigsize, const unsigned char *tbs, size_t tbslen)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+ OQSX_KEY* oqsxkey = poqs_sigctx->sig;
+ OQS_SIG* oqs_key = poqs_sigctx->sig->oqsx_provider_ctx.oqsx_qs_ctx.sig;
+ EVP_PKEY* evpkey = oqsxkey->classical_pkey; // if this value is not NULL, we're running hybrid
+ EVP_PKEY_CTX *classical_ctx_sign = NULL;
+
+ OQS_SIG_PRINTF2("OQS SIG provider: sign called for %ld bytes\n", tbslen);
+
+ int is_hybrid = evpkey!=NULL;
+ size_t max_sig_len = oqs_key->length_signature;
+ size_t classical_sig_len = 0, oqs_sig_len = 0;
+ size_t actual_classical_sig_len = 0;
+ size_t index = 0;
+ int rv = 0;
+
+ if (!oqsxkey || !oqs_key || !oqsxkey->privkey) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_NO_PRIVATE_KEY);
+ return rv;
+ }
+ if (is_hybrid) {
+ actual_classical_sig_len = oqsxkey->evp_info->length_signature;
+ max_sig_len += (SIZE_OF_UINT32 + actual_classical_sig_len);
+ }
+
+ if (sig == NULL) {
+ *siglen = max_sig_len;
+ OQS_SIG_PRINTF2("OQS SIG provider: sign test returning size %ld\n", *siglen);
+ return 1;
+ }
+ if (*siglen < max_sig_len) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_BUFFER_LENGTH_WRONG);
+ return rv;
+ }
+
+ if (is_hybrid) {
+ if ((classical_ctx_sign = EVP_PKEY_CTX_new(evpkey, NULL)) == NULL ||
+ EVP_PKEY_sign_init(classical_ctx_sign) <= 0) {
+ ERR_raise(ERR_LIB_USER, ERR_R_FATAL);
+ goto endsign;
+ }
+ if (oqsxkey->evp_info->keytype == EVP_PKEY_RSA) {
+ if (EVP_PKEY_CTX_set_rsa_padding(classical_ctx_sign, RSA_PKCS1_PADDING) <= 0) {
+ ERR_raise(ERR_LIB_USER, ERR_R_FATAL);
+ goto endsign;
+ }
+ }
+
+ /* unconditionally hash to be in line with oqs-openssl111:
+ * uncomment the following line if using pre-performed hash:
+ * if (poqs_sigctx->mdctx == NULL) { // hashing not yet done
+ */
+ const EVP_MD *classical_md;
+ int digest_len;
+ unsigned char digest[SHA512_DIGEST_LENGTH]; /* init with max length */
+
+ /* classical schemes can't sign arbitrarily large data; we hash it first */
+ switch (oqs_key->claimed_nist_level) {
+ case 1:
+ classical_md = EVP_sha256();
+ digest_len = SHA256_DIGEST_LENGTH;
+ SHA256(tbs, tbslen, (unsigned char*) &digest);
+ break;
+ case 2:
+ case 3:
+ classical_md = EVP_sha384();
+ digest_len = SHA384_DIGEST_LENGTH;
+ SHA384(tbs, tbslen, (unsigned char*) &digest);
+ break;
+ case 4:
+ case 5:
+ default:
+ classical_md = EVP_sha512();
+ digest_len = SHA512_DIGEST_LENGTH;
+ SHA512(tbs, tbslen, (unsigned char*) &digest);
+ break;
+ }
+ if ((EVP_PKEY_CTX_set_signature_md(classical_ctx_sign, classical_md) <= 0) ||
+ (EVP_PKEY_sign(classical_ctx_sign, sig + SIZE_OF_UINT32, &actual_classical_sig_len, digest, digest_len) <= 0)) {
+ ERR_raise(ERR_LIB_USER, ERR_R_FATAL);
+ goto endsign;
+ }
+ /* activate in case we want to use pre-performed hashes:
+ * }
+ * else { // hashing done before; just sign:
+ * if (EVP_PKEY_sign(classical_ctx_sign, sig + SIZE_OF_UINT32, &actual_classical_sig_len, tbs, tbslen) <= 0) {
+ * ERR_raise(ERR_LIB_USER, OQSPROV_R_SIGNING_FAILED);
+ * goto endsign;
+ * }
+ * }
+ */
+ if (actual_classical_sig_len > oqsxkey->evp_info->length_signature) {
+ /* sig is bigger than expected */
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_BUFFER_LENGTH_WRONG);
+ goto endsign;
+ }
+ ENCODE_UINT32(sig, actual_classical_sig_len);
+ classical_sig_len = SIZE_OF_UINT32 + actual_classical_sig_len;
+ index += classical_sig_len;
+ }
+
+ if (OQS_SIG_sign(oqs_key, sig + index, &oqs_sig_len, tbs, tbslen, oqsxkey->comp_privkey[oqsxkey->numkeys-1]) != OQS_SUCCESS) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_SIGNING_FAILED);
+ goto endsign;
+ }
+ *siglen = classical_sig_len + oqs_sig_len;
+ OQS_SIG_PRINTF2("OQS SIG provider: signing completes with size %ld\n", *siglen);
+ rv = 1; /* success */
+
+ endsign:
+ if (classical_ctx_sign) {
+ EVP_PKEY_CTX_free(classical_ctx_sign);
+ }
+ return rv;
+}
+
+static int oqs_sig_verify(void *vpoqs_sigctx, const unsigned char *sig, size_t siglen,
+ const unsigned char *tbs, size_t tbslen)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+ OQSX_KEY* oqsxkey = poqs_sigctx->sig;
+ OQS_SIG* oqs_key = poqs_sigctx->sig->oqsx_provider_ctx.oqsx_qs_ctx.sig;
+ EVP_PKEY* evpkey = oqsxkey->classical_pkey; // if this value is not NULL, we're running hybrid
+ EVP_PKEY_CTX *classical_ctx_sign = NULL;
+ EVP_PKEY_CTX *ctx_verify = NULL;
+ int is_hybrid = evpkey!=NULL;
+ size_t classical_sig_len = 0;
+ size_t index = 0;
+ int rv = 0;
+
+ OQS_SIG_PRINTF3("OQS SIG provider: verify called with siglen %ld bytes and tbslen %ld\n", siglen, tbslen);
+
+ if (!oqsxkey || !oqs_key || !oqsxkey->pubkey || sig == NULL || (tbs == NULL && tbslen > 0)) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS);
+ goto endverify;
+ }
+
+ if (is_hybrid) {
+ const EVP_MD *classical_md;
+ size_t actual_classical_sig_len = 0;
+ int digest_len;
+ unsigned char digest[SHA512_DIGEST_LENGTH]; /* init with max length */
+
+ if ((ctx_verify = EVP_PKEY_CTX_new(oqsxkey->classical_pkey, NULL)) == NULL ||
+ EVP_PKEY_verify_init(ctx_verify) <= 0) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR);
+ goto endverify;
+ }
+ if (oqsxkey->evp_info->keytype == EVP_PKEY_RSA) {
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx_verify, RSA_PKCS1_PADDING) <= 0) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS);
+ goto endverify;
+ }
+ }
+ DECODE_UINT32(actual_classical_sig_len, sig);
+
+ /* same as with sign: activate if pre-existing hashing to be used:
+ * if (poqs_sigctx->mdctx == NULL) { // hashing not yet done
+ */
+ switch (oqs_key->claimed_nist_level) {
+ case 1:
+ classical_md = EVP_sha256();
+ digest_len = SHA256_DIGEST_LENGTH;
+ SHA256(tbs, tbslen, (unsigned char*) &digest);
+ break;
+ case 2:
+ case 3:
+ classical_md = EVP_sha384();
+ digest_len = SHA384_DIGEST_LENGTH;
+ SHA384(tbs, tbslen, (unsigned char*) &digest);
+ break;
+ case 4:
+ case 5:
+ default:
+ classical_md = EVP_sha512();
+ digest_len = SHA512_DIGEST_LENGTH;
+ SHA512(tbs, tbslen, (unsigned char*) &digest);
+ break;
+ }
+ if ((EVP_PKEY_CTX_set_signature_md(ctx_verify, classical_md) <= 0) ||
+ (EVP_PKEY_verify(ctx_verify, sig + SIZE_OF_UINT32, actual_classical_sig_len, digest, digest_len) <= 0)) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR);
+ goto endverify;
+ }
+ else {
+ OQS_SIG_PRINTF("OQS SIG: classic verification OK\n");
+ }
+ /* activate for using pre-existing digest:
+ * }
+ * else { // hashing already done:
+ * if (EVP_PKEY_verify(ctx_verify, sig + SIZE_OF_UINT32, actual_classical_sig_len, tbs, tbslen) <= 0) {
+ * ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR);
+ * goto endverify;
+ * }
+ * }
+ */
+ classical_sig_len = SIZE_OF_UINT32 + actual_classical_sig_len;
+ index += classical_sig_len;
+ }
+
+ if (!oqsxkey->comp_pubkey[oqsxkey->numkeys-1]) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS);
+ goto endverify;
+ }
+ if (OQS_SIG_verify(oqs_key, tbs, tbslen, sig + index, siglen - classical_sig_len, oqsxkey->comp_pubkey[oqsxkey->numkeys-1]) != OQS_SUCCESS) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_VERIFY_ERROR);
+ goto endverify;
+ }
+ rv = 1;
+
+ endverify:
+ if (ctx_verify) {
+ EVP_PKEY_CTX_free(ctx_verify);
+ }
+ OQS_SIG_PRINTF2("OQS SIG provider: verify rv = %d\n", rv);
+ return rv;
+}
+
+static int oqs_sig_digest_signverify_init(void *vpoqs_sigctx, const char *mdname,
+ void *voqssig, int operation)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+
+ OQS_SIG_PRINTF2("OQS SIG provider: digest_signverify_init called for mdname %s\n", mdname);
+
+ poqs_sigctx->flag_allow_md = 1; /* permitted until first use */
+ if (!oqs_sig_signverify_init(vpoqs_sigctx, voqssig, operation))
+ return 0;
+
+ if (!oqs_sig_setup_md(poqs_sigctx, mdname, NULL))
+ return 0;
+
+ if (mdname != NULL) {
+ poqs_sigctx->mdctx = EVP_MD_CTX_new();
+ if (poqs_sigctx->mdctx == NULL)
+ goto error;
+
+ if (!EVP_DigestInit_ex(poqs_sigctx->mdctx, poqs_sigctx->md, NULL))
+ goto error;
+ }
+
+ return 1;
+
+ error:
+ EVP_MD_CTX_free(poqs_sigctx->mdctx);
+ EVP_MD_free(poqs_sigctx->md);
+ poqs_sigctx->mdctx = NULL;
+ poqs_sigctx->md = NULL;
+ OQS_SIG_PRINTF(" OQS SIG provider: digest_signverify FAILED\n");
+ return 0;
+}
+
+static int oqs_sig_digest_sign_init(void *vpoqs_sigctx, const char *mdname,
+ void *voqssig, const OSSL_PARAM params[])
+{
+ OQS_SIG_PRINTF("OQS SIG provider: digest_sign_init called\n");
+ return oqs_sig_digest_signverify_init(vpoqs_sigctx, mdname, voqssig, EVP_PKEY_OP_SIGN);
+}
+
+static int oqs_sig_digest_verify_init(void *vpoqs_sigctx, const char *mdname, void *voqssig, const OSSL_PARAM params[])
+{
+ OQS_SIG_PRINTF("OQS SIG provider: sig_digest_verify called\n");
+ return oqs_sig_digest_signverify_init(vpoqs_sigctx, mdname, voqssig, EVP_PKEY_OP_VERIFY);
+}
+
+int oqs_sig_digest_signverify_update(void *vpoqs_sigctx, const unsigned char *data,
+ size_t datalen)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+
+ OQS_SIG_PRINTF("OQS SIG provider: digest_signverify_update called\n");
+
+ if (poqs_sigctx == NULL)
+ return 0;
+ // disallow MD changes after update has been called at least once
+ poqs_sigctx->flag_allow_md = 0;
+
+ if (poqs_sigctx->mdctx)
+ return EVP_DigestUpdate(poqs_sigctx->mdctx, data, datalen);
+ else {
+ // unconditionally collect data for passing in full to OQS API
+ if (poqs_sigctx->mddata) {
+ unsigned char* newdata = OPENSSL_realloc(poqs_sigctx->mddata, poqs_sigctx->mdsize+datalen);
+ if (newdata == NULL) return 0;
+ memcpy(newdata+poqs_sigctx->mdsize, data, datalen);
+ poqs_sigctx->mddata = newdata;
+ poqs_sigctx->mdsize += datalen;
+ }
+ else { // simple alloc and copy
+ poqs_sigctx->mddata = OPENSSL_malloc(datalen);
+ if (poqs_sigctx->mddata == NULL) return 0;
+ poqs_sigctx->mdsize=datalen;
+ memcpy(poqs_sigctx->mddata, data, poqs_sigctx->mdsize);
+ }
+ OQS_SIG_PRINTF2("OQS SIG provider: digest_signverify_update collected %ld bytes...\n", poqs_sigctx->mdsize);
+ }
+ return 1;
+}
+
+int oqs_sig_digest_sign_final(void *vpoqs_sigctx, unsigned char *sig, size_t *siglen,
+ size_t sigsize)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ unsigned int dlen = 0;
+
+ OQS_SIG_PRINTF("OQS SIG provider: digest_sign_final called\n");
+ if (poqs_sigctx == NULL)
+ return 0;
+
+ /*
+ * If sig is NULL then we're just finding out the sig size. Other fields
+ * are ignored. Defer to oqs_sig_sign.
+ */
+ if (sig != NULL) {
+ /*
+ * TODO(3.0): There is the possibility that some externally provided
+ * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow -
+ * but that problem is much larger than just here.
+ */
+ if (poqs_sigctx->mdctx != NULL)
+ if (!EVP_DigestFinal_ex(poqs_sigctx->mdctx, digest, &dlen))
+ return 0;
+ }
+
+ poqs_sigctx->flag_allow_md = 1;
+
+ if (poqs_sigctx->mdctx != NULL)
+ return oqs_sig_sign(vpoqs_sigctx, sig, siglen, sigsize, digest, (size_t)dlen);
+ else
+ return oqs_sig_sign(vpoqs_sigctx, sig, siglen, sigsize, poqs_sigctx->mddata, poqs_sigctx->mdsize);
+
+}
+
+
+int oqs_sig_digest_verify_final(void *vpoqs_sigctx, const unsigned char *sig,
+ size_t siglen)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ unsigned int dlen = 0;
+
+ OQS_SIG_PRINTF("OQS SIG provider: digest_verify_final called\n");
+ if (poqs_sigctx == NULL)
+ return 0;
+
+ // TBC for hybrids:
+ if (poqs_sigctx->mdctx) {
+ if (!EVP_DigestFinal_ex(poqs_sigctx->mdctx, digest, &dlen))
+ return 0;
+
+ poqs_sigctx->flag_allow_md = 1;
+
+ return oqs_sig_verify(vpoqs_sigctx, sig, siglen, digest, (size_t)dlen);
+ }
+ else
+ return oqs_sig_verify(vpoqs_sigctx, sig, siglen, poqs_sigctx->mddata, poqs_sigctx->mdsize);
+}
+
+static void oqs_sig_freectx(void *vpoqs_sigctx)
+{
+ PROV_OQSSIG_CTX *ctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+
+ OQS_SIG_PRINTF("OQS SIG provider: freectx called\n");
+ OPENSSL_free(ctx->propq);
+ EVP_MD_CTX_free(ctx->mdctx);
+ EVP_MD_free(ctx->md);
+ ctx->propq = NULL;
+ ctx->mdctx = NULL;
+ ctx->md = NULL;
+ oqsx_key_free(ctx->sig);
+ OPENSSL_free(ctx->mddata);
+ ctx->mddata = NULL;
+ ctx->mdsize = 0;
+ OPENSSL_free(ctx->aid);
+ ctx->aid = NULL;
+ ctx->aid_len = 0;
+ OPENSSL_free(ctx);
+}
+
+static void *oqs_sig_dupctx(void *vpoqs_sigctx)
+{
+ PROV_OQSSIG_CTX *srcctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+ PROV_OQSSIG_CTX *dstctx;
+
+ OQS_SIG_PRINTF("OQS SIG provider: dupctx called\n");
+
+ dstctx = OPENSSL_zalloc(sizeof(*srcctx));
+ if (dstctx == NULL)
+ return NULL;
+
+ *dstctx = *srcctx;
+ dstctx->sig = NULL;
+ dstctx->md = NULL;
+ dstctx->mdctx = NULL;
+
+ if (srcctx->sig != NULL && !oqsx_key_up_ref(srcctx->sig))
+ goto err;
+ dstctx->sig = srcctx->sig;
+
+ if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md))
+ goto err;
+ dstctx->md = srcctx->md;
+
+ if (srcctx->mdctx != NULL) {
+ dstctx->mdctx = EVP_MD_CTX_new();
+ if (dstctx->mdctx == NULL
+ || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx))
+ goto err;
+ }
+
+ if (srcctx->mddata) {
+ dstctx->mddata=OPENSSL_memdup(srcctx->mddata, srcctx->mdsize);
+ if (dstctx->mddata == NULL)
+ goto err;
+ dstctx->mdsize = srcctx->mdsize;
+ }
+
+ if (srcctx->aid) {
+ dstctx->aid = OPENSSL_memdup(srcctx->aid, srcctx->aid_len);
+ if (dstctx->aid == NULL)
+ goto err;
+ dstctx->aid_len = srcctx->aid_len;
+ }
+
+ if (srcctx->propq) {
+ dstctx->propq = OPENSSL_strdup(srcctx->propq);
+ if (dstctx->propq == NULL)
+ goto err;
+ }
+
+ return dstctx;
+ err:
+ oqs_sig_freectx(dstctx);
+ return NULL;
+}
+
+static int oqs_sig_get_ctx_params(void *vpoqs_sigctx, OSSL_PARAM *params)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+ OSSL_PARAM *p;
+
+ OQS_SIG_PRINTF("OQS SIG provider: get_ctx_params called\n");
+ if (poqs_sigctx == NULL || params == NULL)
+ return 0;
+
+ p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID);
+
+ if (poqs_sigctx->aid == NULL) {
+ poqs_sigctx->aid_len = get_aid(&(poqs_sigctx->aid), poqs_sigctx->sig->tls_name);
+ }
+
+ if (p != NULL
+ && !OSSL_PARAM_set_octet_string(p, poqs_sigctx->aid, poqs_sigctx->aid_len))
+ return 0;
+
+ p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_DIGEST);
+ if (p != NULL && !OSSL_PARAM_set_utf8_string(p, poqs_sigctx->mdname))
+ return 0;
+
+ return 1;
+}
+
+static const OSSL_PARAM known_gettable_ctx_params[] = {
+ OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
+ OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *oqs_sig_gettable_ctx_params(ossl_unused void *vpoqs_sigctx, ossl_unused void *vctx)
+{
+ OQS_SIG_PRINTF("OQS SIG provider: gettable_ctx_params called\n");
+ return known_gettable_ctx_params;
+}
+static int oqs_sig_set_ctx_params(void *vpoqs_sigctx, const OSSL_PARAM params[])
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+ const OSSL_PARAM *p;
+
+ OQS_SIG_PRINTF("OQS SIG provider: set_ctx_params called\n");
+ if (poqs_sigctx == NULL || params == NULL)
+ return 0;
+
+ p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST);
+ /* Not allowed during certain operations */
+ if (p != NULL && !poqs_sigctx->flag_allow_md)
+ return 0;
+ if (p != NULL) {
+ char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname;
+ char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops;
+ const OSSL_PARAM *propsp =
+ OSSL_PARAM_locate_const(params,
+ OSSL_SIGNATURE_PARAM_PROPERTIES);
+
+ if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname)))
+ return 0;
+ if (propsp != NULL
+ && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops)))
+ return 0;
+ if (!oqs_sig_setup_md(poqs_sigctx, mdname, mdprops))
+ return 0;
+ }
+
+ return 1;
+}
+
+static const OSSL_PARAM known_settable_ctx_params[] = {
+ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
+ OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0),
+ OSSL_PARAM_END
+};
+
+static const OSSL_PARAM *oqs_sig_settable_ctx_params(ossl_unused void *vpsm2ctx,
+ ossl_unused void *provctx)
+{
+ /*
+ * TODO(3.0): Should this function return a different set of settable ctx
+ * params if the ctx is being used for a DigestSign/DigestVerify? In that
+ * case it is not allowed to set the digest size/digest name because the
+ * digest is explicitly set as part of the init.
+ * NOTE: Ideally we would check poqs_sigctx->flag_allow_md, but this is
+ * problematic because there is no nice way of passing the
+ * PROV_OQSSIG_CTX down to this function...
+ * Because we have API's that dont know about their parent..
+ * e.g: EVP_SIGNATURE_gettable_ctx_params(const EVP_SIGNATURE *sig).
+ * We could pass NULL for that case (but then how useful is the check?).
+ */
+ OQS_SIG_PRINTF("OQS SIG provider: settable_ctx_params called\n");
+ return known_settable_ctx_params;
+}
+
+static int oqs_sig_get_ctx_md_params(void *vpoqs_sigctx, OSSL_PARAM *params)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+
+ OQS_SIG_PRINTF("OQS SIG provider: get_ctx_md_params called\n");
+ if (poqs_sigctx->mdctx == NULL)
+ return 0;
+
+ return EVP_MD_CTX_get_params(poqs_sigctx->mdctx, params);
+}
+
+static const OSSL_PARAM *oqs_sig_gettable_ctx_md_params(void *vpoqs_sigctx)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+
+ OQS_SIG_PRINTF("OQS SIG provider: gettable_ctx_md_params called\n");
+ if (poqs_sigctx->md == NULL)
+ return 0;
+
+ return EVP_MD_gettable_ctx_params(poqs_sigctx->md);
+}
+
+static int oqs_sig_set_ctx_md_params(void *vpoqs_sigctx, const OSSL_PARAM params[])
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+
+ OQS_SIG_PRINTF("OQS SIG provider: set_ctx_md_params called\n");
+ if (poqs_sigctx->mdctx == NULL)
+ return 0;
+
+ return EVP_MD_CTX_set_params(poqs_sigctx->mdctx, params);
+}
+
+static const OSSL_PARAM *oqs_sig_settable_ctx_md_params(void *vpoqs_sigctx)
+{
+ PROV_OQSSIG_CTX *poqs_sigctx = (PROV_OQSSIG_CTX *)vpoqs_sigctx;
+
+ if (poqs_sigctx->md == NULL)
+ return 0;
+
+ OQS_SIG_PRINTF("OQS SIG provider: settable_ctx_md_params called\n");
+ return EVP_MD_settable_ctx_params(poqs_sigctx->md);
+}
+
+const OSSL_DISPATCH oqs_signature_functions[] = {
+ { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))oqs_sig_newctx },
+ { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))oqs_sig_sign_init },
+ { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))oqs_sig_sign },
+ { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))oqs_sig_verify_init },
+ { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))oqs_sig_verify },
+ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,
+ (void (*)(void))oqs_sig_digest_sign_init },
+ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,
+ (void (*)(void))oqs_sig_digest_signverify_update },
+ { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,
+ (void (*)(void))oqs_sig_digest_sign_final },
+ { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT,
+ (void (*)(void))oqs_sig_digest_verify_init },
+ { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE,
+ (void (*)(void))oqs_sig_digest_signverify_update },
+ { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL,
+ (void (*)(void))oqs_sig_digest_verify_final },
+ { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))oqs_sig_freectx },
+ { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))oqs_sig_dupctx },
+ { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))oqs_sig_get_ctx_params },
+ { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,
+ (void (*)(void))oqs_sig_gettable_ctx_params },
+ { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))oqs_sig_set_ctx_params },
+ { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,
+ (void (*)(void))oqs_sig_settable_ctx_params },
+ { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS,
+ (void (*)(void))oqs_sig_get_ctx_md_params },
+ { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS,
+ (void (*)(void))oqs_sig_gettable_ctx_md_params },
+ { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS,
+ (void (*)(void))oqs_sig_set_ctx_md_params },
+ { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS,
+ (void (*)(void))oqs_sig_settable_ctx_md_params },
+ { 0, NULL }
+};
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider decoders
+ *
+ * Code strongly inspired by OpenSSL default provider.
+ *
+ */
+
+#ifndef DECODER_PROVIDER
+# error Macro DECODER_PROVIDER undefined
+#endif
+
+#define DECODER_STRUCTURE_type_specific_keypair "type-specific"
+#define DECODER_STRUCTURE_type_specific_params "type-specific"
+#define DECODER_STRUCTURE_type_specific "type-specific"
+#define DECODER_STRUCTURE_type_specific_no_pub "type-specific"
+#define DECODER_STRUCTURE_PKCS8 "pkcs8"
+#define DECODER_STRUCTURE_SubjectPublicKeyInfo "SubjectPublicKeyInfo"
+#define DECODER_STRUCTURE_PrivateKeyInfo "PrivateKeyInfo"
+
+/* Arguments are prefixed with '_' to avoid build breaks on certain platforms */
+#define DECODER(_name, _input, _output) \
+ { _name, \
+ "provider=" DECODER_PROVIDER ",input=" #_input, \
+ (oqs_##_input##_to_##_output##_decoder_functions) }
+#define DECODER_w_structure(_name, _input, _structure, _output) \
+ { _name, \
+ "provider=" DECODER_PROVIDER ",input=" #_input \
+ ",structure=" DECODER_STRUCTURE_##_structure, \
+ (oqs_##_structure##_##_input##_to_##_output##_decoder_functions) }
+
+///// OQS_TEMPLATE_FRAGMENT_MAKE_START
+#ifdef OQS_ENABLE_SIG_dilithium_2
+DECODER_w_structure("dilithium2", der, PrivateKeyInfo, dilithium2),
+DECODER_w_structure("dilithium2", der, SubjectPublicKeyInfo, dilithium2),DECODER_w_structure("p256_dilithium2", der, PrivateKeyInfo, p256_dilithium2),
+DECODER_w_structure("p256_dilithium2", der, SubjectPublicKeyInfo, p256_dilithium2),DECODER_w_structure("rsa3072_dilithium2", der, PrivateKeyInfo, rsa3072_dilithium2),
+DECODER_w_structure("rsa3072_dilithium2", der, SubjectPublicKeyInfo, rsa3072_dilithium2),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_3
+DECODER_w_structure("dilithium3", der, PrivateKeyInfo, dilithium3),
+DECODER_w_structure("dilithium3", der, SubjectPublicKeyInfo, dilithium3),DECODER_w_structure("p384_dilithium3", der, PrivateKeyInfo, p384_dilithium3),
+DECODER_w_structure("p384_dilithium3", der, SubjectPublicKeyInfo, p384_dilithium3),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_5
+DECODER_w_structure("dilithium5", der, PrivateKeyInfo, dilithium5),
+DECODER_w_structure("dilithium5", der, SubjectPublicKeyInfo, dilithium5),DECODER_w_structure("p521_dilithium5", der, PrivateKeyInfo, p521_dilithium5),
+DECODER_w_structure("p521_dilithium5", der, SubjectPublicKeyInfo, p521_dilithium5),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_512
+DECODER_w_structure("falcon512", der, PrivateKeyInfo, falcon512),
+DECODER_w_structure("falcon512", der, SubjectPublicKeyInfo, falcon512),DECODER_w_structure("p256_falcon512", der, PrivateKeyInfo, p256_falcon512),
+DECODER_w_structure("p256_falcon512", der, SubjectPublicKeyInfo, p256_falcon512),DECODER_w_structure("rsa3072_falcon512", der, PrivateKeyInfo, rsa3072_falcon512),
+DECODER_w_structure("rsa3072_falcon512", der, SubjectPublicKeyInfo, rsa3072_falcon512),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_1024
+DECODER_w_structure("falcon1024", der, PrivateKeyInfo, falcon1024),
+DECODER_w_structure("falcon1024", der, SubjectPublicKeyInfo, falcon1024),DECODER_w_structure("p521_falcon1024", der, PrivateKeyInfo, p521_falcon1024),
+DECODER_w_structure("p521_falcon1024", der, SubjectPublicKeyInfo, p521_falcon1024),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128f_simple
+DECODER_w_structure("sphincssha2128fsimple", der, PrivateKeyInfo, sphincssha2128fsimple),
+DECODER_w_structure("sphincssha2128fsimple", der, SubjectPublicKeyInfo, sphincssha2128fsimple),DECODER_w_structure("p256_sphincssha2128fsimple", der, PrivateKeyInfo, p256_sphincssha2128fsimple),
+DECODER_w_structure("p256_sphincssha2128fsimple", der, SubjectPublicKeyInfo, p256_sphincssha2128fsimple),DECODER_w_structure("rsa3072_sphincssha2128fsimple", der, PrivateKeyInfo, rsa3072_sphincssha2128fsimple),
+DECODER_w_structure("rsa3072_sphincssha2128fsimple", der, SubjectPublicKeyInfo, rsa3072_sphincssha2128fsimple),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128s_simple
+DECODER_w_structure("sphincssha2128ssimple", der, PrivateKeyInfo, sphincssha2128ssimple),
+DECODER_w_structure("sphincssha2128ssimple", der, SubjectPublicKeyInfo, sphincssha2128ssimple),DECODER_w_structure("p256_sphincssha2128ssimple", der, PrivateKeyInfo, p256_sphincssha2128ssimple),
+DECODER_w_structure("p256_sphincssha2128ssimple", der, SubjectPublicKeyInfo, p256_sphincssha2128ssimple),DECODER_w_structure("rsa3072_sphincssha2128ssimple", der, PrivateKeyInfo, rsa3072_sphincssha2128ssimple),
+DECODER_w_structure("rsa3072_sphincssha2128ssimple", der, SubjectPublicKeyInfo, rsa3072_sphincssha2128ssimple),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_192f_simple
+DECODER_w_structure("sphincssha2192fsimple", der, PrivateKeyInfo, sphincssha2192fsimple),
+DECODER_w_structure("sphincssha2192fsimple", der, SubjectPublicKeyInfo, sphincssha2192fsimple),DECODER_w_structure("p384_sphincssha2192fsimple", der, PrivateKeyInfo, p384_sphincssha2192fsimple),
+DECODER_w_structure("p384_sphincssha2192fsimple", der, SubjectPublicKeyInfo, p384_sphincssha2192fsimple),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_shake_128f_simple
+DECODER_w_structure("sphincsshake128fsimple", der, PrivateKeyInfo, sphincsshake128fsimple),
+DECODER_w_structure("sphincsshake128fsimple", der, SubjectPublicKeyInfo, sphincsshake128fsimple),DECODER_w_structure("p256_sphincsshake128fsimple", der, PrivateKeyInfo, p256_sphincsshake128fsimple),
+DECODER_w_structure("p256_sphincsshake128fsimple", der, SubjectPublicKeyInfo, p256_sphincsshake128fsimple),DECODER_w_structure("rsa3072_sphincsshake128fsimple", der, PrivateKeyInfo, rsa3072_sphincsshake128fsimple),
+DECODER_w_structure("rsa3072_sphincsshake128fsimple", der, SubjectPublicKeyInfo, rsa3072_sphincsshake128fsimple),
+#endif
+///// OQS_TEMPLATE_FRAGMENT_MAKE_END
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider encoders
+ *
+ * Code strongly inspired by OpenSSL default provider.
+ *
+ */
+
+#ifndef ENCODER_PROVIDER
+# error Macro ENCODER_PROVIDER undefined
+#endif
+
+#define ENCODER_STRUCTURE_type_specific_keypair "type-specific"
+#define ENCODER_STRUCTURE_type_specific_params "type-specific"
+#define ENCODER_STRUCTURE_type_specific "type-specific"
+#define ENCODER_STRUCTURE_type_specific_no_pub "type-specific"
+#define ENCODER_STRUCTURE_PKCS8 "pkcs8"
+#define ENCODER_STRUCTURE_SubjectPublicKeyInfo "SubjectPublicKeyInfo"
+#define ENCODER_STRUCTURE_PrivateKeyInfo "PrivateKeyInfo"
+#define ENCODER_STRUCTURE_EncryptedPrivateKeyInfo "EncryptedPrivateKeyInfo"
+#define ENCODER_STRUCTURE_PKCS1 "pkcs1"
+#define ENCODER_STRUCTURE_PKCS3 "pkcs3"
+
+/* Arguments are prefixed with '_' to avoid build breaks on certain platforms */
+#define ENCODER_TEXT(_name, _sym) \
+ { _name, \
+ "provider=" ENCODER_PROVIDER ",output=text", \
+ (oqs_##_sym##_to_text_encoder_functions) }
+#define ENCODER(_name, _sym, _fips, _output) \
+ { _name, \
+ "provider=" ENCODER_PROVIDER ",output=" #_output, \
+ (oqs_##_sym##_to_##_output##_encoder_functions) }
+
+#define ENCODER_w_structure(_name, _sym, _output, _structure) \
+ { _name, \
+ "provider=" ENCODER_PROVIDER ",output=" #_output \
+ ",structure=" ENCODER_STRUCTURE_##_structure, \
+ (oqs_##_sym##_to_##_structure##_##_output##_encoder_functions) }
+
+/*
+ * Entries for human text "encoders"
+ */
+
+/*
+ * Entries for key type specific output formats. The structure name on these
+ * is the same as the key type name. This allows us to say something like:
+ *
+ * To replace i2d_{TYPE}PrivateKey(), i2d_{TYPE}PublicKey() and
+ * i2d_{TYPE}Params(), use OSSL_ENCODER functions with an OSSL_ENCODER_CTX
+ * created like this:
+ *
+ * OSSL_ENCODER_CTX *ctx =
+ * OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, "DER", "type-specific",
+ * NULL, NULL);
+ *
+ * To replace PEM_write_bio_{TYPE}PrivateKey(), PEM_write_bio_{TYPE}PublicKey()
+ * and PEM_write_bio_{TYPE}Params(), use OSSL_ENCODER functions with an
+ * OSSL_ENCODER_CTX created like this:
+ *
+ * OSSL_ENCODER_CTX *ctx =
+ * OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, "PEM", "type-specific",
+ * NULL, NULL);
+ *
+ * We only implement those for which there are current i2d_ and PEM_write_bio
+ * implementations.
+ */
+
+/*
+ * Entries for PKCS#8 and SubjectPublicKeyInfo.
+ * The "der" ones are added convenience for any user that wants to use
+ * OSSL_ENCODER directly.
+ * The "pem" ones also support PEM_write_bio_PrivateKey() and
+ * PEM_write_bio_PUBKEY().
+ */
+
+///// OQS_TEMPLATE_FRAGMENT_MAKE_START
+#ifdef OQS_ENABLE_SIG_dilithium_2
+ENCODER_w_structure("dilithium2", dilithium2, der, PrivateKeyInfo),
+ENCODER_w_structure("dilithium2", dilithium2, pem, PrivateKeyInfo),
+ENCODER_w_structure("dilithium2", dilithium2, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("dilithium2", dilithium2, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("dilithium2", dilithium2, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("dilithium2", dilithium2, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("dilithium2", dilithium2),
+ENCODER_w_structure("p256_dilithium2", p256_dilithium2, der, PrivateKeyInfo),
+ENCODER_w_structure("p256_dilithium2", p256_dilithium2, pem, PrivateKeyInfo),
+ENCODER_w_structure("p256_dilithium2", p256_dilithium2, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_dilithium2", p256_dilithium2, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_dilithium2", p256_dilithium2, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("p256_dilithium2", p256_dilithium2, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("p256_dilithium2", p256_dilithium2),
+ENCODER_w_structure("rsa3072_dilithium2", rsa3072_dilithium2, der, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_dilithium2", rsa3072_dilithium2, pem, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_dilithium2", rsa3072_dilithium2, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_dilithium2", rsa3072_dilithium2, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_dilithium2", rsa3072_dilithium2, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("rsa3072_dilithium2", rsa3072_dilithium2, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("rsa3072_dilithium2", rsa3072_dilithium2),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_3
+ENCODER_w_structure("dilithium3", dilithium3, der, PrivateKeyInfo),
+ENCODER_w_structure("dilithium3", dilithium3, pem, PrivateKeyInfo),
+ENCODER_w_structure("dilithium3", dilithium3, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("dilithium3", dilithium3, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("dilithium3", dilithium3, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("dilithium3", dilithium3, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("dilithium3", dilithium3),
+ENCODER_w_structure("p384_dilithium3", p384_dilithium3, der, PrivateKeyInfo),
+ENCODER_w_structure("p384_dilithium3", p384_dilithium3, pem, PrivateKeyInfo),
+ENCODER_w_structure("p384_dilithium3", p384_dilithium3, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p384_dilithium3", p384_dilithium3, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p384_dilithium3", p384_dilithium3, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("p384_dilithium3", p384_dilithium3, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("p384_dilithium3", p384_dilithium3),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_5
+ENCODER_w_structure("dilithium5", dilithium5, der, PrivateKeyInfo),
+ENCODER_w_structure("dilithium5", dilithium5, pem, PrivateKeyInfo),
+ENCODER_w_structure("dilithium5", dilithium5, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("dilithium5", dilithium5, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("dilithium5", dilithium5, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("dilithium5", dilithium5, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("dilithium5", dilithium5),
+ENCODER_w_structure("p521_dilithium5", p521_dilithium5, der, PrivateKeyInfo),
+ENCODER_w_structure("p521_dilithium5", p521_dilithium5, pem, PrivateKeyInfo),
+ENCODER_w_structure("p521_dilithium5", p521_dilithium5, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p521_dilithium5", p521_dilithium5, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p521_dilithium5", p521_dilithium5, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("p521_dilithium5", p521_dilithium5, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("p521_dilithium5", p521_dilithium5),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_512
+ENCODER_w_structure("falcon512", falcon512, der, PrivateKeyInfo),
+ENCODER_w_structure("falcon512", falcon512, pem, PrivateKeyInfo),
+ENCODER_w_structure("falcon512", falcon512, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("falcon512", falcon512, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("falcon512", falcon512, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("falcon512", falcon512, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("falcon512", falcon512),
+ENCODER_w_structure("p256_falcon512", p256_falcon512, der, PrivateKeyInfo),
+ENCODER_w_structure("p256_falcon512", p256_falcon512, pem, PrivateKeyInfo),
+ENCODER_w_structure("p256_falcon512", p256_falcon512, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_falcon512", p256_falcon512, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_falcon512", p256_falcon512, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("p256_falcon512", p256_falcon512, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("p256_falcon512", p256_falcon512),
+ENCODER_w_structure("rsa3072_falcon512", rsa3072_falcon512, der, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_falcon512", rsa3072_falcon512, pem, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_falcon512", rsa3072_falcon512, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_falcon512", rsa3072_falcon512, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_falcon512", rsa3072_falcon512, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("rsa3072_falcon512", rsa3072_falcon512, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("rsa3072_falcon512", rsa3072_falcon512),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_1024
+ENCODER_w_structure("falcon1024", falcon1024, der, PrivateKeyInfo),
+ENCODER_w_structure("falcon1024", falcon1024, pem, PrivateKeyInfo),
+ENCODER_w_structure("falcon1024", falcon1024, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("falcon1024", falcon1024, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("falcon1024", falcon1024, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("falcon1024", falcon1024, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("falcon1024", falcon1024),
+ENCODER_w_structure("p521_falcon1024", p521_falcon1024, der, PrivateKeyInfo),
+ENCODER_w_structure("p521_falcon1024", p521_falcon1024, pem, PrivateKeyInfo),
+ENCODER_w_structure("p521_falcon1024", p521_falcon1024, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p521_falcon1024", p521_falcon1024, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p521_falcon1024", p521_falcon1024, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("p521_falcon1024", p521_falcon1024, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("p521_falcon1024", p521_falcon1024),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128f_simple
+ENCODER_w_structure("sphincssha2128fsimple", sphincssha2128fsimple, der, PrivateKeyInfo),
+ENCODER_w_structure("sphincssha2128fsimple", sphincssha2128fsimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("sphincssha2128fsimple", sphincssha2128fsimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("sphincssha2128fsimple", sphincssha2128fsimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("sphincssha2128fsimple", sphincssha2128fsimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("sphincssha2128fsimple", sphincssha2128fsimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("sphincssha2128fsimple", sphincssha2128fsimple),
+ENCODER_w_structure("p256_sphincssha2128fsimple", p256_sphincssha2128fsimple, der, PrivateKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128fsimple", p256_sphincssha2128fsimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128fsimple", p256_sphincssha2128fsimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128fsimple", p256_sphincssha2128fsimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128fsimple", p256_sphincssha2128fsimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128fsimple", p256_sphincssha2128fsimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("p256_sphincssha2128fsimple", p256_sphincssha2128fsimple),
+ENCODER_w_structure("rsa3072_sphincssha2128fsimple", rsa3072_sphincssha2128fsimple, der, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128fsimple", rsa3072_sphincssha2128fsimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128fsimple", rsa3072_sphincssha2128fsimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128fsimple", rsa3072_sphincssha2128fsimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128fsimple", rsa3072_sphincssha2128fsimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128fsimple", rsa3072_sphincssha2128fsimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("rsa3072_sphincssha2128fsimple", rsa3072_sphincssha2128fsimple),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128s_simple
+ENCODER_w_structure("sphincssha2128ssimple", sphincssha2128ssimple, der, PrivateKeyInfo),
+ENCODER_w_structure("sphincssha2128ssimple", sphincssha2128ssimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("sphincssha2128ssimple", sphincssha2128ssimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("sphincssha2128ssimple", sphincssha2128ssimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("sphincssha2128ssimple", sphincssha2128ssimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("sphincssha2128ssimple", sphincssha2128ssimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("sphincssha2128ssimple", sphincssha2128ssimple),
+ENCODER_w_structure("p256_sphincssha2128ssimple", p256_sphincssha2128ssimple, der, PrivateKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128ssimple", p256_sphincssha2128ssimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128ssimple", p256_sphincssha2128ssimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128ssimple", p256_sphincssha2128ssimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128ssimple", p256_sphincssha2128ssimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("p256_sphincssha2128ssimple", p256_sphincssha2128ssimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("p256_sphincssha2128ssimple", p256_sphincssha2128ssimple),
+ENCODER_w_structure("rsa3072_sphincssha2128ssimple", rsa3072_sphincssha2128ssimple, der, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128ssimple", rsa3072_sphincssha2128ssimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128ssimple", rsa3072_sphincssha2128ssimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128ssimple", rsa3072_sphincssha2128ssimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128ssimple", rsa3072_sphincssha2128ssimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("rsa3072_sphincssha2128ssimple", rsa3072_sphincssha2128ssimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("rsa3072_sphincssha2128ssimple", rsa3072_sphincssha2128ssimple),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_192f_simple
+ENCODER_w_structure("sphincssha2192fsimple", sphincssha2192fsimple, der, PrivateKeyInfo),
+ENCODER_w_structure("sphincssha2192fsimple", sphincssha2192fsimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("sphincssha2192fsimple", sphincssha2192fsimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("sphincssha2192fsimple", sphincssha2192fsimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("sphincssha2192fsimple", sphincssha2192fsimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("sphincssha2192fsimple", sphincssha2192fsimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("sphincssha2192fsimple", sphincssha2192fsimple),
+ENCODER_w_structure("p384_sphincssha2192fsimple", p384_sphincssha2192fsimple, der, PrivateKeyInfo),
+ENCODER_w_structure("p384_sphincssha2192fsimple", p384_sphincssha2192fsimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("p384_sphincssha2192fsimple", p384_sphincssha2192fsimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p384_sphincssha2192fsimple", p384_sphincssha2192fsimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p384_sphincssha2192fsimple", p384_sphincssha2192fsimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("p384_sphincssha2192fsimple", p384_sphincssha2192fsimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("p384_sphincssha2192fsimple", p384_sphincssha2192fsimple),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_shake_128f_simple
+ENCODER_w_structure("sphincsshake128fsimple", sphincsshake128fsimple, der, PrivateKeyInfo),
+ENCODER_w_structure("sphincsshake128fsimple", sphincsshake128fsimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("sphincsshake128fsimple", sphincsshake128fsimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("sphincsshake128fsimple", sphincsshake128fsimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("sphincsshake128fsimple", sphincsshake128fsimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("sphincsshake128fsimple", sphincsshake128fsimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("sphincsshake128fsimple", sphincsshake128fsimple),
+ENCODER_w_structure("p256_sphincsshake128fsimple", p256_sphincsshake128fsimple, der, PrivateKeyInfo),
+ENCODER_w_structure("p256_sphincsshake128fsimple", p256_sphincsshake128fsimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("p256_sphincsshake128fsimple", p256_sphincsshake128fsimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_sphincsshake128fsimple", p256_sphincsshake128fsimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("p256_sphincsshake128fsimple", p256_sphincsshake128fsimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("p256_sphincsshake128fsimple", p256_sphincsshake128fsimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("p256_sphincsshake128fsimple", p256_sphincsshake128fsimple),
+ENCODER_w_structure("rsa3072_sphincsshake128fsimple", rsa3072_sphincsshake128fsimple, der, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincsshake128fsimple", rsa3072_sphincsshake128fsimple, pem, PrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincsshake128fsimple", rsa3072_sphincsshake128fsimple, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincsshake128fsimple", rsa3072_sphincsshake128fsimple, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("rsa3072_sphincsshake128fsimple", rsa3072_sphincsshake128fsimple, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("rsa3072_sphincsshake128fsimple", rsa3072_sphincsshake128fsimple, pem, SubjectPublicKeyInfo),
+ENCODER_TEXT("rsa3072_sphincsshake128fsimple", rsa3072_sphincsshake128fsimple),
+#endif
+///// OQS_TEMPLATE_FRAGMENT_MAKE_END
+
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider
+ *
+ * Code strongly inspired by OpenSSL legacy provider.
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <openssl/core.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
+#include <openssl/objects.h>
+#include <openssl/err.h>
+#include <openssl/provider.h>
+#include "oqs_prov.h"
+
+#ifdef NDEBUG
+#define OQS_PROV_PRINTF(a)
+#define OQS_PROV_PRINTF2(a, b)
+#define OQS_PROV_PRINTF3(a, b, c)
+#else
+#define OQS_PROV_PRINTF(a) if (getenv("OQSPROV")) printf(a)
+#define OQS_PROV_PRINTF2(a, b) if (getenv("OQSPROV")) printf(a, b)
+#define OQS_PROV_PRINTF3(a, b, c) if (getenv("OQSPROV")) printf(a, b, c)
+#endif // NDEBUG
+
+/*
+ * Forward declarations to ensure that interface functions are correctly
+ * defined.
+ */
+static OSSL_FUNC_provider_gettable_params_fn oqsprovider_gettable_params;
+static OSSL_FUNC_provider_get_params_fn oqsprovider_get_params;
+static OSSL_FUNC_provider_query_operation_fn oqsprovider_query;
+extern OSSL_FUNC_provider_get_capabilities_fn oqs_provider_get_capabilities;
+
+/*
+ * List of all algorithms with given OIDs
+ */
+///// OQS_TEMPLATE_FRAGMENT_ASSIGN_SIG_OIDS_START
+#define OQS_OID_CNT 46
+const char* oqs_oid_alg_list[OQS_OID_CNT] =
+{
+"1.3.6.1.4.1.2.267.7.4.4", "dilithium2",
+"1.3.9999.2.7.1" , "p256_dilithium2",
+"1.3.9999.2.7.2" , "rsa3072_dilithium2",
+"1.3.6.1.4.1.2.267.7.6.5", "dilithium3",
+"1.3.9999.2.7.3" , "p384_dilithium3",
+"1.3.6.1.4.1.2.267.7.8.7", "dilithium5",
+"1.3.9999.2.7.4" , "p521_dilithium5",
+"1.3.9999.3.6", "falcon512",
+"1.3.9999.3.7" , "p256_falcon512",
+"1.3.9999.3.8" , "rsa3072_falcon512",
+"1.3.9999.3.9", "falcon1024",
+"1.3.9999.3.10" , "p521_falcon1024",
+"1.3.9999.6.4.13", "sphincssha2128fsimple",
+"1.3.9999.6.4.14" , "p256_sphincssha2128fsimple",
+"1.3.9999.6.4.15" , "rsa3072_sphincssha2128fsimple",
+"1.3.9999.6.4.16", "sphincssha2128ssimple",
+"1.3.9999.6.4.17" , "p256_sphincssha2128ssimple",
+"1.3.9999.6.4.18" , "rsa3072_sphincssha2128ssimple",
+"1.3.9999.6.5.10", "sphincssha2192fsimple",
+"1.3.9999.6.5.11" , "p384_sphincssha2192fsimple",
+"1.3.9999.6.7.13", "sphincsshake128fsimple",
+"1.3.9999.6.7.14" , "p256_sphincsshake128fsimple",
+"1.3.9999.6.7.15" , "rsa3072_sphincsshake128fsimple",
+///// OQS_TEMPLATE_FRAGMENT_ASSIGN_SIG_OIDS_END
+};
+
+int oqs_patch_oids(void) {
+///// OQS_TEMPLATE_FRAGMENT_OID_PATCHING_START
+ if (getenv("OQS_OID_DILITHIUM2")) oqs_oid_alg_list[0] = getenv("OQS_OID_DILITHIUM2");
+ if (getenv("OQS_OID_P256_DILITHIUM2")) oqs_oid_alg_list[2] = getenv("OQS_OID_P256_DILITHIUM2");
+ if (getenv("OQS_OID_RSA3072_DILITHIUM2")) oqs_oid_alg_list[4] = getenv("OQS_OID_RSA3072_DILITHIUM2");
+ if (getenv("OQS_OID_DILITHIUM3")) oqs_oid_alg_list[6] = getenv("OQS_OID_DILITHIUM3");
+ if (getenv("OQS_OID_P384_DILITHIUM3")) oqs_oid_alg_list[8] = getenv("OQS_OID_P384_DILITHIUM3");
+ if (getenv("OQS_OID_DILITHIUM5")) oqs_oid_alg_list[10] = getenv("OQS_OID_DILITHIUM5");
+ if (getenv("OQS_OID_P521_DILITHIUM5")) oqs_oid_alg_list[12] = getenv("OQS_OID_P521_DILITHIUM5");
+ if (getenv("OQS_OID_FALCON512")) oqs_oid_alg_list[14] = getenv("OQS_OID_FALCON512");
+ if (getenv("OQS_OID_P256_FALCON512")) oqs_oid_alg_list[16] = getenv("OQS_OID_P256_FALCON512");
+ if (getenv("OQS_OID_RSA3072_FALCON512")) oqs_oid_alg_list[18] = getenv("OQS_OID_RSA3072_FALCON512");
+ if (getenv("OQS_OID_FALCON1024")) oqs_oid_alg_list[20] = getenv("OQS_OID_FALCON1024");
+ if (getenv("OQS_OID_P521_FALCON1024")) oqs_oid_alg_list[22] = getenv("OQS_OID_P521_FALCON1024");
+ if (getenv("OQS_OID_SPHINCSSHA2128FSIMPLE")) oqs_oid_alg_list[24] = getenv("OQS_OID_SPHINCSSHA2128FSIMPLE");
+ if (getenv("OQS_OID_P256_SPHINCSSHA2128FSIMPLE")) oqs_oid_alg_list[26] = getenv("OQS_OID_P256_SPHINCSSHA2128FSIMPLE");
+ if (getenv("OQS_OID_RSA3072_SPHINCSSHA2128FSIMPLE")) oqs_oid_alg_list[28] = getenv("OQS_OID_RSA3072_SPHINCSSHA2128FSIMPLE");
+ if (getenv("OQS_OID_SPHINCSSHA2128SSIMPLE")) oqs_oid_alg_list[30] = getenv("OQS_OID_SPHINCSSHA2128SSIMPLE");
+ if (getenv("OQS_OID_P256_SPHINCSSHA2128SSIMPLE")) oqs_oid_alg_list[32] = getenv("OQS_OID_P256_SPHINCSSHA2128SSIMPLE");
+ if (getenv("OQS_OID_RSA3072_SPHINCSSHA2128SSIMPLE")) oqs_oid_alg_list[34] = getenv("OQS_OID_RSA3072_SPHINCSSHA2128SSIMPLE");
+ if (getenv("OQS_OID_SPHINCSSHA2192FSIMPLE")) oqs_oid_alg_list[36] = getenv("OQS_OID_SPHINCSSHA2192FSIMPLE");
+ if (getenv("OQS_OID_P384_SPHINCSSHA2192FSIMPLE")) oqs_oid_alg_list[38] = getenv("OQS_OID_P384_SPHINCSSHA2192FSIMPLE");
+ if (getenv("OQS_OID_SPHINCSSHAKE128FSIMPLE")) oqs_oid_alg_list[40] = getenv("OQS_OID_SPHINCSSHAKE128FSIMPLE");
+ if (getenv("OQS_OID_P256_SPHINCSSHAKE128FSIMPLE")) oqs_oid_alg_list[42] = getenv("OQS_OID_P256_SPHINCSSHAKE128FSIMPLE");
+ if (getenv("OQS_OID_RSA3072_SPHINCSSHAKE128FSIMPLE")) oqs_oid_alg_list[44] = getenv("OQS_OID_RSA3072_SPHINCSSHAKE128FSIMPLE");
+///// OQS_TEMPLATE_FRAGMENT_OID_PATCHING_END
+ return 1;
+}
+
+
+#ifdef USE_ENCODING_LIB
+const char* oqs_alg_encoding_list[OQS_OID_CNT] = { 0 };
+
+int oqs_patch_encodings(void) {
+///// OQS_TEMPLATE_FRAGMENT_ENCODING_PATCHING_START
+ if (getenv("OQS_ENCODING_DILITHIUM2")) oqs_alg_encoding_list[0] = getenv("OQS_ENCODING_DILITHIUM2");
+ if (getenv("OQS_ENCODING_DILITHIUM2_ALGNAME")) oqs_alg_encoding_list[1] = getenv("OQS_ENCODING_DILITHIUM2_ALGNAME");
+ if (getenv("OQS_ENCODING_P256_DILITHIUM2")) oqs_alg_encoding_list[2] = getenv("OQS_ENCODING_P256_DILITHIUM2");
+ if (getenv("OQS_ENCODING_P256_DILITHIUM2_ALGNAME")) oqs_alg_encoding_list[3] = getenv("OQS_ENCODING_P256_DILITHIUM2_ALGNAME");
+ if (getenv("OQS_ENCODING_RSA3072_DILITHIUM2")) oqs_alg_encoding_list[4] = getenv("OQS_ENCODING_RSA3072_DILITHIUM2");
+ if (getenv("OQS_ENCODING_RSA3072_DILITHIUM2_ALGNAME")) oqs_alg_encoding_list[5] = getenv("OQS_ENCODING_RSA3072_DILITHIUM2_ALGNAME");
+ if (getenv("OQS_ENCODING_DILITHIUM3")) oqs_alg_encoding_list[6] = getenv("OQS_ENCODING_DILITHIUM3");
+ if (getenv("OQS_ENCODING_DILITHIUM3_ALGNAME")) oqs_alg_encoding_list[7] = getenv("OQS_ENCODING_DILITHIUM3_ALGNAME");
+ if (getenv("OQS_ENCODING_P384_DILITHIUM3")) oqs_alg_encoding_list[8] = getenv("OQS_ENCODING_P384_DILITHIUM3");
+ if (getenv("OQS_ENCODING_P384_DILITHIUM3_ALGNAME")) oqs_alg_encoding_list[9] = getenv("OQS_ENCODING_P384_DILITHIUM3_ALGNAME");
+ if (getenv("OQS_ENCODING_DILITHIUM5")) oqs_alg_encoding_list[10] = getenv("OQS_ENCODING_DILITHIUM5");
+ if (getenv("OQS_ENCODING_DILITHIUM5_ALGNAME")) oqs_alg_encoding_list[11] = getenv("OQS_ENCODING_DILITHIUM5_ALGNAME");
+ if (getenv("OQS_ENCODING_P521_DILITHIUM5")) oqs_alg_encoding_list[12] = getenv("OQS_ENCODING_P521_DILITHIUM5");
+ if (getenv("OQS_ENCODING_P521_DILITHIUM5_ALGNAME")) oqs_alg_encoding_list[13] = getenv("OQS_ENCODING_P521_DILITHIUM5_ALGNAME");
+ if (getenv("OQS_ENCODING_FALCON512")) oqs_alg_encoding_list[14] = getenv("OQS_ENCODING_FALCON512");
+ if (getenv("OQS_ENCODING_FALCON512_ALGNAME")) oqs_alg_encoding_list[15] = getenv("OQS_ENCODING_FALCON512_ALGNAME");
+ if (getenv("OQS_ENCODING_P256_FALCON512")) oqs_alg_encoding_list[16] = getenv("OQS_ENCODING_P256_FALCON512");
+ if (getenv("OQS_ENCODING_P256_FALCON512_ALGNAME")) oqs_alg_encoding_list[17] = getenv("OQS_ENCODING_P256_FALCON512_ALGNAME");
+ if (getenv("OQS_ENCODING_RSA3072_FALCON512")) oqs_alg_encoding_list[18] = getenv("OQS_ENCODING_RSA3072_FALCON512");
+ if (getenv("OQS_ENCODING_RSA3072_FALCON512_ALGNAME")) oqs_alg_encoding_list[19] = getenv("OQS_ENCODING_RSA3072_FALCON512_ALGNAME");
+ if (getenv("OQS_ENCODING_FALCON1024")) oqs_alg_encoding_list[20] = getenv("OQS_ENCODING_FALCON1024");
+ if (getenv("OQS_ENCODING_FALCON1024_ALGNAME")) oqs_alg_encoding_list[21] = getenv("OQS_ENCODING_FALCON1024_ALGNAME");
+ if (getenv("OQS_ENCODING_P521_FALCON1024")) oqs_alg_encoding_list[22] = getenv("OQS_ENCODING_P521_FALCON1024");
+ if (getenv("OQS_ENCODING_P521_FALCON1024_ALGNAME")) oqs_alg_encoding_list[23] = getenv("OQS_ENCODING_P521_FALCON1024_ALGNAME");
+ if (getenv("OQS_ENCODING_SPHINCSSHA2128FSIMPLE")) oqs_alg_encoding_list[24] = getenv("OQS_ENCODING_SPHINCSSHA2128FSIMPLE");
+ if (getenv("OQS_ENCODING_SPHINCSSHA2128FSIMPLE_ALGNAME")) oqs_alg_encoding_list[25] = getenv("OQS_ENCODING_SPHINCSSHA2128FSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_P256_SPHINCSSHA2128FSIMPLE")) oqs_alg_encoding_list[26] = getenv("OQS_ENCODING_P256_SPHINCSSHA2128FSIMPLE");
+ if (getenv("OQS_ENCODING_P256_SPHINCSSHA2128FSIMPLE_ALGNAME")) oqs_alg_encoding_list[27] = getenv("OQS_ENCODING_P256_SPHINCSSHA2128FSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128FSIMPLE")) oqs_alg_encoding_list[28] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128FSIMPLE");
+ if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128FSIMPLE_ALGNAME")) oqs_alg_encoding_list[29] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128FSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_SPHINCSSHA2128SSIMPLE")) oqs_alg_encoding_list[30] = getenv("OQS_ENCODING_SPHINCSSHA2128SSIMPLE");
+ if (getenv("OQS_ENCODING_SPHINCSSHA2128SSIMPLE_ALGNAME")) oqs_alg_encoding_list[31] = getenv("OQS_ENCODING_SPHINCSSHA2128SSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_P256_SPHINCSSHA2128SSIMPLE")) oqs_alg_encoding_list[32] = getenv("OQS_ENCODING_P256_SPHINCSSHA2128SSIMPLE");
+ if (getenv("OQS_ENCODING_P256_SPHINCSSHA2128SSIMPLE_ALGNAME")) oqs_alg_encoding_list[33] = getenv("OQS_ENCODING_P256_SPHINCSSHA2128SSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128SSIMPLE")) oqs_alg_encoding_list[34] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128SSIMPLE");
+ if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128SSIMPLE_ALGNAME")) oqs_alg_encoding_list[35] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHA2128SSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_SPHINCSSHA2192FSIMPLE")) oqs_alg_encoding_list[36] = getenv("OQS_ENCODING_SPHINCSSHA2192FSIMPLE");
+ if (getenv("OQS_ENCODING_SPHINCSSHA2192FSIMPLE_ALGNAME")) oqs_alg_encoding_list[37] = getenv("OQS_ENCODING_SPHINCSSHA2192FSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_P384_SPHINCSSHA2192FSIMPLE")) oqs_alg_encoding_list[38] = getenv("OQS_ENCODING_P384_SPHINCSSHA2192FSIMPLE");
+ if (getenv("OQS_ENCODING_P384_SPHINCSSHA2192FSIMPLE_ALGNAME")) oqs_alg_encoding_list[39] = getenv("OQS_ENCODING_P384_SPHINCSSHA2192FSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_SPHINCSSHAKE128FSIMPLE")) oqs_alg_encoding_list[40] = getenv("OQS_ENCODING_SPHINCSSHAKE128FSIMPLE");
+ if (getenv("OQS_ENCODING_SPHINCSSHAKE128FSIMPLE_ALGNAME")) oqs_alg_encoding_list[41] = getenv("OQS_ENCODING_SPHINCSSHAKE128FSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_P256_SPHINCSSHAKE128FSIMPLE")) oqs_alg_encoding_list[42] = getenv("OQS_ENCODING_P256_SPHINCSSHAKE128FSIMPLE");
+ if (getenv("OQS_ENCODING_P256_SPHINCSSHAKE128FSIMPLE_ALGNAME")) oqs_alg_encoding_list[43] = getenv("OQS_ENCODING_P256_SPHINCSSHAKE128FSIMPLE_ALGNAME");
+ if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHAKE128FSIMPLE")) oqs_alg_encoding_list[44] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHAKE128FSIMPLE");
+ if (getenv("OQS_ENCODING_RSA3072_SPHINCSSHAKE128FSIMPLE_ALGNAME")) oqs_alg_encoding_list[45] = getenv("OQS_ENCODING_RSA3072_SPHINCSSHAKE128FSIMPLE_ALGNAME");
+///// OQS_TEMPLATE_FRAGMENT_ENCODING_PATCHING_END
+ return 1;
+}
+#endif
+
+#define SIGALG(NAMES, SECBITS, FUNC) { NAMES, "provider=oqsprovider,oqsprovider.security_bits="#SECBITS"", FUNC }
+#define KEMBASEALG(NAMES, SECBITS) \
+ { "" #NAMES "", "provider=oqsprovider,oqsprovider.security_bits="#SECBITS"", oqs_generic_kem_functions },
+
+#define KEMHYBALG(NAMES, SECBITS) \
+ { "" #NAMES "", "provider=oqsprovider,oqsprovider.security_bits="#SECBITS"", oqs_hybrid_kem_functions },
+
+#define KEMKMALG(NAMES, SECBITS) \
+ { "" #NAMES "", "provider=oqsprovider,oqsprovider.security_bits="#SECBITS"" , oqs_##NAMES##_keymgmt_functions },
+
+#define KEMKMHYBALG(NAMES, SECBITS, HYBTYPE) \
+ { "" #NAMES "", "provider=oqsprovider,oqsprovider.security_bits="#SECBITS"" , oqs_##HYBTYPE##_##NAMES##_keymgmt_functions },
+
+/* Functions provided by the core */
+static OSSL_FUNC_core_gettable_params_fn *c_gettable_params = NULL;
+static OSSL_FUNC_core_get_params_fn *c_get_params = NULL;
+
+/* Parameters we provide to the core */
+static const OSSL_PARAM oqsprovider_param_types[] = {
+ OSSL_PARAM_DEFN(OSSL_PROV_PARAM_NAME, OSSL_PARAM_UTF8_PTR, NULL, 0),
+ OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0),
+ OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0),
+ OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0),
+ OSSL_PARAM_END
+};
+
+
+static const OSSL_ALGORITHM oqsprovider_signatures[] = {
+///// OQS_TEMPLATE_FRAGMENT_SIG_FUNCTIONS_START
+#ifdef OQS_ENABLE_SIG_dilithium_2
+ SIGALG("dilithium2", 128, oqs_signature_functions),
+ SIGALG("p256_dilithium2", 128, oqs_signature_functions),
+ SIGALG("rsa3072_dilithium2", 128, oqs_signature_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_3
+ SIGALG("dilithium3", 192, oqs_signature_functions),
+ SIGALG("p384_dilithium3", 192, oqs_signature_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_5
+ SIGALG("dilithium5", 256, oqs_signature_functions),
+ SIGALG("p521_dilithium5", 256, oqs_signature_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_512
+ SIGALG("falcon512", 128, oqs_signature_functions),
+ SIGALG("p256_falcon512", 128, oqs_signature_functions),
+ SIGALG("rsa3072_falcon512", 128, oqs_signature_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_1024
+ SIGALG("falcon1024", 256, oqs_signature_functions),
+ SIGALG("p521_falcon1024", 256, oqs_signature_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128f_simple
+ SIGALG("sphincssha2128fsimple", 128, oqs_signature_functions),
+ SIGALG("p256_sphincssha2128fsimple", 128, oqs_signature_functions),
+ SIGALG("rsa3072_sphincssha2128fsimple", 128, oqs_signature_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128s_simple
+ SIGALG("sphincssha2128ssimple", 128, oqs_signature_functions),
+ SIGALG("p256_sphincssha2128ssimple", 128, oqs_signature_functions),
+ SIGALG("rsa3072_sphincssha2128ssimple", 128, oqs_signature_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_192f_simple
+ SIGALG("sphincssha2192fsimple", 192, oqs_signature_functions),
+ SIGALG("p384_sphincssha2192fsimple", 192, oqs_signature_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_shake_128f_simple
+ SIGALG("sphincsshake128fsimple", 128, oqs_signature_functions),
+ SIGALG("p256_sphincsshake128fsimple", 128, oqs_signature_functions),
+ SIGALG("rsa3072_sphincsshake128fsimple", 128, oqs_signature_functions),
+#endif
+///// OQS_TEMPLATE_FRAGMENT_SIG_FUNCTIONS_END
+ { NULL, NULL, NULL }
+};
+
+static const OSSL_ALGORITHM oqsprovider_asym_kems[] = {
+///// OQS_TEMPLATE_FRAGMENT_KEM_FUNCTIONS_START
+#ifdef OQS_ENABLE_KEM_frodokem_640_aes
+ KEMBASEALG(frodo640aes, 128)
+ KEMHYBALG(p256_frodo640aes, 128)
+ KEMHYBALG(x25519_frodo640aes, 128)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_640_shake
+ KEMBASEALG(frodo640shake, 128)
+ KEMHYBALG(p256_frodo640shake, 128)
+ KEMHYBALG(x25519_frodo640shake, 128)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_976_aes
+ KEMBASEALG(frodo976aes, 192)
+ KEMHYBALG(p384_frodo976aes, 192)
+ KEMHYBALG(x448_frodo976aes, 192)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_976_shake
+ KEMBASEALG(frodo976shake, 192)
+ KEMHYBALG(p384_frodo976shake, 192)
+ KEMHYBALG(x448_frodo976shake, 192)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_1344_aes
+ KEMBASEALG(frodo1344aes, 256)
+ KEMHYBALG(p521_frodo1344aes, 256)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_1344_shake
+ KEMBASEALG(frodo1344shake, 256)
+ KEMHYBALG(p521_frodo1344shake, 256)
+#endif
+#ifdef OQS_ENABLE_KEM_kyber_512
+ KEMBASEALG(kyber512, 128)
+ KEMHYBALG(p256_kyber512, 128)
+ KEMHYBALG(x25519_kyber512, 128)
+#endif
+#ifdef OQS_ENABLE_KEM_kyber_768
+ KEMBASEALG(kyber768, 192)
+ KEMHYBALG(p384_kyber768, 192)
+ KEMHYBALG(x448_kyber768, 192)
+ KEMHYBALG(x25519_kyber768, 128)
+ KEMHYBALG(p256_kyber768, 128)
+#endif
+#ifdef OQS_ENABLE_KEM_kyber_1024
+ KEMBASEALG(kyber1024, 256)
+ KEMHYBALG(p521_kyber1024, 256)
+#endif
+#ifdef OQS_ENABLE_KEM_bike_l1
+ KEMBASEALG(bikel1, 128)
+ KEMHYBALG(p256_bikel1, 128)
+ KEMHYBALG(x25519_bikel1, 128)
+#endif
+#ifdef OQS_ENABLE_KEM_bike_l3
+ KEMBASEALG(bikel3, 192)
+ KEMHYBALG(p384_bikel3, 192)
+ KEMHYBALG(x448_bikel3, 192)
+#endif
+#ifdef OQS_ENABLE_KEM_bike_l5
+ KEMBASEALG(bikel5, 256)
+ KEMHYBALG(p521_bikel5, 256)
+#endif
+#ifdef OQS_ENABLE_KEM_hqc_128
+ KEMBASEALG(hqc128, 128)
+ KEMHYBALG(p256_hqc128, 128)
+ KEMHYBALG(x25519_hqc128, 128)
+#endif
+#ifdef OQS_ENABLE_KEM_hqc_192
+ KEMBASEALG(hqc192, 192)
+ KEMHYBALG(p384_hqc192, 192)
+ KEMHYBALG(x448_hqc192, 192)
+#endif
+#ifdef OQS_ENABLE_KEM_hqc_256
+ KEMBASEALG(hqc256, 256)
+ KEMHYBALG(p521_hqc256, 256)
+#endif
+///// OQS_TEMPLATE_FRAGMENT_KEM_FUNCTIONS_END
+ { NULL, NULL, NULL }
+};
+
+static const OSSL_ALGORITHM oqsprovider_keymgmt[] = {
+///// OQS_TEMPLATE_FRAGMENT_KEYMGMT_FUNCTIONS_START
+#ifdef OQS_ENABLE_SIG_dilithium_2
+ SIGALG("dilithium2", 128, oqs_dilithium2_keymgmt_functions),
+ SIGALG("p256_dilithium2", 128, oqs_p256_dilithium2_keymgmt_functions),
+ SIGALG("rsa3072_dilithium2", 128, oqs_rsa3072_dilithium2_keymgmt_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_3
+ SIGALG("dilithium3", 192, oqs_dilithium3_keymgmt_functions),
+ SIGALG("p384_dilithium3", 192, oqs_p384_dilithium3_keymgmt_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_5
+ SIGALG("dilithium5", 256, oqs_dilithium5_keymgmt_functions),
+ SIGALG("p521_dilithium5", 256, oqs_p521_dilithium5_keymgmt_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_512
+ SIGALG("falcon512", 128, oqs_falcon512_keymgmt_functions),
+ SIGALG("p256_falcon512", 128, oqs_p256_falcon512_keymgmt_functions),
+ SIGALG("rsa3072_falcon512", 128, oqs_rsa3072_falcon512_keymgmt_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_1024
+ SIGALG("falcon1024", 256, oqs_falcon1024_keymgmt_functions),
+ SIGALG("p521_falcon1024", 256, oqs_p521_falcon1024_keymgmt_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128f_simple
+ SIGALG("sphincssha2128fsimple", 128, oqs_sphincssha2128fsimple_keymgmt_functions),
+ SIGALG("p256_sphincssha2128fsimple", 128, oqs_p256_sphincssha2128fsimple_keymgmt_functions),
+ SIGALG("rsa3072_sphincssha2128fsimple", 128, oqs_rsa3072_sphincssha2128fsimple_keymgmt_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128s_simple
+ SIGALG("sphincssha2128ssimple", 128, oqs_sphincssha2128ssimple_keymgmt_functions),
+ SIGALG("p256_sphincssha2128ssimple", 128, oqs_p256_sphincssha2128ssimple_keymgmt_functions),
+ SIGALG("rsa3072_sphincssha2128ssimple", 128, oqs_rsa3072_sphincssha2128ssimple_keymgmt_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_192f_simple
+ SIGALG("sphincssha2192fsimple", 192, oqs_sphincssha2192fsimple_keymgmt_functions),
+ SIGALG("p384_sphincssha2192fsimple", 192, oqs_p384_sphincssha2192fsimple_keymgmt_functions),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_shake_128f_simple
+ SIGALG("sphincsshake128fsimple", 128, oqs_sphincsshake128fsimple_keymgmt_functions),
+ SIGALG("p256_sphincsshake128fsimple", 128, oqs_p256_sphincsshake128fsimple_keymgmt_functions),
+ SIGALG("rsa3072_sphincsshake128fsimple", 128, oqs_rsa3072_sphincsshake128fsimple_keymgmt_functions),
+#endif
+
+#ifdef OQS_ENABLE_KEM_frodokem_640_aes
+ KEMKMALG(frodo640aes, 128)
+
+ KEMKMHYBALG(p256_frodo640aes, 128, ecp)
+ KEMKMHYBALG(x25519_frodo640aes, 128, ecx)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_640_shake
+ KEMKMALG(frodo640shake, 128)
+
+ KEMKMHYBALG(p256_frodo640shake, 128, ecp)
+ KEMKMHYBALG(x25519_frodo640shake, 128, ecx)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_976_aes
+ KEMKMALG(frodo976aes, 192)
+
+ KEMKMHYBALG(p384_frodo976aes, 192, ecp)
+ KEMKMHYBALG(x448_frodo976aes, 192, ecx)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_976_shake
+ KEMKMALG(frodo976shake, 192)
+
+ KEMKMHYBALG(p384_frodo976shake, 192, ecp)
+ KEMKMHYBALG(x448_frodo976shake, 192, ecx)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_1344_aes
+ KEMKMALG(frodo1344aes, 256)
+
+ KEMKMHYBALG(p521_frodo1344aes, 256, ecp)
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_1344_shake
+ KEMKMALG(frodo1344shake, 256)
+
+ KEMKMHYBALG(p521_frodo1344shake, 256, ecp)
+#endif
+#ifdef OQS_ENABLE_KEM_kyber_512
+ KEMKMALG(kyber512, 128)
+
+ KEMKMHYBALG(p256_kyber512, 128, ecp)
+ KEMKMHYBALG(x25519_kyber512, 128, ecx)
+#endif
+#ifdef OQS_ENABLE_KEM_kyber_768
+ KEMKMALG(kyber768, 192)
+
+ KEMKMHYBALG(p384_kyber768, 192, ecp)
+ KEMKMHYBALG(x448_kyber768, 192, ecx)
+ KEMKMHYBALG(x25519_kyber768, 128, ecx)
+ KEMKMHYBALG(p256_kyber768, 128, ecp)
+#endif
+#ifdef OQS_ENABLE_KEM_kyber_1024
+ KEMKMALG(kyber1024, 256)
+
+ KEMKMHYBALG(p521_kyber1024, 256, ecp)
+#endif
+#ifdef OQS_ENABLE_KEM_bike_l1
+ KEMKMALG(bikel1, 128)
+
+ KEMKMHYBALG(p256_bikel1, 128, ecp)
+ KEMKMHYBALG(x25519_bikel1, 128, ecx)
+#endif
+#ifdef OQS_ENABLE_KEM_bike_l3
+ KEMKMALG(bikel3, 192)
+
+ KEMKMHYBALG(p384_bikel3, 192, ecp)
+ KEMKMHYBALG(x448_bikel3, 192, ecx)
+#endif
+#ifdef OQS_ENABLE_KEM_bike_l5
+ KEMKMALG(bikel5, 256)
+
+ KEMKMHYBALG(p521_bikel5, 256, ecp)
+#endif
+#ifdef OQS_ENABLE_KEM_hqc_128
+ KEMKMALG(hqc128, 128)
+
+ KEMKMHYBALG(p256_hqc128, 128, ecp)
+ KEMKMHYBALG(x25519_hqc128, 128, ecx)
+#endif
+#ifdef OQS_ENABLE_KEM_hqc_192
+ KEMKMALG(hqc192, 192)
+
+ KEMKMHYBALG(p384_hqc192, 192, ecp)
+ KEMKMHYBALG(x448_hqc192, 192, ecx)
+#endif
+#ifdef OQS_ENABLE_KEM_hqc_256
+ KEMKMALG(hqc256, 256)
+
+ KEMKMHYBALG(p521_hqc256, 256, ecp)
+#endif
+///// OQS_TEMPLATE_FRAGMENT_KEYMGMT_FUNCTIONS_END
+ //ALG("x25519_sikep434", oqs_ecx_sikep434_keymgmt_functions),
+ { NULL, NULL, NULL }
+};
+
+static const OSSL_ALGORITHM oqsprovider_encoder[] = {
+#define ENCODER_PROVIDER "oqsprovider"
+#include "oqsencoders.inc"
+ { NULL, NULL, NULL }
+#undef ENCODER_PROVIDER
+};
+
+static const OSSL_ALGORITHM oqsprovider_decoder[] = {
+#define DECODER_PROVIDER "oqsprovider"
+#include "oqsdecoders.inc"
+ { NULL, NULL, NULL }
+#undef DECODER_PROVIDER
+};
+
+
+static const OSSL_PARAM *oqsprovider_gettable_params(void *provctx)
+{
+ return oqsprovider_param_types;
+}
+
+#define OQS_PROVIDER_BASE_BUILD_INFO_STR "OQS Provider v." OQS_PROVIDER_VERSION_STR OQS_PROVIDER_COMMIT " based on liboqs v." OQS_VERSION_TEXT
+
+#ifdef QSC_ENCODING_VERSION_STRING
+#define OQS_PROVIDER_BUILD_INFO_STR OQS_PROVIDER_BASE_BUILD_INFO_STR " using qsc-key-encoder v." QSC_ENCODING_VERSION_STRING
+#else
+#define OQS_PROVIDER_BUILD_INFO_STR OQS_PROVIDER_BASE_BUILD_INFO_STR
+#endif
+
+
+static int oqsprovider_get_params(void *provctx, OSSL_PARAM params[])
+{
+ OSSL_PARAM *p;
+
+ p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
+ if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL OQS Provider"))
+ return 0;
+ p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
+ if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OQS_PROVIDER_VERSION_STR))
+ return 0;
+ p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_BUILDINFO);
+ if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OQS_PROVIDER_BUILD_INFO_STR))
+ return 0;
+ p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS);
+ if (p != NULL && !OSSL_PARAM_set_int(p, 1)) // provider is always running
+ return 0;
+ return 1;
+}
+
+static const OSSL_ALGORITHM *oqsprovider_query(void *provctx, int operation_id,
+ int *no_cache)
+{
+ *no_cache = 0;
+
+ switch (operation_id) {
+ case OSSL_OP_SIGNATURE:
+ return oqsprovider_signatures;
+ case OSSL_OP_KEM:
+ return oqsprovider_asym_kems;
+ case OSSL_OP_KEYMGMT:
+ return oqsprovider_keymgmt;
+ case OSSL_OP_ENCODER:
+ return oqsprovider_encoder;
+ case OSSL_OP_DECODER:
+ return oqsprovider_decoder;
+ default:
+ if (getenv("OQSPROV")) printf("Unknown operation %d requested from OQS provider\n", operation_id);
+ }
+ return NULL;
+}
+
+static void oqsprovider_teardown(void *provctx)
+{
+ oqsx_freeprovctx((PROV_OQS_CTX*)provctx);
+ OQS_destroy();
+}
+
+/* Functions we provide to the core */
+static const OSSL_DISPATCH oqsprovider_dispatch_table[] = {
+ { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))oqsprovider_teardown },
+ { OSSL_FUNC_PROVIDER_GETTABLE_PARAMS, (void (*)(void))oqsprovider_gettable_params },
+ { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))oqsprovider_get_params },
+ { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))oqsprovider_query },
+ { OSSL_FUNC_PROVIDER_GET_CAPABILITIES, (void (*)(void))oqs_provider_get_capabilities },
+ { 0, NULL }
+};
+
+#ifdef OQS_PROVIDER_STATIC
+#define OQS_PROVIDER_ENTRYPOINT_NAME oqs_provider_init
+#else
+#define OQS_PROVIDER_ENTRYPOINT_NAME OSSL_provider_init
+#endif // ifdef OQS_PROVIDER_STATIC
+
+int OQS_PROVIDER_ENTRYPOINT_NAME(const OSSL_CORE_HANDLE *handle,
+ const OSSL_DISPATCH *in,
+ const OSSL_DISPATCH **out,
+ void **provctx)
+{
+ const OSSL_DISPATCH *orig_in=in;
+ OSSL_FUNC_core_obj_create_fn *c_obj_create= NULL;
+
+ OSSL_FUNC_core_obj_add_sigid_fn *c_obj_add_sigid= NULL;
+ BIO_METHOD *corebiometh;
+ OSSL_LIB_CTX *libctx = NULL;
+ int i, rc = 0;
+
+ OQS_init();
+
+ if (!oqs_prov_bio_from_dispatch(in))
+ return 0;
+
+ if (!oqs_patch_codepoints())
+ return 0;
+
+ if (!oqs_patch_oids())
+ return 0;
+
+#ifdef USE_ENCODING_LIB
+ if (!oqs_patch_encodings())
+ return 0;
+#endif
+
+ for (; in->function_id != 0; in++) {
+ switch (in->function_id) {
+ case OSSL_FUNC_CORE_GETTABLE_PARAMS:
+ c_gettable_params = OSSL_FUNC_core_gettable_params(in);
+ break;
+ case OSSL_FUNC_CORE_GET_PARAMS:
+ c_get_params = OSSL_FUNC_core_get_params(in);
+ break;
+ case OSSL_FUNC_CORE_OBJ_CREATE:
+ c_obj_create = OSSL_FUNC_core_obj_create(in);
+ break;
+ case OSSL_FUNC_CORE_OBJ_ADD_SIGID:
+ c_obj_add_sigid = OSSL_FUNC_core_obj_add_sigid(in);
+ break;
+ /* Just ignore anything we don't understand */
+ default:
+ break;
+ }
+ }
+
+ // we need these functions:
+ if (c_obj_create == NULL || c_obj_add_sigid==NULL)
+ return 0;
+
+ // insert all OIDs to the global objects list
+ for (i=0; i<OQS_OID_CNT;i+=2) {
+ if (!c_obj_create(handle, oqs_oid_alg_list[i], oqs_oid_alg_list[i+1], oqs_oid_alg_list[i+1])) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_OBJ_CREATE_ERR);
+ fprintf(stderr, "error registering NID for %s\n", oqs_oid_alg_list[i+1]);
+ return 0;
+ }
+
+ if (!oqs_set_nid((char*)oqs_oid_alg_list[i+1], OBJ_sn2nid(oqs_oid_alg_list[i+1]))) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_OBJ_CREATE_ERR);
+ return 0;
+ }
+
+ if (!c_obj_add_sigid(handle, oqs_oid_alg_list[i+1], "", oqs_oid_alg_list[i+1])) {
+ fprintf(stderr, "error registering %s with no hash\n", oqs_oid_alg_list[i+1]);
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_OBJ_CREATE_ERR);
+ return 0;
+ }
+
+ if (OBJ_sn2nid(oqs_oid_alg_list[i+1]) != 0) {
+ OQS_PROV_PRINTF3("OQS PROV: successfully registered %s with NID %d\n", oqs_oid_alg_list[i+1], OBJ_sn2nid(oqs_oid_alg_list[i+1]));
+ }
+ else {
+ fprintf(stderr, "OQS PROV: Impossible error: NID unregistered for %s.\n", oqs_oid_alg_list[i+1]);
+ return 0;
+ }
+
+ }
+
+ // if libctx not yet existing, create a new one
+ if ( ((corebiometh = oqs_bio_prov_init_bio_method()) == NULL) ||
+ ((libctx = OSSL_LIB_CTX_new_child(handle, orig_in)) == NULL) ||
+ ((*provctx = oqsx_newprovctx(libctx, handle, corebiometh)) == NULL ) ) {
+ OQS_PROV_PRINTF("OQS PROV: error creating new provider context\n");
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_LIB_CREATE_ERR);
+ goto end_init;
+ }
+
+ *out = oqsprovider_dispatch_table;
+
+ // finally, warn if neither default nor fips provider are present:
+ if (!OSSL_PROVIDER_available(libctx, "default") && !OSSL_PROVIDER_available(libctx, "fips")) {
+ OQS_PROV_PRINTF("OQS PROV: Default and FIPS provider not available. Errors may result.\n");
+ }
+ else {
+ OQS_PROV_PRINTF("OQS PROV: Default or FIPS provider available.\n");
+ }
+ rc = 1;
+
+end_init:
+ if (!rc) {
+ OSSL_LIB_CTX_free(libctx);
+ oqsprovider_teardown(*provctx);
+ *provctx = NULL;
+ }
+ return rc;
+}
--- /dev/null
+EXPORTS
+ OSSL_provider_init
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+// Code strongly inspired by OpenSSL common provider bio code
+
+#include <assert.h>
+#include <openssl/core_dispatch.h>
+//#include "internal/cryptlib.h"
+#include "oqs_prov.h"
+
+static OSSL_FUNC_BIO_new_file_fn *c_bio_new_file = NULL;
+static OSSL_FUNC_BIO_new_membuf_fn *c_bio_new_membuf = NULL;
+static OSSL_FUNC_BIO_read_ex_fn *c_bio_read_ex = NULL;
+static OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex = NULL;
+static OSSL_FUNC_BIO_gets_fn *c_bio_gets = NULL;
+static OSSL_FUNC_BIO_puts_fn *c_bio_puts = NULL;
+static OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl = NULL;
+static OSSL_FUNC_BIO_up_ref_fn *c_bio_up_ref = NULL;
+static OSSL_FUNC_BIO_free_fn *c_bio_free = NULL;
+static OSSL_FUNC_BIO_vprintf_fn *c_bio_vprintf = NULL;
+
+int oqs_prov_bio_from_dispatch(const OSSL_DISPATCH *fns)
+{
+ for (; fns->function_id != 0; fns++) {
+ switch (fns->function_id) {
+ case OSSL_FUNC_BIO_NEW_FILE:
+ if (c_bio_new_file == NULL)
+ c_bio_new_file = OSSL_FUNC_BIO_new_file(fns);
+ break;
+ case OSSL_FUNC_BIO_NEW_MEMBUF:
+ if (c_bio_new_membuf == NULL)
+ c_bio_new_membuf = OSSL_FUNC_BIO_new_membuf(fns);
+ break;
+ case OSSL_FUNC_BIO_READ_EX:
+ if (c_bio_read_ex == NULL)
+ c_bio_read_ex = OSSL_FUNC_BIO_read_ex(fns);
+ break;
+ case OSSL_FUNC_BIO_WRITE_EX:
+ if (c_bio_write_ex == NULL)
+ c_bio_write_ex = OSSL_FUNC_BIO_write_ex(fns);
+ break;
+ case OSSL_FUNC_BIO_GETS:
+ if (c_bio_gets == NULL)
+ c_bio_gets = OSSL_FUNC_BIO_gets(fns);
+ break;
+ case OSSL_FUNC_BIO_PUTS:
+ if (c_bio_puts == NULL)
+ c_bio_puts = OSSL_FUNC_BIO_puts(fns);
+ break;
+ case OSSL_FUNC_BIO_CTRL:
+ if (c_bio_ctrl == NULL)
+ c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns);
+ break;
+ case OSSL_FUNC_BIO_UP_REF:
+ if (c_bio_up_ref == NULL)
+ c_bio_up_ref = OSSL_FUNC_BIO_up_ref(fns);
+ break;
+ case OSSL_FUNC_BIO_FREE:
+ if (c_bio_free == NULL)
+ c_bio_free = OSSL_FUNC_BIO_free(fns);
+ break;
+ case OSSL_FUNC_BIO_VPRINTF:
+ if (c_bio_vprintf == NULL)
+ c_bio_vprintf = OSSL_FUNC_BIO_vprintf(fns);
+ break;
+ }
+ }
+
+ return 1;
+}
+
+OSSL_CORE_BIO *oqs_prov_bio_new_file(const char *filename, const char *mode)
+{
+ if (c_bio_new_file == NULL)
+ return NULL;
+ return c_bio_new_file(filename, mode);
+}
+
+OSSL_CORE_BIO *oqs_prov_bio_new_membuf(const char *filename, int len)
+{
+ if (c_bio_new_membuf == NULL)
+ return NULL;
+ return c_bio_new_membuf(filename, len);
+}
+
+int oqs_prov_bio_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len,
+ size_t *bytes_read)
+{
+ if (c_bio_read_ex == NULL)
+ return 0;
+ return c_bio_read_ex(bio, data, data_len, bytes_read);
+}
+
+int oqs_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len,
+ size_t *written)
+{
+ if (c_bio_write_ex == NULL)
+ return 0;
+ return c_bio_write_ex(bio, data, data_len, written);
+}
+
+int oqs_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size)
+{
+ if (c_bio_gets == NULL)
+ return -1;
+ return c_bio_gets(bio, buf, size);
+}
+
+int oqs_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str)
+{
+ if (c_bio_puts == NULL)
+ return -1;
+ return c_bio_puts(bio, str);
+}
+
+int oqs_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr)
+{
+ if (c_bio_ctrl == NULL)
+ return -1;
+ return c_bio_ctrl(bio, cmd, num, ptr);
+}
+
+int oqs_prov_bio_up_ref(OSSL_CORE_BIO *bio)
+{
+ if (c_bio_up_ref == NULL)
+ return 0;
+ return c_bio_up_ref(bio);
+}
+
+int oqs_prov_bio_free(OSSL_CORE_BIO *bio)
+{
+ if (c_bio_free == NULL)
+ return 0;
+ return c_bio_free(bio);
+}
+
+int oqs_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap)
+{
+ if (c_bio_vprintf == NULL)
+ return -1;
+ return c_bio_vprintf(bio, format, ap);
+}
+
+int oqs_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, format);
+ ret = oqs_prov_bio_vprintf(bio, format, ap);
+ va_end(ap);
+
+ return ret;
+}
+
+#ifndef FIPS_MODULE
+
+/* No direct BIO support in the FIPS module */
+
+static int bio_core_read_ex(BIO *bio, char *data, size_t data_len,
+ size_t *bytes_read)
+{
+ return oqs_prov_bio_read_ex(BIO_get_data(bio), data, data_len, bytes_read);
+}
+
+static int bio_core_write_ex(BIO *bio, const char *data, size_t data_len,
+ size_t *written)
+{
+ return oqs_prov_bio_write_ex(BIO_get_data(bio), data, data_len, written);
+}
+
+static long bio_core_ctrl(BIO *bio, int cmd, long num, void *ptr)
+{
+ return oqs_prov_bio_ctrl(BIO_get_data(bio), cmd, num, ptr);
+}
+
+static int bio_core_gets(BIO *bio, char *buf, int size)
+{
+ return oqs_prov_bio_gets(BIO_get_data(bio), buf, size);
+}
+
+static int bio_core_puts(BIO *bio, const char *str)
+{
+ return oqs_prov_bio_puts(BIO_get_data(bio), str);
+}
+
+static int bio_core_new(BIO *bio)
+{
+ BIO_set_init(bio, 1);
+
+ return 1;
+}
+
+static int bio_core_free(BIO *bio)
+{
+ BIO_set_init(bio, 0);
+ oqs_prov_bio_free(BIO_get_data(bio));
+
+ return 1;
+}
+
+BIO_METHOD *oqs_bio_prov_init_bio_method(void)
+{
+ BIO_METHOD *corebiometh = NULL;
+
+ corebiometh = BIO_meth_new(BIO_TYPE_CORE_TO_PROV, "BIO to Core filter");
+ if (corebiometh == NULL
+ || !BIO_meth_set_write_ex(corebiometh, bio_core_write_ex)
+ || !BIO_meth_set_read_ex(corebiometh, bio_core_read_ex)
+ || !BIO_meth_set_puts(corebiometh, bio_core_puts)
+ || !BIO_meth_set_gets(corebiometh, bio_core_gets)
+ || !BIO_meth_set_ctrl(corebiometh, bio_core_ctrl)
+ || !BIO_meth_set_create(corebiometh, bio_core_new)
+ || !BIO_meth_set_destroy(corebiometh, bio_core_free)) {
+ BIO_meth_free(corebiometh);
+ return NULL;
+ }
+
+ return corebiometh;
+}
+
+BIO *oqs_bio_new_from_core_bio(PROV_OQS_CTX *provctx, OSSL_CORE_BIO *corebio)
+{
+ BIO *outbio;
+ BIO_METHOD *corebiometh = provctx->corebiometh;
+
+ if (corebiometh == NULL)
+ return NULL;
+
+ if ((outbio = BIO_new(corebiometh)) == NULL)
+ return NULL;
+ if (!oqs_prov_bio_up_ref(corebio)) {
+ BIO_free(outbio);
+ return NULL;
+ }
+ BIO_set_data(outbio, corebio);
+ return outbio;
+}
+
+#endif
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 provider
+ *
+ * Code strongly inspired by OpenSSL common provider capabilities.
+ *
+ * ToDo: Interop testing.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <openssl/core_dispatch.h>
+#include <openssl/core_names.h>
+
+/* For TLS1_VERSION etc */
+#include <openssl/ssl.h>
+#include <openssl/params.h>
+
+// internal, but useful OSSL define:
+# define OSSL_NELEM(x) (sizeof(x)/sizeof((x)[0]))
+
+#include "oqs_prov.h"
+
+typedef struct oqs_group_constants_st {
+ unsigned int group_id; /* Group ID */
+ unsigned int secbits; /* Bits of security */
+ int mintls; /* Minimum TLS version, -1 unsupported */
+ int maxtls; /* Maximum TLS version (or 0 for undefined) */
+ int mindtls; /* Minimum DTLS version, -1 unsupported */
+ int maxdtls; /* Maximum DTLS version (or 0 for undefined) */
+ int is_kem; /* Always set */
+} OQS_GROUP_CONSTANTS;
+
+static OQS_GROUP_CONSTANTS oqs_group_list[] = {
+ // ad-hoc assignments - take from OQS generate data structures
+///// OQS_TEMPLATE_FRAGMENT_GROUP_ASSIGNMENTS_START
+ { 0x0200, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F00, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2F80, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x0201, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F01, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2F81, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x0202, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F02, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2F82, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x0203, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F03, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2F83, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x0204, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F04, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x0205, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F05, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x023A, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F3A, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2F39, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x023C, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F3C, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2F90, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x6399, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x639A, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x023D, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F3D, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x0241, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F41, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2FAE, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x0242, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F42, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2FAF, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x0243, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F43, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x022C, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F2C, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2FAC, 128, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x022D, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F2D, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x2FAD, 192, TLS1_3_VERSION, 0, -1, -1, 1 },
+ { 0x022E, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+
+ { 0x2F2E, 256, TLS1_3_VERSION, 0, -1, -1, 1 },
+///// OQS_TEMPLATE_FRAGMENT_GROUP_ASSIGNMENTS_END
+};
+
+// Adds entries for tlsname, `ecx`_tlsname and `ecp`_tlsname
+#define OQS_GROUP_ENTRY(tlsname, realname, algorithm, idx) \
+ { \
+ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME, \
+ #tlsname, \
+ sizeof(#tlsname)), \
+ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_NAME_INTERNAL, \
+ #realname, \
+ sizeof(#realname)), \
+ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_GROUP_ALG, \
+ #algorithm, \
+ sizeof(#algorithm)), \
+ OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_ID, \
+ (unsigned int *)&oqs_group_list[idx].group_id), \
+ OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, \
+ (unsigned int *)&oqs_group_list[idx].secbits), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, \
+ (unsigned int *)&oqs_group_list[idx].mintls), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, \
+ (unsigned int *)&oqs_group_list[idx].maxtls), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, \
+ (unsigned int *)&oqs_group_list[idx].mindtls), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, \
+ (unsigned int *)&oqs_group_list[idx].maxdtls), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, \
+ (unsigned int *)&oqs_group_list[idx].is_kem), \
+ OSSL_PARAM_END \
+ }
+
+static const OSSL_PARAM oqs_param_group_list[][11] = {
+///// OQS_TEMPLATE_FRAGMENT_GROUP_NAMES_START
+
+#ifdef OQS_ENABLE_KEM_frodokem_640_aes
+ OQS_GROUP_ENTRY(frodo640aes, frodo640aes, frodo640aes, 0),
+
+ OQS_GROUP_ENTRY(p256_frodo640aes, p256_frodo640aes, p256_frodo640aes, 1),
+ OQS_GROUP_ENTRY(x25519_frodo640aes, x25519_frodo640aes, x25519_frodo640aes, 2),
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_640_shake
+ OQS_GROUP_ENTRY(frodo640shake, frodo640shake, frodo640shake, 3),
+
+ OQS_GROUP_ENTRY(p256_frodo640shake, p256_frodo640shake, p256_frodo640shake, 4),
+ OQS_GROUP_ENTRY(x25519_frodo640shake, x25519_frodo640shake, x25519_frodo640shake, 5),
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_976_aes
+ OQS_GROUP_ENTRY(frodo976aes, frodo976aes, frodo976aes, 6),
+
+ OQS_GROUP_ENTRY(p384_frodo976aes, p384_frodo976aes, p384_frodo976aes, 7),
+ OQS_GROUP_ENTRY(x448_frodo976aes, x448_frodo976aes, x448_frodo976aes, 8),
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_976_shake
+ OQS_GROUP_ENTRY(frodo976shake, frodo976shake, frodo976shake, 9),
+
+ OQS_GROUP_ENTRY(p384_frodo976shake, p384_frodo976shake, p384_frodo976shake, 10),
+ OQS_GROUP_ENTRY(x448_frodo976shake, x448_frodo976shake, x448_frodo976shake, 11),
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_1344_aes
+ OQS_GROUP_ENTRY(frodo1344aes, frodo1344aes, frodo1344aes, 12),
+
+ OQS_GROUP_ENTRY(p521_frodo1344aes, p521_frodo1344aes, p521_frodo1344aes, 13),
+#endif
+#ifdef OQS_ENABLE_KEM_frodokem_1344_shake
+ OQS_GROUP_ENTRY(frodo1344shake, frodo1344shake, frodo1344shake, 14),
+
+ OQS_GROUP_ENTRY(p521_frodo1344shake, p521_frodo1344shake, p521_frodo1344shake, 15),
+#endif
+#ifdef OQS_ENABLE_KEM_kyber_512
+ OQS_GROUP_ENTRY(kyber512, kyber512, kyber512, 16),
+
+ OQS_GROUP_ENTRY(p256_kyber512, p256_kyber512, p256_kyber512, 17),
+ OQS_GROUP_ENTRY(x25519_kyber512, x25519_kyber512, x25519_kyber512, 18),
+#endif
+#ifdef OQS_ENABLE_KEM_kyber_768
+ OQS_GROUP_ENTRY(kyber768, kyber768, kyber768, 19),
+
+ OQS_GROUP_ENTRY(p384_kyber768, p384_kyber768, p384_kyber768, 20),
+ OQS_GROUP_ENTRY(x448_kyber768, x448_kyber768, x448_kyber768, 21),
+ OQS_GROUP_ENTRY(x25519_kyber768, x25519_kyber768, x25519_kyber768, 22),
+ OQS_GROUP_ENTRY(p256_kyber768, p256_kyber768, p256_kyber768, 23),
+#endif
+#ifdef OQS_ENABLE_KEM_kyber_1024
+ OQS_GROUP_ENTRY(kyber1024, kyber1024, kyber1024, 24),
+
+ OQS_GROUP_ENTRY(p521_kyber1024, p521_kyber1024, p521_kyber1024, 25),
+#endif
+#ifdef OQS_ENABLE_KEM_bike_l1
+ OQS_GROUP_ENTRY(bikel1, bikel1, bikel1, 26),
+
+ OQS_GROUP_ENTRY(p256_bikel1, p256_bikel1, p256_bikel1, 27),
+ OQS_GROUP_ENTRY(x25519_bikel1, x25519_bikel1, x25519_bikel1, 28),
+#endif
+#ifdef OQS_ENABLE_KEM_bike_l3
+ OQS_GROUP_ENTRY(bikel3, bikel3, bikel3, 29),
+
+ OQS_GROUP_ENTRY(p384_bikel3, p384_bikel3, p384_bikel3, 30),
+ OQS_GROUP_ENTRY(x448_bikel3, x448_bikel3, x448_bikel3, 31),
+#endif
+#ifdef OQS_ENABLE_KEM_bike_l5
+ OQS_GROUP_ENTRY(bikel5, bikel5, bikel5, 32),
+
+ OQS_GROUP_ENTRY(p521_bikel5, p521_bikel5, p521_bikel5, 33),
+#endif
+#ifdef OQS_ENABLE_KEM_hqc_128
+ OQS_GROUP_ENTRY(hqc128, hqc128, hqc128, 34),
+
+ OQS_GROUP_ENTRY(p256_hqc128, p256_hqc128, p256_hqc128, 35),
+ OQS_GROUP_ENTRY(x25519_hqc128, x25519_hqc128, x25519_hqc128, 36),
+#endif
+#ifdef OQS_ENABLE_KEM_hqc_192
+ OQS_GROUP_ENTRY(hqc192, hqc192, hqc192, 37),
+
+ OQS_GROUP_ENTRY(p384_hqc192, p384_hqc192, p384_hqc192, 38),
+ OQS_GROUP_ENTRY(x448_hqc192, x448_hqc192, x448_hqc192, 39),
+#endif
+#ifdef OQS_ENABLE_KEM_hqc_256
+ OQS_GROUP_ENTRY(hqc256, hqc256, hqc256, 40),
+
+ OQS_GROUP_ENTRY(p521_hqc256, p521_hqc256, p521_hqc256, 41),
+#endif
+///// OQS_TEMPLATE_FRAGMENT_GROUP_NAMES_END
+};
+
+typedef struct oqs_sigalg_constants_st {
+ unsigned int code_point; /* Code point */
+ unsigned int secbits; /* Bits of security */
+ int mintls; /* Minimum TLS version, -1 unsupported */
+ int maxtls; /* Maximum TLS version (or 0 for undefined) */
+} OQS_SIGALG_CONSTANTS;
+
+static OQS_SIGALG_CONSTANTS oqs_sigalg_list[] = {
+ // ad-hoc assignments - take from OQS generate data structures
+///// OQS_TEMPLATE_FRAGMENT_SIGALG_ASSIGNMENTS_START
+ { 0xfea0, 128, TLS1_3_VERSION, 0 },
+ { 0xfea1, 128, TLS1_3_VERSION, 0 },
+ { 0xfea2, 128, TLS1_3_VERSION, 0 },
+ { 0xfea3, 192, TLS1_3_VERSION, 0 },
+ { 0xfea4, 192, TLS1_3_VERSION, 0 },
+ { 0xfea5, 256, TLS1_3_VERSION, 0 },
+ { 0xfea6, 256, TLS1_3_VERSION, 0 },
+ { 0xfeae, 128, TLS1_3_VERSION, 0 },
+ { 0xfeaf, 128, TLS1_3_VERSION, 0 },
+ { 0xfeb0, 128, TLS1_3_VERSION, 0 },
+ { 0xfeb1, 256, TLS1_3_VERSION, 0 },
+ { 0xfeb2, 256, TLS1_3_VERSION, 0 },
+ { 0xfeb3, 128, TLS1_3_VERSION, 0 },
+ { 0xfeb4, 128, TLS1_3_VERSION, 0 },
+ { 0xfeb5, 128, TLS1_3_VERSION, 0 },
+ { 0xfeb6, 128, TLS1_3_VERSION, 0 },
+ { 0xfeb7, 128, TLS1_3_VERSION, 0 },
+ { 0xfeb8, 128, TLS1_3_VERSION, 0 },
+ { 0xfeb9, 192, TLS1_3_VERSION, 0 },
+ { 0xfeba, 192, TLS1_3_VERSION, 0 },
+ { 0xfec2, 128, TLS1_3_VERSION, 0 },
+ { 0xfec3, 128, TLS1_3_VERSION, 0 },
+ { 0xfec4, 128, TLS1_3_VERSION, 0 },
+///// OQS_TEMPLATE_FRAGMENT_SIGALG_ASSIGNMENTS_END
+};
+
+int oqs_patch_codepoints() {
+
+///// OQS_TEMPLATE_FRAGMENT_CODEPOINT_PATCHING_START
+ if (getenv("OQS_CODEPOINT_FRODO640AES")) oqs_group_list[0].group_id = atoi(getenv("OQS_CODEPOINT_FRODO640AES"));
+ if (getenv("OQS_CODEPOINT_P256_FRODO640AES")) oqs_group_list[1].group_id = atoi(getenv("OQS_CODEPOINT_P256_FRODO640AES"));
+ if (getenv("OQS_CODEPOINT_X25519_FRODO640AES")) oqs_group_list[2].group_id = atoi(getenv("OQS_CODEPOINT_X25519_FRODO640AES"));
+ if (getenv("OQS_CODEPOINT_FRODO640SHAKE")) oqs_group_list[3].group_id = atoi(getenv("OQS_CODEPOINT_FRODO640SHAKE"));
+ if (getenv("OQS_CODEPOINT_P256_FRODO640SHAKE")) oqs_group_list[4].group_id = atoi(getenv("OQS_CODEPOINT_P256_FRODO640SHAKE"));
+ if (getenv("OQS_CODEPOINT_X25519_FRODO640SHAKE")) oqs_group_list[5].group_id = atoi(getenv("OQS_CODEPOINT_X25519_FRODO640SHAKE"));
+ if (getenv("OQS_CODEPOINT_FRODO976AES")) oqs_group_list[6].group_id = atoi(getenv("OQS_CODEPOINT_FRODO976AES"));
+ if (getenv("OQS_CODEPOINT_P384_FRODO976AES")) oqs_group_list[7].group_id = atoi(getenv("OQS_CODEPOINT_P384_FRODO976AES"));
+ if (getenv("OQS_CODEPOINT_X448_FRODO976AES")) oqs_group_list[8].group_id = atoi(getenv("OQS_CODEPOINT_X448_FRODO976AES"));
+ if (getenv("OQS_CODEPOINT_FRODO976SHAKE")) oqs_group_list[9].group_id = atoi(getenv("OQS_CODEPOINT_FRODO976SHAKE"));
+ if (getenv("OQS_CODEPOINT_P384_FRODO976SHAKE")) oqs_group_list[10].group_id = atoi(getenv("OQS_CODEPOINT_P384_FRODO976SHAKE"));
+ if (getenv("OQS_CODEPOINT_X448_FRODO976SHAKE")) oqs_group_list[11].group_id = atoi(getenv("OQS_CODEPOINT_X448_FRODO976SHAKE"));
+ if (getenv("OQS_CODEPOINT_FRODO1344AES")) oqs_group_list[12].group_id = atoi(getenv("OQS_CODEPOINT_FRODO1344AES"));
+ if (getenv("OQS_CODEPOINT_P521_FRODO1344AES")) oqs_group_list[13].group_id = atoi(getenv("OQS_CODEPOINT_P521_FRODO1344AES"));
+ if (getenv("OQS_CODEPOINT_FRODO1344SHAKE")) oqs_group_list[14].group_id = atoi(getenv("OQS_CODEPOINT_FRODO1344SHAKE"));
+ if (getenv("OQS_CODEPOINT_P521_FRODO1344SHAKE")) oqs_group_list[15].group_id = atoi(getenv("OQS_CODEPOINT_P521_FRODO1344SHAKE"));
+ if (getenv("OQS_CODEPOINT_KYBER512")) oqs_group_list[16].group_id = atoi(getenv("OQS_CODEPOINT_KYBER512"));
+ if (getenv("OQS_CODEPOINT_P256_KYBER512")) oqs_group_list[17].group_id = atoi(getenv("OQS_CODEPOINT_P256_KYBER512"));
+ if (getenv("OQS_CODEPOINT_X25519_KYBER512")) oqs_group_list[18].group_id = atoi(getenv("OQS_CODEPOINT_X25519_KYBER512"));
+ if (getenv("OQS_CODEPOINT_KYBER768")) oqs_group_list[19].group_id = atoi(getenv("OQS_CODEPOINT_KYBER768"));
+ if (getenv("OQS_CODEPOINT_P384_KYBER768")) oqs_group_list[20].group_id = atoi(getenv("OQS_CODEPOINT_P384_KYBER768"));
+ if (getenv("OQS_CODEPOINT_X448_KYBER768")) oqs_group_list[21].group_id = atoi(getenv("OQS_CODEPOINT_X448_KYBER768"));
+ if (getenv("OQS_CODEPOINT_X25519_KYBER768")) oqs_group_list[22].group_id = atoi(getenv("OQS_CODEPOINT_X25519_KYBER768"));
+ if (getenv("OQS_CODEPOINT_P256_KYBER768")) oqs_group_list[23].group_id = atoi(getenv("OQS_CODEPOINT_P256_KYBER768"));
+ if (getenv("OQS_CODEPOINT_KYBER1024")) oqs_group_list[24].group_id = atoi(getenv("OQS_CODEPOINT_KYBER1024"));
+ if (getenv("OQS_CODEPOINT_P521_KYBER1024")) oqs_group_list[25].group_id = atoi(getenv("OQS_CODEPOINT_P521_KYBER1024"));
+ if (getenv("OQS_CODEPOINT_BIKEL1")) oqs_group_list[26].group_id = atoi(getenv("OQS_CODEPOINT_BIKEL1"));
+ if (getenv("OQS_CODEPOINT_P256_BIKEL1")) oqs_group_list[27].group_id = atoi(getenv("OQS_CODEPOINT_P256_BIKEL1"));
+ if (getenv("OQS_CODEPOINT_X25519_BIKEL1")) oqs_group_list[28].group_id = atoi(getenv("OQS_CODEPOINT_X25519_BIKEL1"));
+ if (getenv("OQS_CODEPOINT_BIKEL3")) oqs_group_list[29].group_id = atoi(getenv("OQS_CODEPOINT_BIKEL3"));
+ if (getenv("OQS_CODEPOINT_P384_BIKEL3")) oqs_group_list[30].group_id = atoi(getenv("OQS_CODEPOINT_P384_BIKEL3"));
+ if (getenv("OQS_CODEPOINT_X448_BIKEL3")) oqs_group_list[31].group_id = atoi(getenv("OQS_CODEPOINT_X448_BIKEL3"));
+ if (getenv("OQS_CODEPOINT_BIKEL5")) oqs_group_list[32].group_id = atoi(getenv("OQS_CODEPOINT_BIKEL5"));
+ if (getenv("OQS_CODEPOINT_P521_BIKEL5")) oqs_group_list[33].group_id = atoi(getenv("OQS_CODEPOINT_P521_BIKEL5"));
+ if (getenv("OQS_CODEPOINT_HQC128")) oqs_group_list[34].group_id = atoi(getenv("OQS_CODEPOINT_HQC128"));
+ if (getenv("OQS_CODEPOINT_P256_HQC128")) oqs_group_list[35].group_id = atoi(getenv("OQS_CODEPOINT_P256_HQC128"));
+ if (getenv("OQS_CODEPOINT_X25519_HQC128")) oqs_group_list[36].group_id = atoi(getenv("OQS_CODEPOINT_X25519_HQC128"));
+ if (getenv("OQS_CODEPOINT_HQC192")) oqs_group_list[37].group_id = atoi(getenv("OQS_CODEPOINT_HQC192"));
+ if (getenv("OQS_CODEPOINT_P384_HQC192")) oqs_group_list[38].group_id = atoi(getenv("OQS_CODEPOINT_P384_HQC192"));
+ if (getenv("OQS_CODEPOINT_X448_HQC192")) oqs_group_list[39].group_id = atoi(getenv("OQS_CODEPOINT_X448_HQC192"));
+ if (getenv("OQS_CODEPOINT_HQC256")) oqs_group_list[40].group_id = atoi(getenv("OQS_CODEPOINT_HQC256"));
+ if (getenv("OQS_CODEPOINT_P521_HQC256")) oqs_group_list[41].group_id = atoi(getenv("OQS_CODEPOINT_P521_HQC256"));
+
+ if (getenv("OQS_CODEPOINT_DILITHIUM2")) oqs_sigalg_list[0].code_point = atoi(getenv("OQS_CODEPOINT_DILITHIUM2"));
+ if (getenv("OQS_CODEPOINT_P256_DILITHIUM2")) oqs_sigalg_list[1].code_point = atoi(getenv("OQS_CODEPOINT_P256_DILITHIUM2"));
+ if (getenv("OQS_CODEPOINT_RSA3072_DILITHIUM2")) oqs_sigalg_list[2].code_point = atoi(getenv("OQS_CODEPOINT_RSA3072_DILITHIUM2"));
+ if (getenv("OQS_CODEPOINT_DILITHIUM3")) oqs_sigalg_list[3].code_point = atoi(getenv("OQS_CODEPOINT_DILITHIUM3"));
+ if (getenv("OQS_CODEPOINT_P384_DILITHIUM3")) oqs_sigalg_list[4].code_point = atoi(getenv("OQS_CODEPOINT_P384_DILITHIUM3"));
+ if (getenv("OQS_CODEPOINT_DILITHIUM5")) oqs_sigalg_list[5].code_point = atoi(getenv("OQS_CODEPOINT_DILITHIUM5"));
+ if (getenv("OQS_CODEPOINT_P521_DILITHIUM5")) oqs_sigalg_list[6].code_point = atoi(getenv("OQS_CODEPOINT_P521_DILITHIUM5"));
+ if (getenv("OQS_CODEPOINT_FALCON512")) oqs_sigalg_list[7].code_point = atoi(getenv("OQS_CODEPOINT_FALCON512"));
+ if (getenv("OQS_CODEPOINT_P256_FALCON512")) oqs_sigalg_list[8].code_point = atoi(getenv("OQS_CODEPOINT_P256_FALCON512"));
+ if (getenv("OQS_CODEPOINT_RSA3072_FALCON512")) oqs_sigalg_list[9].code_point = atoi(getenv("OQS_CODEPOINT_RSA3072_FALCON512"));
+ if (getenv("OQS_CODEPOINT_FALCON1024")) oqs_sigalg_list[10].code_point = atoi(getenv("OQS_CODEPOINT_FALCON1024"));
+ if (getenv("OQS_CODEPOINT_P521_FALCON1024")) oqs_sigalg_list[11].code_point = atoi(getenv("OQS_CODEPOINT_P521_FALCON1024"));
+ if (getenv("OQS_CODEPOINT_SPHINCSSHA2128FSIMPLE")) oqs_sigalg_list[12].code_point = atoi(getenv("OQS_CODEPOINT_SPHINCSSHA2128FSIMPLE"));
+ if (getenv("OQS_CODEPOINT_P256_SPHINCSSHA2128FSIMPLE")) oqs_sigalg_list[13].code_point = atoi(getenv("OQS_CODEPOINT_P256_SPHINCSSHA2128FSIMPLE"));
+ if (getenv("OQS_CODEPOINT_RSA3072_SPHINCSSHA2128FSIMPLE")) oqs_sigalg_list[14].code_point = atoi(getenv("OQS_CODEPOINT_RSA3072_SPHINCSSHA2128FSIMPLE"));
+ if (getenv("OQS_CODEPOINT_SPHINCSSHA2128SSIMPLE")) oqs_sigalg_list[15].code_point = atoi(getenv("OQS_CODEPOINT_SPHINCSSHA2128SSIMPLE"));
+ if (getenv("OQS_CODEPOINT_P256_SPHINCSSHA2128SSIMPLE")) oqs_sigalg_list[16].code_point = atoi(getenv("OQS_CODEPOINT_P256_SPHINCSSHA2128SSIMPLE"));
+ if (getenv("OQS_CODEPOINT_RSA3072_SPHINCSSHA2128SSIMPLE")) oqs_sigalg_list[17].code_point = atoi(getenv("OQS_CODEPOINT_RSA3072_SPHINCSSHA2128SSIMPLE"));
+ if (getenv("OQS_CODEPOINT_SPHINCSSHA2192FSIMPLE")) oqs_sigalg_list[18].code_point = atoi(getenv("OQS_CODEPOINT_SPHINCSSHA2192FSIMPLE"));
+ if (getenv("OQS_CODEPOINT_P384_SPHINCSSHA2192FSIMPLE")) oqs_sigalg_list[19].code_point = atoi(getenv("OQS_CODEPOINT_P384_SPHINCSSHA2192FSIMPLE"));
+ if (getenv("OQS_CODEPOINT_SPHINCSSHAKE128FSIMPLE")) oqs_sigalg_list[20].code_point = atoi(getenv("OQS_CODEPOINT_SPHINCSSHAKE128FSIMPLE"));
+ if (getenv("OQS_CODEPOINT_P256_SPHINCSSHAKE128FSIMPLE")) oqs_sigalg_list[21].code_point = atoi(getenv("OQS_CODEPOINT_P256_SPHINCSSHAKE128FSIMPLE"));
+ if (getenv("OQS_CODEPOINT_RSA3072_SPHINCSSHAKE128FSIMPLE")) oqs_sigalg_list[22].code_point = atoi(getenv("OQS_CODEPOINT_RSA3072_SPHINCSSHAKE128FSIMPLE"));
+///// OQS_TEMPLATE_FRAGMENT_CODEPOINT_PATCHING_END
+ return 1;
+}
+
+static int oqs_group_capability(OSSL_CALLBACK *cb, void *arg)
+{
+ size_t i;
+
+ for (i = 0; i < OSSL_NELEM(oqs_param_group_list); i++) {
+ if (!cb(oqs_param_group_list[i], arg))
+ return 0;
+ }
+
+ return 1;
+}
+
+#ifdef OSSL_CAPABILITY_TLS_SIGALG_NAME
+#define OQS_SIGALG_ENTRY(tlsname, realname, algorithm, oid, idx) \
+ { \
+ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_IANA_NAME, \
+ #tlsname, \
+ sizeof(#tlsname)), \
+ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_NAME, \
+ #tlsname, \
+ sizeof(#tlsname)), \
+ OSSL_PARAM_utf8_string(OSSL_CAPABILITY_TLS_SIGALG_OID, \
+ #oid, \
+ sizeof(#oid)), \
+ OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_CODE_POINT, \
+ (unsigned int *)&oqs_sigalg_list[idx].code_point), \
+ OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS, \
+ (unsigned int *)&oqs_sigalg_list[idx].secbits), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS, \
+ (unsigned int *)&oqs_sigalg_list[idx].mintls), \
+ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS, \
+ (unsigned int *)&oqs_sigalg_list[idx].maxtls), \
+ OSSL_PARAM_END \
+ }
+
+static const OSSL_PARAM oqs_param_sigalg_list[][12] = {
+///// OQS_TEMPLATE_FRAGMENT_SIGALG_NAMES_START
+#ifdef OQS_ENABLE_SIG_dilithium_2
+ OQS_SIGALG_ENTRY(dilithium2, dilithium2, dilithium2, "1.3.6.1.4.1.2.267.7.4.4", 0),
+ OQS_SIGALG_ENTRY(p256_dilithium2, p256_dilithium2, p256_dilithium2, "1.3.9999.2.7.1", 1),
+ OQS_SIGALG_ENTRY(rsa3072_dilithium2, rsa3072_dilithium2, rsa3072_dilithium2, "1.3.9999.2.7.2", 2),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_3
+ OQS_SIGALG_ENTRY(dilithium3, dilithium3, dilithium3, "1.3.6.1.4.1.2.267.7.6.5", 3),
+ OQS_SIGALG_ENTRY(p384_dilithium3, p384_dilithium3, p384_dilithium3, "1.3.9999.2.7.3", 4),
+#endif
+#ifdef OQS_ENABLE_SIG_dilithium_5
+ OQS_SIGALG_ENTRY(dilithium5, dilithium5, dilithium5, "1.3.6.1.4.1.2.267.7.8.7", 5),
+ OQS_SIGALG_ENTRY(p521_dilithium5, p521_dilithium5, p521_dilithium5, "1.3.9999.2.7.4", 6),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_512
+ OQS_SIGALG_ENTRY(falcon512, falcon512, falcon512, "1.3.9999.3.6", 7),
+ OQS_SIGALG_ENTRY(p256_falcon512, p256_falcon512, p256_falcon512, "1.3.9999.3.7", 8),
+ OQS_SIGALG_ENTRY(rsa3072_falcon512, rsa3072_falcon512, rsa3072_falcon512, "1.3.9999.3.8", 9),
+#endif
+#ifdef OQS_ENABLE_SIG_falcon_1024
+ OQS_SIGALG_ENTRY(falcon1024, falcon1024, falcon1024, "1.3.9999.3.9", 10),
+ OQS_SIGALG_ENTRY(p521_falcon1024, p521_falcon1024, p521_falcon1024, "1.3.9999.3.10", 11),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128f_simple
+ OQS_SIGALG_ENTRY(sphincssha2128fsimple, sphincssha2128fsimple, sphincssha2128fsimple, "1.3.9999.6.4.13", 12),
+ OQS_SIGALG_ENTRY(p256_sphincssha2128fsimple, p256_sphincssha2128fsimple, p256_sphincssha2128fsimple, "1.3.9999.6.4.14", 13),
+ OQS_SIGALG_ENTRY(rsa3072_sphincssha2128fsimple, rsa3072_sphincssha2128fsimple, rsa3072_sphincssha2128fsimple, "1.3.9999.6.4.15", 14),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_128s_simple
+ OQS_SIGALG_ENTRY(sphincssha2128ssimple, sphincssha2128ssimple, sphincssha2128ssimple, "1.3.9999.6.4.16", 15),
+ OQS_SIGALG_ENTRY(p256_sphincssha2128ssimple, p256_sphincssha2128ssimple, p256_sphincssha2128ssimple, "1.3.9999.6.4.17", 16),
+ OQS_SIGALG_ENTRY(rsa3072_sphincssha2128ssimple, rsa3072_sphincssha2128ssimple, rsa3072_sphincssha2128ssimple, "1.3.9999.6.4.18", 17),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_sha2_192f_simple
+ OQS_SIGALG_ENTRY(sphincssha2192fsimple, sphincssha2192fsimple, sphincssha2192fsimple, "1.3.9999.6.5.10", 18),
+ OQS_SIGALG_ENTRY(p384_sphincssha2192fsimple, p384_sphincssha2192fsimple, p384_sphincssha2192fsimple, "1.3.9999.6.5.11", 19),
+#endif
+#ifdef OQS_ENABLE_SIG_sphincs_shake_128f_simple
+ OQS_SIGALG_ENTRY(sphincsshake128fsimple, sphincsshake128fsimple, sphincsshake128fsimple, "1.3.9999.6.7.13", 20),
+ OQS_SIGALG_ENTRY(p256_sphincsshake128fsimple, p256_sphincsshake128fsimple, p256_sphincsshake128fsimple, "1.3.9999.6.7.14", 21),
+ OQS_SIGALG_ENTRY(rsa3072_sphincsshake128fsimple, rsa3072_sphincsshake128fsimple, rsa3072_sphincsshake128fsimple, "1.3.9999.6.7.15", 22),
+#endif
+///// OQS_TEMPLATE_FRAGMENT_SIGALG_NAMES_END
+};
+
+static int oqs_sigalg_capability(OSSL_CALLBACK *cb, void *arg)
+{
+ size_t i;
+
+ // relaxed assertion for the case that not all algorithms are enabled in liboqs:
+ assert(OSSL_NELEM(oqs_param_sigalg_list) <= OSSL_NELEM(oqs_sigalg_list));
+ for (i = 0; i < OSSL_NELEM(oqs_param_sigalg_list); i++) {
+ if (!cb(oqs_param_sigalg_list[i], arg))
+ return 0;
+ }
+
+ return 1;
+}
+#endif /* OSSL_CAPABILITY_TLS_SIGALG_NAME */
+
+int oqs_provider_get_capabilities(void *provctx, const char *capability,
+ OSSL_CALLBACK *cb, void *arg)
+{
+ if (strcasecmp(capability, "TLS-GROUP") == 0)
+ return oqs_group_capability(cb, arg);
+
+#ifdef OSSL_CAPABILITY_TLS_SIGALG_NAME
+ if (strcasecmp(capability, "TLS-SIGALG") == 0)
+ return oqs_sigalg_capability(cb, arg);
+#endif
+
+ /* We don't support this capability */
+ return 0;
+}
+
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+/*
+ * OQS OpenSSL 3 key handler.
+ *
+ * Code strongly inspired by OpenSSL crypto/ec key handler but relocated here
+ * to have code within provider.
+ *
+ */
+
+#include <openssl/err.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
+#include <openssl/evp.h>
+#include <openssl/x509.h>
+#include <string.h>
+#include <assert.h>
+#include "oqs_prov.h"
+
+#ifdef NDEBUG
+#define OQS_KEY_PRINTF(a)
+#define OQS_KEY_PRINTF2(a, b)
+#define OQS_KEY_PRINTF3(a, b, c)
+#else
+#define OQS_KEY_PRINTF(a) if (getenv("OQSKEY")) printf(a)
+#define OQS_KEY_PRINTF2(a, b) if (getenv("OQSKEY")) printf(a, b)
+#define OQS_KEY_PRINTF3(a, b, c) if (getenv("OQSKEY")) printf(a, b, c)
+#endif // NDEBUG
+
+typedef enum {
+ KEY_OP_PUBLIC,
+ KEY_OP_PRIVATE,
+ KEY_OP_KEYGEN
+} oqsx_key_op_t;
+
+/// NID/name table
+
+typedef struct {
+ int nid;
+ char* tlsname;
+ char* oqsname;
+ int keytype;
+ int secbits;
+} oqs_nid_name_t;
+
+static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op);
+
+///// OQS_TEMPLATE_FRAGMENT_OQSNAMES_START
+#define NID_TABLE_LEN 23
+
+static oqs_nid_name_t nid_names[NID_TABLE_LEN] = {
+ { 0, "dilithium2", OQS_SIG_alg_dilithium_2, KEY_TYPE_SIG, 128 },
+ { 0, "p256_dilithium2", OQS_SIG_alg_dilithium_2, KEY_TYPE_HYB_SIG, 128 },
+ { 0, "rsa3072_dilithium2", OQS_SIG_alg_dilithium_2, KEY_TYPE_HYB_SIG, 128 },
+ { 0, "dilithium3", OQS_SIG_alg_dilithium_3, KEY_TYPE_SIG, 192 },
+ { 0, "p384_dilithium3", OQS_SIG_alg_dilithium_3, KEY_TYPE_HYB_SIG, 192 },
+ { 0, "dilithium5", OQS_SIG_alg_dilithium_5, KEY_TYPE_SIG, 256 },
+ { 0, "p521_dilithium5", OQS_SIG_alg_dilithium_5, KEY_TYPE_HYB_SIG, 256 },
+ { 0, "falcon512", OQS_SIG_alg_falcon_512, KEY_TYPE_SIG, 128 },
+ { 0, "p256_falcon512", OQS_SIG_alg_falcon_512, KEY_TYPE_HYB_SIG, 128 },
+ { 0, "rsa3072_falcon512", OQS_SIG_alg_falcon_512, KEY_TYPE_HYB_SIG, 128 },
+ { 0, "falcon1024", OQS_SIG_alg_falcon_1024, KEY_TYPE_SIG, 256 },
+ { 0, "p521_falcon1024", OQS_SIG_alg_falcon_1024, KEY_TYPE_HYB_SIG, 256 },
+ { 0, "sphincssha2128fsimple", OQS_SIG_alg_sphincs_sha2_128f_simple, KEY_TYPE_SIG, 128 },
+ { 0, "p256_sphincssha2128fsimple", OQS_SIG_alg_sphincs_sha2_128f_simple, KEY_TYPE_HYB_SIG, 128 },
+ { 0, "rsa3072_sphincssha2128fsimple", OQS_SIG_alg_sphincs_sha2_128f_simple, KEY_TYPE_HYB_SIG, 128 },
+ { 0, "sphincssha2128ssimple", OQS_SIG_alg_sphincs_sha2_128s_simple, KEY_TYPE_SIG, 128 },
+ { 0, "p256_sphincssha2128ssimple", OQS_SIG_alg_sphincs_sha2_128s_simple, KEY_TYPE_HYB_SIG, 128 },
+ { 0, "rsa3072_sphincssha2128ssimple", OQS_SIG_alg_sphincs_sha2_128s_simple, KEY_TYPE_HYB_SIG, 128 },
+ { 0, "sphincssha2192fsimple", OQS_SIG_alg_sphincs_sha2_192f_simple, KEY_TYPE_SIG, 192 },
+ { 0, "p384_sphincssha2192fsimple", OQS_SIG_alg_sphincs_sha2_192f_simple, KEY_TYPE_HYB_SIG, 192 },
+ { 0, "sphincsshake128fsimple", OQS_SIG_alg_sphincs_shake_128f_simple, KEY_TYPE_SIG, 128 },
+ { 0, "p256_sphincsshake128fsimple", OQS_SIG_alg_sphincs_shake_128f_simple, KEY_TYPE_HYB_SIG, 128 },
+ { 0, "rsa3072_sphincsshake128fsimple", OQS_SIG_alg_sphincs_shake_128f_simple, KEY_TYPE_HYB_SIG, 128 },
+///// OQS_TEMPLATE_FRAGMENT_OQSNAMES_END
+};
+
+int oqs_set_nid(char* tlsname, int nid) {
+ int i;
+ for(i=0;i<NID_TABLE_LEN;i++) {
+ if (!strcmp(nid_names[i].tlsname, tlsname)) {
+ nid_names[i].nid = nid;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static int get_secbits(int nid) {
+ int i;
+ for(i=0;i<NID_TABLE_LEN;i++) {
+ if (nid_names[i].nid == nid)
+ return nid_names[i].secbits;
+ }
+ return 0;
+}
+
+static int get_keytype(int nid) {
+ int i;
+ for(i=0;i<NID_TABLE_LEN;i++) {
+ if (nid_names[i].nid == nid)
+ return nid_names[i].keytype;
+ }
+ return 0;
+}
+
+static char* get_oqsname(int nid) {
+ int i;
+ for(i=0;i<NID_TABLE_LEN;i++) {
+ if (nid_names[i].nid == nid)
+ return nid_names[i].oqsname;
+ }
+ return 0;
+}
+
+static int get_oqsalg_idx(int nid) {
+ int i;
+ for(i=0;i<NID_TABLE_LEN;i++) {
+ if (nid_names[i].nid == nid)
+ return i;
+ }
+ return -1;
+}
+
+/* Prepare composite data structures. RetVal 0 is error. */
+static int oqsx_key_set_composites(OQSX_KEY *key) {
+ int ret = 1;
+
+ OQS_KEY_PRINTF2("Setting composites with evp_info %p\n", key->evp_info);
+
+ if (key->numkeys == 1) {
+ key->comp_privkey[0] = key->privkey;
+ key->comp_pubkey[0] = key->pubkey;
+ }
+ else { // TBD: extend for more than 1 classic key:
+ int classic_pubkey_len, classic_privkey_len;
+
+ if (key->privkey) {
+ key->comp_privkey[0] = (char*)key->privkey + SIZE_OF_UINT32;
+ DECODE_UINT32(classic_privkey_len, key->privkey);
+ key->comp_privkey[1] = (char*)key->privkey + classic_privkey_len + SIZE_OF_UINT32;
+ }
+ else {
+ key->comp_privkey[0] = NULL;
+ key->comp_privkey[1] = NULL;
+ }
+ if (key->pubkey) {
+ key->comp_pubkey[0] = (char*)key->pubkey + SIZE_OF_UINT32;
+ DECODE_UINT32(classic_pubkey_len, key->pubkey);
+ key->comp_pubkey[1] = (char*)key->pubkey + classic_pubkey_len + SIZE_OF_UINT32;
+ }
+ else {
+
+ key->comp_pubkey[0] = NULL;
+ key->comp_pubkey[1] = NULL;
+ }
+ }
+ return ret;
+}
+
+PROV_OQS_CTX *oqsx_newprovctx(OSSL_LIB_CTX *libctx, const OSSL_CORE_HANDLE *handle, BIO_METHOD *bm) {
+ PROV_OQS_CTX * ret = OPENSSL_zalloc(sizeof(PROV_OQS_CTX));
+ if (ret) {
+ ret->libctx = libctx;
+ ret->handle = handle;
+ ret->corebiometh = bm;
+ }
+ return ret;
+}
+
+void oqsx_freeprovctx(PROV_OQS_CTX *ctx) {
+ OSSL_LIB_CTX_free(ctx->libctx);
+ BIO_meth_free(ctx->corebiometh);
+ OPENSSL_free(ctx);
+}
+
+
+void oqsx_key_set0_libctx(OQSX_KEY *key, OSSL_LIB_CTX *libctx)
+{
+ key->libctx = libctx;
+}
+
+/* convenience function creating OQSX keys from nids (only for sigs) */
+static OQSX_KEY *oqsx_key_new_from_nid(OSSL_LIB_CTX *libctx, const char *propq, int nid) {
+ OQS_KEY_PRINTF2("Generating OQSX key for nid %d\n", nid);
+
+ char* tls_algname = (char *)OBJ_nid2sn(nid);
+ OQS_KEY_PRINTF2(" for tls_name %s\n", tls_algname);
+
+ if (!tls_algname) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_WRONG_PARAMETERS);
+ return NULL;
+ }
+
+ return oqsx_key_new(libctx, get_oqsname(nid), tls_algname, get_keytype(nid), propq, get_secbits(nid), get_oqsalg_idx(nid));
+}
+
+/* Workaround for not functioning EC PARAM initialization
+ * TBD, check https://github.com/openssl/openssl/issues/16989
+ */
+EVP_PKEY* setECParams(EVP_PKEY *eck, int nid) {
+ const unsigned char p256params[] = { 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07 };
+ const unsigned char p384params[] = { 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22 };
+ const unsigned char p521params[] = { 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23 };
+
+ const unsigned char* params;
+ switch(nid) {
+ case NID_X9_62_prime256v1:
+ params = p256params;
+ return d2i_KeyParams(EVP_PKEY_EC, &eck, ¶ms, sizeof(p256params));
+ case NID_secp384r1:
+ params = p384params;
+ return d2i_KeyParams(EVP_PKEY_EC, &eck, ¶ms, sizeof(p384params));
+ case NID_secp521r1:
+ params = p521params;
+ return d2i_KeyParams(EVP_PKEY_EC, &eck, ¶ms, sizeof(p521params));
+ default:
+ return NULL;
+ }
+}
+
+/* Re-create OQSX_KEY from encoding(s): Same end-state as after ken-gen */
+static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg,
+ const unsigned char *p, int plen,
+ oqsx_key_op_t op,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ OQSX_KEY *key = NULL;
+ void **privkey, **pubkey;
+ int nid = NID_undef;
+ int ret = 0;
+
+ OQS_KEY_PRINTF2("OQSX KEY: key_op called with data of len %d\n", plen);
+ if (palg != NULL) {
+ int ptype;
+
+ /* Algorithm parameters must be absent */
+ X509_ALGOR_get0(NULL, &ptype, NULL, palg);
+ if (ptype != V_ASN1_UNDEF || !palg || !palg->algorithm) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ return 0;
+ }
+ nid = OBJ_obj2nid(palg->algorithm);
+ }
+
+ if (p == NULL || nid == EVP_PKEY_NONE || nid == NID_undef) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ return 0;
+ }
+
+ key = oqsx_key_new_from_nid(libctx, propq, nid);
+ if (key == NULL) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (op == KEY_OP_PUBLIC) {
+#ifdef USE_ENCODING_LIB
+ if (key->oqsx_encoding_ctx.encoding_ctx && key->oqsx_encoding_ctx.encoding_impl) {
+ key->pubkeylen = key->oqsx_encoding_ctx.encoding_ctx->raw_crypto_publickeybytes;
+ if (key->oqsx_encoding_ctx.encoding_impl->crypto_publickeybytes != plen) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto err;
+ }
+ if (oqsx_key_allocate_keymaterial(key, 0)) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (qsc_decode(key->oqsx_encoding_ctx.encoding_ctx, key->oqsx_encoding_ctx.encoding_impl, p, (unsigned char **) &key->pubkey, 0, 0, 1) != QSC_ENC_OK) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto err;
+ }
+ } else {
+#endif
+ if (key->pubkeylen != plen) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto err;
+ }
+ if (oqsx_key_allocate_keymaterial(key, 0)) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memcpy(key->pubkey, p, plen);
+#ifdef USE_ENCODING_LIB
+ }
+#endif
+ } else {
+ int classical_privatekey_len = 0;
+ // for plain OQS keys, we expect OQS priv||OQS pub key
+ size_t actualprivkeylen = key->privkeylen;
+ // for hybrid keys, we expect classic priv key||OQS priv key||OQS pub key
+ // classic pub key must/can be re-created from classic private key
+ if (key->numkeys == 2) {
+ DECODE_UINT32(classical_privatekey_len, p); // actual classic key len
+ // adjust expected size
+ if (classical_privatekey_len > key->evp_info->length_private_key) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto err;
+ }
+ actualprivkeylen -= (key->evp_info->length_private_key - classical_privatekey_len);
+ }
+#ifdef USE_ENCODING_LIB
+ if (key->oqsx_encoding_ctx.encoding_ctx && key->oqsx_encoding_ctx.encoding_impl) {
+ const qsc_encoding_t* encoding_ctx = key->oqsx_encoding_ctx.encoding_ctx;
+#ifdef NOPUBKEY_IN_PRIVKEY
+ // if the raw private key includes the public key, the optional part is needed, otherwise not.
+ int withoptional = (encoding_ctx->raw_private_key_encodes_public_key ? 1 : 0);
+#else
+ int withoptional = 1;
+#endif
+ int pubkey_available = withoptional;
+ if (oqsx_key_allocate_keymaterial(key, 1)) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ if (pubkey_available) {
+ if (oqsx_key_allocate_keymaterial(key, 0)) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+
+ if (qsc_decode(encoding_ctx, key->oqsx_encoding_ctx.encoding_impl,
+ 0, (pubkey_available ? (unsigned char**)&key->pubkey : 0), p,
+ (unsigned char**)&key->privkey, withoptional) != QSC_ENC_OK) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto err;
+ }
+
+ } else {
+#endif
+#ifdef NOPUBKEY_IN_PRIVKEY
+ if (actualprivkeylen != plen) {
+ OQS_KEY_PRINTF3("OQSX KEY: private key with unexpected length %d vs %d\n", plen, (int)(actualprivkeylen));
+#else
+ if (actualprivkeylen + oqsx_key_get_oqs_public_key_len(key) != plen) {
+ OQS_KEY_PRINTF3("OQSX KEY: private key with unexpected length %d vs %d\n", plen, (int)(actualprivkeylen + oqsx_key_get_oqs_public_key_len(key)));
+#endif
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto err;
+ }
+ if (oqsx_key_allocate_keymaterial(key, 1)
+#ifndef NOPUBKEY_IN_PRIVKEY
+ || oqsx_key_allocate_keymaterial(key, 0)
+#endif
+ ) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ // first populate private key data
+ memcpy(key->privkey, p, actualprivkeylen);
+#ifndef NOPUBKEY_IN_PRIVKEY
+ // only enough data to fill public OQS key component
+ if (oqsx_key_get_oqs_public_key_len(key) != plen - actualprivkeylen) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto err;
+ }
+ // populate OQS public key structure
+ if (key->numkeys == 2) {
+ unsigned char *pubkey = (unsigned char *)key->pubkey;
+ ENCODE_UINT32(pubkey,key->evp_info->length_public_key);
+ memcpy(pubkey+SIZE_OF_UINT32+key->evp_info->length_public_key, p+actualprivkeylen, plen-actualprivkeylen);
+ }
+ else
+ memcpy(key->pubkey, p+key->privkeylen, plen-key->privkeylen);
+#endif
+ }
+#ifdef USE_ENCODING_LIB
+ }
+#endif
+ if (!oqsx_key_set_composites(key) || !oqsx_key_recreate_classickey(key, op))
+ goto err;
+
+ return key;
+
+ err:
+ oqsx_key_free(key);
+ return NULL;
+}
+
+/* Recreate EVP data structure after import. RetVal 0 is error. */
+static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op) {
+ if (key->numkeys == 2) { // hybrid key
+ int classical_pubkey_len, classical_privkey_len;
+ if (!key->evp_info) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_EVPINFO_MISSING);
+ goto rec_err;
+ }
+ if (op == KEY_OP_PUBLIC) {
+ DECODE_UINT32(classical_pubkey_len, key->pubkey);
+ if (key->evp_info->raw_key_support) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto rec_err;
+ }
+ else {
+ const unsigned char* enc_pubkey = key->comp_pubkey[0];
+ EVP_PKEY* npk = EVP_PKEY_new();
+ if (key->evp_info->keytype != EVP_PKEY_RSA) {
+ npk = setECParams(npk, key->evp_info->nid);
+ }
+ key->classical_pkey = d2i_PublicKey(key->evp_info->keytype, &npk, &enc_pubkey, classical_pubkey_len);
+ if (!key->classical_pkey) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ EVP_PKEY_free(npk);
+ goto rec_err;
+ }
+ }
+ }
+ if (op == KEY_OP_PRIVATE) {
+ DECODE_UINT32(classical_privkey_len, key->privkey);
+ if (key->evp_info->raw_key_support) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto rec_err;
+ }
+ else {
+ const unsigned char* enc_privkey = key->comp_privkey[0];
+ unsigned char* enc_pubkey = key->comp_pubkey[0];
+ key->classical_pkey = d2i_PrivateKey(key->evp_info->keytype, NULL, &enc_privkey, classical_privkey_len);
+ if (!key->classical_pkey) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto rec_err;
+ }
+#ifndef NOPUBKEY_IN_PRIVKEY
+ // re-create classic public key part from private key:
+ int pubkeylen = i2d_PublicKey(key->classical_pkey, &enc_pubkey);
+ if (pubkeylen != key->evp_info->length_public_key) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ goto rec_err;
+ }
+#endif
+ }
+ }
+ }
+ return 1;
+ rec_err:
+ return 0;
+}
+
+OQSX_KEY *oqsx_key_from_x509pubkey(const X509_PUBKEY *xpk,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ const unsigned char *p;
+ int plen;
+ X509_ALGOR *palg;
+ OQSX_KEY* oqsx = NULL;
+
+ if (!xpk || (!X509_PUBKEY_get0_param(NULL, &p, &plen, &palg, xpk))) {
+ return NULL;
+ }
+ oqsx = oqsx_key_op(palg, p, plen, KEY_OP_PUBLIC, libctx, propq);
+ return oqsx;
+}
+
+OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
+ OSSL_LIB_CTX *libctx, const char *propq)
+{
+ OQSX_KEY *oqsx = NULL;
+ const unsigned char *p;
+ int plen;
+ ASN1_OCTET_STRING *oct = NULL;
+ const X509_ALGOR *palg;
+
+ if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf))
+ return 0;
+
+ oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen);
+ if (oct == NULL) {
+ p = NULL;
+ plen = 0;
+ } else {
+ p = ASN1_STRING_get0_data(oct);
+ plen = ASN1_STRING_length(oct);
+ }
+
+ oqsx = oqsx_key_op(palg, p, plen, KEY_OP_PRIVATE,
+ libctx, propq);
+ ASN1_OCTET_STRING_free(oct);
+ return oqsx;
+}
+
+/* Key codes */
+
+static const OQSX_EVP_INFO nids_sig[] = {
+ { EVP_PKEY_EC, NID_X9_62_prime256v1, 0, 65 , 121, 32, 72}, // 128 bit
+ { EVP_PKEY_EC, NID_secp384r1 , 0, 97 , 167, 48, 104}, // 192 bit
+ { EVP_PKEY_EC, NID_secp521r1 , 0, 133, 223, 66, 141}, // 256 bit
+ { EVP_PKEY_RSA, NID_rsaEncryption , 0, 398, 1770, 0, 384}, // 128 bit
+};
+
+// These two array need to stay synced:
+static const char* OQSX_ECP_NAMES[] = { "p256", "p384", "p521", 0 };
+static const OQSX_EVP_INFO nids_ecp[] = {
+ { EVP_PKEY_EC, NID_X9_62_prime256v1, 0, 65 , 121, 32, 0}, // 128 bit
+ { EVP_PKEY_EC, NID_secp384r1 , 0, 97 , 167, 48, 0}, // 192 bit
+ { EVP_PKEY_EC, NID_secp521r1 , 0, 133, 223, 66, 0} // 256 bit
+};
+
+// These two array need to stay synced:
+static const char* OQSX_ECX_NAMES[] = { "x25519", "x448", 0 };
+static const OQSX_EVP_INFO nids_ecx[] = {
+ { EVP_PKEY_X25519, 0, 1, 32, 32, 32, 0}, // 128 bit
+ { EVP_PKEY_X448, 0, 1, 56, 56, 56, 0}, // 192 bit
+ { 0, 0, 0, 0, 0, 0, 0} // 256 bit
+};
+
+static int oqsx_hybsig_init(int bit_security, OQSX_EVP_CTX *evp_ctx, char* algname)
+{
+ int ret = 1;
+ int idx = (bit_security - 128) / 64;
+ ON_ERR_GOTO(idx < 0 || idx > 2, err);
+
+ if (!strncmp(algname, "rsa3072_", 8)) idx += 3;
+ else if (algname[0]!='p') {
+ OQS_KEY_PRINTF2("OQS KEY: Incorrect hybrid name: %s\n", algname);
+ ret = 0;
+ goto err;
+ }
+
+ ON_ERR_GOTO(idx < 0 || idx > 3, err);
+
+ evp_ctx->evp_info = &nids_sig[idx];
+
+ evp_ctx->ctx = EVP_PKEY_CTX_new_id(evp_ctx->evp_info->keytype, NULL);
+ ON_ERR_GOTO(!evp_ctx->ctx, err);
+
+ if (idx < 3) { // EC
+ ret = EVP_PKEY_paramgen_init(evp_ctx->ctx);
+ ON_ERR_GOTO(ret <= 0, err);
+
+ ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(evp_ctx->ctx, evp_ctx->evp_info->nid);
+ ON_ERR_GOTO(ret <= 0, err);
+
+ ret = EVP_PKEY_paramgen(evp_ctx->ctx, &evp_ctx->keyParam);
+ ON_ERR_GOTO(ret <= 0 || !evp_ctx->keyParam, err);
+ }
+ // RSA bit length set only during keygen
+
+ err:
+ return ret;
+}
+
+static const int oqshybkem_init_ecp(char* tls_name, OQSX_EVP_CTX *evp_ctx)
+{
+ int ret = 1;
+ int idx = 0;
+ while(idx < sizeof(OQSX_ECP_NAMES)) {
+ if (!strncmp(tls_name, OQSX_ECP_NAMES[idx], 4))
+ break;
+ idx++;
+ }
+ ON_ERR_GOTO(idx < 0 || idx > 2, err);
+
+ evp_ctx->evp_info = &nids_ecp[idx];
+
+ evp_ctx->ctx = EVP_PKEY_CTX_new_id(evp_ctx->evp_info->keytype, NULL);
+ ON_ERR_GOTO(!evp_ctx->ctx, err);
+
+ ret = EVP_PKEY_paramgen_init(evp_ctx->ctx);
+ ON_ERR_GOTO(ret <= 0, err);
+
+ ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(evp_ctx->ctx, evp_ctx->evp_info->nid);
+ ON_ERR_GOTO(ret <= 0, err);
+
+ ret = EVP_PKEY_paramgen(evp_ctx->ctx, &evp_ctx->keyParam);
+ ON_ERR_GOTO(ret <= 0 || !evp_ctx->keyParam, err);
+
+ err:
+ return ret;
+}
+
+static const int oqshybkem_init_ecx(char* tls_name, OQSX_EVP_CTX *evp_ctx)
+{
+ int ret = 1;
+ int idx = 0;
+
+ while(idx < sizeof(OQSX_ECX_NAMES)) {
+ if (!strncmp(tls_name, OQSX_ECX_NAMES[idx], 4))
+ break;
+ idx++;
+ }
+ ON_ERR_GOTO(idx < 0 || idx > 2, err);
+
+ evp_ctx->evp_info = &nids_ecx[idx];
+
+ evp_ctx->keyParam = EVP_PKEY_new();
+ ON_ERR_SET_GOTO(!evp_ctx->keyParam, ret, -1, err);
+
+ ret = EVP_PKEY_set_type(evp_ctx->keyParam, evp_ctx->evp_info->keytype);
+ ON_ERR_SET_GOTO(ret <= 0, ret, -1, err);
+
+ evp_ctx->ctx = EVP_PKEY_CTX_new(evp_ctx->keyParam, NULL);
+ ON_ERR_SET_GOTO(!evp_ctx->ctx, ret, -1, err);
+
+ err:
+ return ret;
+}
+
+static const int (*init_kex_fun[])(char *, OQSX_EVP_CTX *) = {
+ oqshybkem_init_ecp,
+ oqshybkem_init_ecx
+};
+#ifdef USE_ENCODING_LIB
+extern const char* oqs_alg_encoding_list[];
+#endif
+extern const char* oqs_oid_alg_list[];
+
+OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char* oqs_name, char* tls_name, int primitive, const char *propq, int bit_security, int alg_idx)
+{
+ OQSX_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
+ OQSX_EVP_CTX *evp_ctx = NULL;
+ int ret2 = 0;
+
+ if (ret == NULL) goto err;
+
+#ifdef OQS_PROVIDER_NOATOMIC
+ ret->lock = CRYPTO_THREAD_lock_new();
+ if (ret->lock == NULL) {
+ OPENSSL_free(ret);
+ goto err;
+ }
+#endif
+
+ if (oqs_name == NULL) {
+ OQS_KEY_PRINTF("OQSX_KEY: Fatal error: No OQS key name provided:\n");
+ goto err;
+ }
+
+ if (tls_name == NULL) {
+ OQS_KEY_PRINTF("OQSX_KEY: Fatal error: No TLS key name provided:\n");
+ goto err;
+ }
+
+ switch(primitive) {
+ case KEY_TYPE_SIG:
+ ret->numkeys = 1;
+ ret->comp_privkey = OPENSSL_malloc(sizeof(void *));
+ ret->comp_pubkey = OPENSSL_malloc(sizeof(void *));
+ ret->oqsx_provider_ctx.oqsx_qs_ctx.sig = OQS_SIG_new(oqs_name);
+ if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.sig) {
+ fprintf(stderr, "Could not create OQS signature algorithm %s. Enabled in liboqs?\n", oqs_name);
+ goto err;
+ }
+
+#ifdef USE_ENCODING_LIB
+ if (alg_idx >= 0 && oqs_alg_encoding_list[2*alg_idx] != NULL && oqs_alg_encoding_list[2*alg_idx+1] != NULL) {
+ if (qsc_encoding_by_name_oid(&ret->oqsx_encoding_ctx.encoding_ctx, &ret->oqsx_encoding_ctx.encoding_impl, oqs_alg_encoding_list[2*alg_idx+1], oqs_alg_encoding_list[2*alg_idx]) != QSC_ENC_OK) {
+ fprintf(stderr, "Could not create OQS signature encoding algorithm %s (%s, %s).\n", oqs_alg_encoding_list[2*alg_idx+1], oqs_name, oqs_alg_encoding_list[2*alg_idx]);
+ ret->oqsx_encoding_ctx.encoding_ctx = NULL;
+ ret->oqsx_encoding_ctx.encoding_impl = NULL;
+ goto err;
+ }
+ }
+#endif
+ ret->privkeylen = ret->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_secret_key;
+ ret->pubkeylen = ret->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_public_key;
+ ret->keytype = KEY_TYPE_SIG;
+ break;
+ case KEY_TYPE_KEM:
+ ret->numkeys = 1;
+ ret->comp_privkey = OPENSSL_malloc(sizeof(void *));
+ ret->comp_pubkey = OPENSSL_malloc(sizeof(void *));
+ ret->oqsx_provider_ctx.oqsx_qs_ctx.kem = OQS_KEM_new(oqs_name);
+ if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.kem) {
+ fprintf(stderr, "Could not create OQS KEM algorithm %s. Enabled in liboqs?\n", oqs_name);
+ goto err;
+ }
+ ret->privkeylen = ret->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_secret_key;
+ ret->pubkeylen = ret->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_public_key;
+ ret->keytype = KEY_TYPE_KEM;
+ break;
+ case KEY_TYPE_ECX_HYB_KEM:
+ case KEY_TYPE_ECP_HYB_KEM:
+ ret->oqsx_provider_ctx.oqsx_qs_ctx.kem = OQS_KEM_new(oqs_name);
+ if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.kem) {
+ fprintf(stderr, "Could not create OQS KEM algorithm %s. Enabled in liboqs?\n", oqs_name);
+ goto err;
+ }
+ evp_ctx = OPENSSL_zalloc(sizeof(OQSX_EVP_CTX));
+ ON_ERR_GOTO(!evp_ctx, err);
+
+ ret2 = (init_kex_fun[primitive - KEY_TYPE_ECP_HYB_KEM])
+ (tls_name, evp_ctx);
+ ON_ERR_GOTO(ret2 <= 0 || !evp_ctx->keyParam || !evp_ctx->ctx, err);
+
+ ret->numkeys = 2;
+ ret->comp_privkey = OPENSSL_malloc(ret->numkeys * sizeof(void *));
+ ret->comp_pubkey = OPENSSL_malloc(ret->numkeys * sizeof(void *));
+ ret->privkeylen = (ret->numkeys-1)*SIZE_OF_UINT32 + ret->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_secret_key + evp_ctx->evp_info->length_private_key;
+ ret->pubkeylen = (ret->numkeys-1)*SIZE_OF_UINT32 + ret->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_public_key + evp_ctx->evp_info->length_public_key;
+ ret->oqsx_provider_ctx.oqsx_evp_ctx = evp_ctx;
+ ret->keytype = primitive;
+ break;
+ case KEY_TYPE_HYB_SIG:
+ ret->oqsx_provider_ctx.oqsx_qs_ctx.sig = OQS_SIG_new(oqs_name);
+ if (!ret->oqsx_provider_ctx.oqsx_qs_ctx.sig) {
+ fprintf(stderr, "Could not create OQS signature algorithm %s. Enabled in liboqs?\n", oqs_name);
+ goto err;
+ }
+ evp_ctx = OPENSSL_zalloc(sizeof(OQSX_EVP_CTX));
+ ON_ERR_GOTO(!evp_ctx, err);
+
+ ret2 = oqsx_hybsig_init(bit_security, evp_ctx, tls_name);
+ ON_ERR_GOTO(ret2 <= 0 || !evp_ctx->ctx, err);
+
+ ret->numkeys = 2;
+ ret->comp_privkey = OPENSSL_malloc(ret->numkeys * sizeof(void *));
+ ret->comp_pubkey = OPENSSL_malloc(ret->numkeys * sizeof(void *));
+ ret->privkeylen = (ret->numkeys-1) * SIZE_OF_UINT32 + ret->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_secret_key + evp_ctx->evp_info->length_private_key;
+ ret->pubkeylen = (ret->numkeys-1) * SIZE_OF_UINT32 + ret->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_public_key + evp_ctx->evp_info->length_public_key;
+ ret->oqsx_provider_ctx.oqsx_evp_ctx = evp_ctx;
+ ret->keytype = primitive;
+ ret->evp_info = evp_ctx->evp_info;
+ break;
+ default:
+ OQS_KEY_PRINTF2("OQSX_KEY: Unknown key type encountered: %d\n", primitive);
+ goto err;
+ }
+
+ ret->libctx = libctx;
+ ret->references = 1;
+ ret->tls_name = OPENSSL_strdup(tls_name);
+ ret->bit_security = bit_security;
+
+ if (propq != NULL) {
+ ret->propq = OPENSSL_strdup(propq);
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ if (ret->propq == NULL)
+ goto err;
+ }
+
+ OQS_KEY_PRINTF2("OQSX_KEY: new key created: %p\n", ret);
+ return ret;
+err:
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_free(ret);
+ return NULL;
+}
+
+void oqsx_key_free(OQSX_KEY *key)
+{
+ int refcnt;
+
+ if (key == NULL)
+ return;
+
+#ifndef OQS_PROVIDER_NOATOMIC
+ refcnt = atomic_fetch_sub_explicit(&key->references, 1,
+ memory_order_relaxed) - 1;
+ if (refcnt == 0)
+ atomic_thread_fence(memory_order_acquire);
+#else
+ CRYPTO_atomic_add(&key->references, -1, &refcnt, key->lock);
+#endif
+
+ OQS_KEY_PRINTF3("%p:%4d:OQSX_KEY\n", (void*)key, refcnt);
+ if (refcnt > 0)
+ return;
+#ifndef NDEBUG
+ assert(refcnt == 0);
+#endif
+
+ OPENSSL_free(key->propq);
+ OPENSSL_free(key->tls_name);
+ OPENSSL_secure_clear_free(key->privkey, key->privkeylen);
+ OPENSSL_secure_clear_free(key->pubkey, key->pubkeylen);
+ OPENSSL_free(key->comp_pubkey);
+ OPENSSL_free(key->comp_privkey);
+ if (key->keytype == KEY_TYPE_KEM)
+ OQS_KEM_free(key->oqsx_provider_ctx.oqsx_qs_ctx.kem);
+ else if (key->keytype == KEY_TYPE_ECP_HYB_KEM || key->keytype == KEY_TYPE_ECX_HYB_KEM) {
+ OQS_KEM_free(key->oqsx_provider_ctx.oqsx_qs_ctx.kem);
+ EVP_PKEY_CTX_free(key->oqsx_provider_ctx.oqsx_evp_ctx->ctx);
+ EVP_PKEY_free(key->oqsx_provider_ctx.oqsx_evp_ctx->keyParam);
+ OPENSSL_free(key->oqsx_provider_ctx.oqsx_evp_ctx);
+ } else
+ OQS_SIG_free(key->oqsx_provider_ctx.oqsx_qs_ctx.sig);
+ OPENSSL_free(key->classical_pkey);
+#ifdef OQS_PROVIDER_NOATOMIC
+ CRYPTO_THREAD_lock_free(key->lock);
+#endif
+ OPENSSL_free(key);
+}
+
+int oqsx_key_up_ref(OQSX_KEY *key)
+{
+ int refcnt;
+
+#ifndef OQS_PROVIDER_NOATOMIC
+ refcnt = atomic_fetch_add_explicit(&key->references, 1,
+ memory_order_relaxed) + 1;
+#else
+ CRYPTO_atomic_add(&key->references, 1, &refcnt, key->lock);
+#endif
+
+ OQS_KEY_PRINTF3("%p:%4d:OQSX_KEY\n", (void*)key, refcnt);
+#ifndef NDEBUG
+ assert(refcnt > 1);
+#endif
+ return (refcnt > 1);
+}
+
+int oqsx_key_allocate_keymaterial(OQSX_KEY *key, int include_private)
+{
+ int ret = 0;
+
+ if (!key->privkey && include_private) {
+ key->privkey = OPENSSL_secure_zalloc(key->privkeylen);
+ ON_ERR_SET_GOTO(!key->privkey, ret, 1, err);
+ }
+ if (!key->pubkey && !include_private) {
+ key->pubkey = OPENSSL_secure_zalloc(key->pubkeylen);
+ ON_ERR_SET_GOTO(!key->pubkey, ret, 1, err);
+ }
+ err:
+ return ret;
+}
+
+int oqsx_key_fromdata(OQSX_KEY *key, const OSSL_PARAM params[], int include_private)
+{
+ const OSSL_PARAM *p;
+
+ OQS_KEY_PRINTF("OQSX Key from data called\n");
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
+ if (p != NULL) {
+ if (p->data_type != OSSL_PARAM_OCTET_STRING) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
+ return 0;
+ }
+ if (key->privkeylen != p->data_size) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_SIZE);
+ return 0;
+ }
+ OPENSSL_secure_clear_free(key->privkey, p->data_size);
+ key->privkey = OPENSSL_secure_malloc(p->data_size);
+ if (key->privkey == NULL) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memcpy(key->privkey, p->data, p->data_size);
+ }
+ p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
+ if (p != NULL) {
+ if (p->data_type != OSSL_PARAM_OCTET_STRING) {
+ OQS_KEY_PRINTF("invalid data type\n");
+ return 0;
+ }
+ if (key->pubkeylen != p->data_size) {
+ ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_SIZE);
+ return 0;
+ }
+ OPENSSL_secure_clear_free(key->pubkey, p->data_size);
+ key->pubkey = OPENSSL_secure_malloc(p->data_size);
+ if (key->pubkey == NULL) {
+ ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memcpy(key->pubkey, p->data, p->data_size);
+ }
+ if (!oqsx_key_set_composites(key) || !oqsx_key_recreate_classickey(key, key->privkey!=NULL?KEY_OP_PRIVATE:KEY_OP_PUBLIC))
+ return 0;
+ return 1;
+}
+
+// OQS key always the last of the numkeys comp keys
+static int oqsx_key_gen_oqs(OQSX_KEY *key, int gen_kem) {
+ if (gen_kem)
+ return OQS_KEM_keypair(key->oqsx_provider_ctx.oqsx_qs_ctx.kem, key->comp_pubkey[key->numkeys-1], key->comp_privkey[key->numkeys-1]);
+ else
+ return OQS_SIG_keypair(key->oqsx_provider_ctx.oqsx_qs_ctx.sig, key->comp_pubkey[key->numkeys-1], key->comp_privkey[key->numkeys-1]);
+}
+
+/* Generate classic keys, store length in leading SIZE_OF_UINT32 bytes of pubkey/privkey buffers;
+ * returned EVP_PKEY must be freed if not used
+ */
+static EVP_PKEY* oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey, unsigned char *privkey)
+{
+ int ret = 0, ret2 = 0;
+
+ // Free at errhyb:
+ EVP_PKEY_CTX *kgctx = NULL;
+ EVP_PKEY *pkey = NULL;
+ unsigned char *pubkey_encoded = NULL;
+
+ size_t pubkeylen = 0, privkeylen = 0;
+
+ if (ctx->keyParam)
+ kgctx = EVP_PKEY_CTX_new(ctx->keyParam, NULL);
+ else
+ kgctx = EVP_PKEY_CTX_new_id( ctx->evp_info->nid, NULL );
+ ON_ERR_SET_GOTO(!kgctx, ret, -1, errhyb);
+
+ ret2 = EVP_PKEY_keygen_init(kgctx);
+ ON_ERR_SET_GOTO(ret2 <= 0, ret, -1, errhyb);
+ if (ctx->evp_info->keytype == EVP_PKEY_RSA) {
+ ret2 = EVP_PKEY_CTX_set_rsa_keygen_bits(kgctx, 3072);
+ ON_ERR_SET_GOTO(ret2 <= 0, ret, -1, errhyb);
+ }
+ ret2 = EVP_PKEY_keygen(kgctx, &pkey);
+ ON_ERR_SET_GOTO(ret2 <= 0, ret, -2, errhyb);
+
+ if (ctx->evp_info->raw_key_support) {
+ // TODO: If available, use preallocated memory
+ pubkeylen = EVP_PKEY_get1_encoded_public_key(pkey, &pubkey_encoded);
+ ON_ERR_SET_GOTO(pubkeylen != ctx->evp_info->length_public_key || !pubkey_encoded, ret, -3, errhyb);
+ memcpy(pubkey+SIZE_OF_UINT32, pubkey_encoded, pubkeylen);
+ privkeylen = ctx->evp_info->length_private_key;
+ ret2 = EVP_PKEY_get_raw_private_key(pkey, privkey+SIZE_OF_UINT32, &privkeylen);
+ ON_ERR_SET_GOTO(ret2 <= 0 || privkeylen != ctx->evp_info->length_private_key, ret, -4, errhyb);
+ }
+ else {
+ unsigned char* pubkey_enc = pubkey+SIZE_OF_UINT32;
+ const unsigned char* pubkey_enc2 = pubkey+SIZE_OF_UINT32;
+ pubkeylen = i2d_PublicKey(pkey, &pubkey_enc);
+ ON_ERR_SET_GOTO(!pubkey_enc || pubkeylen > (int) ctx->evp_info->length_public_key, ret, -11, errhyb);
+ unsigned char* privkey_enc = privkey+SIZE_OF_UINT32;
+ const unsigned char* privkey_enc2 = privkey+SIZE_OF_UINT32;
+ privkeylen = i2d_PrivateKey(pkey, &privkey_enc);
+ ON_ERR_SET_GOTO(!privkey_enc || privkeylen > (int) ctx->evp_info->length_private_key, ret, -12, errhyb);
+ // selftest:
+ EVP_PKEY* ck2 = d2i_PrivateKey(ctx->evp_info->keytype, NULL, &privkey_enc2, privkeylen);
+ ON_ERR_SET_GOTO(!ck2, ret, -14, errhyb);
+ }
+ ENCODE_UINT32(pubkey,pubkeylen);
+ ENCODE_UINT32(privkey,privkeylen);
+ OQS_KEY_PRINTF3("OQSKM: Storing classical privkeylen: %ld & pubkeylen: %ld\n", privkeylen, pubkeylen);
+
+ EVP_PKEY_CTX_free(kgctx);
+ OPENSSL_free(pubkey_encoded);
+ return pkey;
+
+ errhyb:
+ EVP_PKEY_CTX_free(kgctx);
+ EVP_PKEY_free(pkey);
+ OPENSSL_free(pubkey_encoded);
+ return NULL;
+}
+
+/* allocates OQS and classical keys; retains EVP_PKEY on success for sig OQSX_KEY */
+int oqsx_key_gen(OQSX_KEY *key)
+{
+ int ret = 0;
+ EVP_PKEY* pkey = NULL;
+
+ if (key->privkey == NULL || key->pubkey == NULL) {
+ ret = oqsx_key_allocate_keymaterial(key, 0) || oqsx_key_allocate_keymaterial(key, 1);
+ ON_ERR_GOTO(ret, err);
+ }
+
+ if (key->keytype == KEY_TYPE_KEM) {
+ ret = !oqsx_key_set_composites(key);
+ ON_ERR_GOTO(ret, err);
+ ret = oqsx_key_gen_oqs(key, 1);
+ } else if (key->keytype == KEY_TYPE_ECP_HYB_KEM || key->keytype == KEY_TYPE_ECX_HYB_KEM || key->keytype == KEY_TYPE_HYB_SIG) {
+ pkey = oqsx_key_gen_evp_key(key->oqsx_provider_ctx.oqsx_evp_ctx, key->pubkey, key->privkey);
+ ON_ERR_GOTO(pkey==NULL, err);
+ ret = !oqsx_key_set_composites(key);
+ ON_ERR_GOTO(ret, err);
+ OQS_KEY_PRINTF3("OQSKM: OQSX_KEY privkeylen %ld & pubkeylen: %ld\n", key->privkeylen, key->pubkeylen);
+
+ if (key->keytype == KEY_TYPE_HYB_SIG) {
+ key->classical_pkey = pkey;
+ ret = oqsx_key_gen_oqs(key, 0);
+ }
+ else {
+ EVP_PKEY_free(pkey);
+ ret = oqsx_key_gen_oqs(key, 1);
+ }
+ } else if (key->keytype == KEY_TYPE_SIG) {
+ ret = !oqsx_key_set_composites(key);
+ ON_ERR_GOTO(ret, err);
+ ret = oqsx_key_gen_oqs(key, 0);
+ } else {
+ ret = 1;
+ }
+ err:
+ if (ret) {
+ EVP_PKEY_free(pkey);
+ key->classical_pkey = NULL;
+ }
+ return ret;
+}
+
+int oqsx_key_secbits(OQSX_KEY *key) {
+ return key->bit_security;
+}
+
+int oqsx_key_maxsize(OQSX_KEY *key) {
+ switch(key->keytype) {
+ case KEY_TYPE_KEM:
+ return key->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_shared_secret;
+ case KEY_TYPE_ECP_HYB_KEM:
+ case KEY_TYPE_ECX_HYB_KEM:
+ return key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->kex_length_secret + key->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_shared_secret;
+ case KEY_TYPE_SIG:
+ return key->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_signature;
+ case KEY_TYPE_HYB_SIG:
+ return key->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_signature + key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->length_signature+SIZE_OF_UINT32;
+ default:
+ OQS_KEY_PRINTF("OQSX KEY: Wrong key type\n");
+ return 0;
+ }
+}
+
+int oqsx_key_get_oqs_public_key_len(OQSX_KEY *k) {
+ switch(k->keytype) {
+ case KEY_TYPE_SIG:
+ case KEY_TYPE_KEM:
+ return k->pubkeylen;
+ case KEY_TYPE_HYB_SIG:
+ return k->oqsx_provider_ctx.oqsx_qs_ctx.sig->length_public_key;
+ case KEY_TYPE_ECX_HYB_KEM:
+ case KEY_TYPE_ECP_HYB_KEM:
+ return k->oqsx_provider_ctx.oqsx_qs_ctx.kem->length_public_key;
+ default:
+ OQS_KEY_PRINTF2("OQSX_KEY: Unknown key type encountered: %d\n", k->keytype);
+ return -1;
+ }
+}
--- /dev/null
+#!/bin/bash
+
+# The following variables influence the operation of this build script:
+# Argument -f: Soft clean, ensuring re-build of oqs-provider binary
+# Argument -F: Hard clean, ensuring checkout and build of all dependencies
+# EnvVar MAKE_PARAMS: passed to invocations of make; sample value: "-j"
+# EnvVar LIBOQS_BRANCH: Defines branch/release of liboqs; default value "main"
+# EnvVar OQS_ALGS_ENABLED: If set, defines OQS algs to be enabled, e.g., "STD"
+# EnvVar OPENSSL_INSTALL: If set, defines (binary) OpenSSL installation to use
+# EnvVar OPENSSL_BRANCH: Defines branch/release of openssl; if set, forces source-build of OpenSSL3
+# EnvVar liboqs_DIR: If set, needs to point to a directory where liboqs has been installed to
+
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ SHLIBEXT="dylib"
+ STATLIBEXT="dylib"
+else
+ SHLIBEXT="so"
+ STATLIBEXT="a"
+fi
+
+if [ $# -gt 0 ]; then
+ if [ "$1" == "-f" ]; then
+ rm -rf _build
+ fi
+ if [ "$1" == "-F" ]; then
+ rm -rf _build openssl liboqs .local
+ fi
+fi
+
+if [ -z "$LIBOQS_BRANCH" ]; then
+ export LIBOQS_BRANCH=main
+fi
+
+if [ -z "$OQS_ALGS_ENABLED" ]; then
+ export DOQS_ALGS_ENABLED=""
+else
+ export DOQS_ALGS_ENABLED="$OQS_ALGS_ENABLED"
+fi
+
+if [ -z "$OPENSSL_INSTALL" ]; then
+ openssl version | grep "OpenSSL 3" > /dev/null 2>&1
+ #if [ \($? -ne 0 \) -o \( ! -z "$OPENSSL_BRANCH" \) ]; then
+ if [ $? -ne 0 ] || [ ! -z "$OPENSSL_BRANCH" ]; then
+ if [ -z "$OPENSSL_BRANCH" ]; then
+ export OPENSSL_BRANCH="master"
+ fi
+ # No OSSL3 installation given/found, or specific branch build requested
+ echo "OpenSSL3 to be built from source at branch $OPENSSL_BRANCH."
+
+ if [ ! -d "openssl" ]; then
+ echo "openssl not specified and doesn't reside where expected: Cloning and building..."
+ # for full debug build add: enable-trace enable-fips --debug
+ export OSSL_PREFIX=`pwd`/.local && git clone --depth 1 --branch $OPENSSL_BRANCH git://git.openssl.org/openssl.git && cd openssl && LDFLAGS="-Wl,-rpath -Wl,${OSSL_PREFIX}/lib64" ./config --prefix=$OSSL_PREFIX && make $MAKE_PARAMS && make install_sw install_ssldirs && cd ..
+ if [ $? -ne 0 ]; then
+ echo "openssl build failed. Exiting."
+ exit -1
+ else
+ # some cmake versions don't look in "lib64", so aid their search with this softlink
+ cd $OSSL_PREFIX && if [ -d "lib64" ]; then ln -s lib64 lib; fi && cd ..
+ export OPENSSL_INSTALL=$OSSL_PREFIX
+ fi
+ else
+ if [ -d ".local" ]; then
+ export OPENSSL_INSTALL=`pwd`/.local
+ fi
+ fi
+ fi
+fi
+
+# Check whether liboqs is built or has been configured:
+if [ -z $liboqs_DIR ]; then
+ if [ ! -f ".local/lib/liboqs.$STATLIBEXT" ]; then
+ echo "need to re-build static liboqs..."
+ if [ ! -d liboqs ]; then
+ echo "cloning liboqs $LIBOQS_BRANCH..."
+ git clone --depth 1 --branch $LIBOQS_BRANCH https://github.com/open-quantum-safe/liboqs.git
+ if [ $? -ne 0 ]; then
+ echo "liboqs clone failure for branch $LIBOQS_BRANCH. Exiting."
+ exit -1
+ fi
+ if [ "$LIBOQS_BRANCH" != "main" ]; then
+ # check for presence of backwards-compatibility generator file
+ if [ -f oqs-template/generate.yml-$LIBOQS_BRANCH ]; then
+ echo "generating code for $LIBOQS_BRANCH"
+ mv oqs-template/generate.yml oqs-template/generate.yml-main
+ cp oqs-template/generate.yml-$LIBOQS_BRANCH oqs-template/generate.yml
+ LIBOQS_SRC_DIR=`pwd`/liboqs python3 oqs-template/generate.py
+ if [ $? -ne 0 ]; then
+ echo "Code generation failure for $LIBOQS_BRANCH. Exiting."
+ exit -1
+ fi
+ fi
+ fi
+ fi
+
+ # Ensure liboqs is built against OpenSSL3, not a possibly still system-
+ # installed OpenSSL111: We otherwise have mismatching symbols at runtime
+ # (detected particularly late when building shared)
+ if [ ! -z $OPENSSL_INSTALL ]; then
+ export CMAKE_OPENSSL_LOCATION="-DOPENSSL_ROOT_DIR=$OPENSSL_INSTALL"
+ else
+ export CMAKE_OPENSSL_LOCATION=""
+ fi
+ # for full debug build add: -DCMAKE_BUILD_TYPE=Debug
+ # to optimize for size add -DOQS_ALGS_ENABLED= suitably to one of these values:
+ # STD: only include NIST standardized algorithms
+ # NIST_R4: only include algorithms in round 4 of the NIST competition
+ # All: include all algorithms supported by liboqs (default)
+ cd liboqs && cmake -GNinja $DOQS_ALGS_ENABLED $CMAKE_OPENSSL_LOCATION -DCMAKE_INSTALL_PREFIX=$(pwd)/../.local -S . -B _build && cd _build && ninja && ninja install && cd ../..
+ if [ $? -ne 0 ]; then
+ echo "liboqs build failed. Exiting."
+ exit -1
+ fi
+ fi
+ export liboqs_DIR=$(pwd)/.local
+fi
+
+# Check whether provider is built:
+if [ ! -f "_build/lib/oqsprovider.$SHLIBEXT" ]; then
+ echo "oqsprovider (_build/lib/oqsprovider.$SHLIBEXT) not built: Building..."
+ # for full debug build add: -DCMAKE_BUILD_TYPE=Debug
+ #BUILD_TYPE="-DCMAKE_BUILD_TYPE=Debug"
+ BUILD_TYPE=""
+ # for omitting public key in private keys add -DNOPUBKEY_IN_PRIVKEY=ON
+ if [ -z "$OPENSSL_INSTALL" ]; then
+ cmake -DOPENSSL_ROOT_DIR=$(pwd)/.local $BUILD_TYPE -S . -B _build && cmake --build _build
+ else
+ cmake -DOPENSSL_ROOT_DIR=$OPENSSL_INSTALL $BUILD_TYPE -S . -B _build && cmake --build _build
+ fi
+ if [ $? -ne 0 ]; then
+ echo "provider build failed. Exiting."
+ exit -1
+ fi
+fi
+
--- /dev/null
+#
+# OpenSSL example configuration file.
+# See doc/man5/config.pod for more info.
+#
+# This is mostly being used for generation of certificate requests,
+# but may be used for auto loading of providers
+
+# Note that you can include other files from the main configuration
+# file using the .include directive.
+#.include filename
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME = .
+
+# Use this in order to automatically load providers.
+openssl_conf = openssl_init
+
+# Comment out the next line to ignore configuration errors
+config_diagnostics = 1
+
+# Extra OBJECT IDENTIFIER info:
+# oid_file = $ENV::HOME/.oid
+oid_section = new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions =
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+# For FIPS
+# Optionally include a file that is generated by the OpenSSL fipsinstall
+# application. This file contains configuration data required by the OpenSSL
+# fips provider. It contains a named section e.g. [fips_sect] which is
+# referenced from the [provider_sect] below.
+# Refer to the OpenSSL security policy for more information.
+# .include fipsmodule.cnf
+
+[openssl_init]
+providers = provider_sect
+
+# List of providers to load
+[provider_sect]
+default = default_sect
+oqsprovider = oqsprovider_sect
+oqsprovider2 = oqsprovider2_sect
+
+# The fips section name should match the section name inside the
+# included fipsmodule.cnf.
+# fips = fips_sect
+
+# If no providers are activated explicitly, the default one is activated implicitly.
+# See man 7 OSSL_PROVIDER-default for more details.
+#
+# If you add a section explicitly activating any other provider(s), you most
+# probably need to explicitly activate the default provider, otherwise it
+# becomes unavailable in openssl. As a consequence applications depending on
+# OpenSSL may not work correctly which could lead to significant system
+# problems including inability to remotely access the system.
+[default_sect]
+activate = 1
+
+[oqsprovider_sect]
+activate = 1
+# This second provider instance can be activated (for testing) for example
+# by creating a softlink with suitable name "oqsprovider2" to the originally
+# created oqsprovider.{so|dylib|dll}
+[oqsprovider2_sect]
+activate = 1
+
+# activate = 1
+
+
+####################################################################
+[ ca ]
+default_ca = CA_default # The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir = ./demoCA # Where everything is kept
+certs = $dir/certs # Where the issued certs are kept
+crl_dir = $dir/crl # Where the issued crl are kept
+database = $dir/index.txt # database index file.
+#unique_subject = no # Set to 'no' to allow creation of
+ # several certs with same subject.
+new_certs_dir = $dir/newcerts # default place for new certs.
+
+certificate = $dir/cacert.pem # The CA certificate
+serial = $dir/serial # The current serial number
+rand_serial = no
+crlnumber = $dir/crlnumber # the current crl number
+ # must be commented out to leave a V1 CRL
+crl = $dir/crl.pem # The current CRL
+private_key = $dir/private/cakey.pem # The private key
+
+x509_extensions = usr_cert # The extensions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt = ca_default # Subject Name options
+cert_opt = ca_default # Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions = crl_ext
+
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = sha256 # use public key default MD
+preserve = no # keep passed DN ordering
+email_in_dn = no
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy = policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName = match
+stateOrProvinceName = match
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+####################################################################
+[ req ]
+default_bits = 2048
+default_keyfile = privkey.pem
+distinguished_name = req_distinguished_name
+attributes = req_attributes
+x509_extensions = v3_ca # The extensions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_min = 2
+countryName_max = 2
+
+stateOrProvinceName = State or Province Name (full name)
+stateOrProvinceName_default = Some-State
+
+localityName = Locality Name (eg, city)
+
+0.organizationName = Organization Name (eg, company)
+0.organizationName_default = Internet Widgits Pty Ltd
+
+# we can do this but it is not needed normally :-)
+#1.organizationName = Second Organization Name (eg, company)
+#1.organizationName_default = World Wide Web Pty Ltd
+
+organizationalUnitName = Organizational Unit Name (eg, section)
+#organizationalUnitName_default =
+
+commonName = Common Name (e.g. server FQDN or YOUR name)
+commonName_max = 64
+
+emailAddress = Email Address
+emailAddress_max = 64
+
+# SET-ex3 = SET extension number 3
+
+[ req_attributes ]
+challengePassword = A challenge password
+challengePassword_min = 4
+challengePassword_max = 20
+
+unstructuredName = An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer
+
+basicConstraints = critical,CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1 # the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir = ./demoCA # TSA root directory
+serial = $dir/tsaserial # The current serial number (mandatory)
+crypto_device = builtin # OpenSSL engine to use for signing
+signer_cert = $dir/tsacert.pem # The TSA signing certificate
+ # (optional)
+certs = $dir/cacert.pem # Certificate chain to include in reply
+ # (optional)
+signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
+signer_digest = sha256 # Signing digest to use. (Optional)
+default_policy = tsa_policy1 # Policy if request did not specify it
+ # (optional)
+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
+digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory)
+accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
+clock_precision_digits = 0 # number of digits after dot. (optional)
+ordering = yes # Is ordering defined for timestamps?
+ # (optional, default: no)
+tsa_name = yes # Must the TSA name be included in the reply?
+ # (optional, default: no)
+ess_cert_id_chain = no # Must the ESS cert id chain be included?
+ # (optional, default: no)
+ess_cert_id_alg = sha1 # algorithm to compute certificate
+ # identifier (optional, default: sha1)
+
+[insta] # CMP using Insta Demo CA
+# Message transfer
+server = pki.certificate.fi:8700
+# proxy = # set this as far as needed, e.g., http://192.168.1.1:8080
+# tls_use = 0
+path = pkix/
+
+# Server authentication
+recipient = "/C=FI/O=Insta Demo/CN=Insta Demo CA" # or set srvcert or issuer
+ignore_keyusage = 1 # potentially needed quirk
+unprotected_errors = 1 # potentially needed quirk
+extracertsout = insta.extracerts.pem
+
+# Client authentication
+ref = 3078 # user identification
+secret = pass:insta # can be used for both client and server side
+
+# Generic message options
+cmd = ir # default operation, can be overridden on cmd line with, e.g., kur
+
+# Certificate enrollment
+subject = "/CN=openssl-cmp-test"
+newkey = insta.priv.pem
+out_trusted = insta.ca.crt
+certout = insta.cert.pem
+
+[pbm] # Password-based protection for Insta CA
+# Server and client authentication
+ref = $insta::ref # 3078
+secret = $insta::secret # pass:insta
+
+[signature] # Signature-based protection for Insta CA
+# Server authentication
+trusted = insta.ca.crt # does not include keyUsage digitalSignature
+
+# Client authentication
+secret = # disable PBM
+key = $insta::newkey # insta.priv.pem
+cert = $insta::certout # insta.cert.pem
+
+[ir]
+cmd = ir
+
+[cr]
+cmd = cr
+
+[kur]
+# Certificate update
+cmd = kur
+oldcert = $insta::certout # insta.cert.pem
+
+[rr]
+# Certificate revocation
+cmd = rr
+oldcert = $insta::certout # insta.cert.pem
+
+[pkcs12]
+certBagAttr = cb_attr
+
+# Uncomment this if you need Java compatible PKCS12 files
+[cb_attr]
+#jdkTrustedKeyUsage = anyExtendedKeyUsage
--- /dev/null
+#!/bin/bash
+
+# Use dockerimage to generate certs for alg $1
+
+IMAGE=openquantumsafe/curl
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 <algorithmname>. Exiting."
+ exit 1
+fi
+
+#rm -rf tmp
+mkdir -p tmp
+
+if [[ -z "$CIRCLECI" ]]; then
+docker run -v `pwd`/tmp:/home/oqs/data -it $IMAGE sh -c "cd /home/oqs/data && openssl req -x509 -new -newkey $1 -keyout $1_CA.key -out $1_CA.crt -nodes -subj \"/CN=oqstest CA\" -days 365 -config /opt/oqssa/ssl/openssl.cnf && openssl genpkey -algorithm $1 -out $1_srv.key && openssl req -new -newkey $1 -keyout $1_srv.key -out $1_srv.csr -nodes -subj \"/CN=oqstest server\" -config /opt/oqssa/ssl/openssl.cnf && openssl x509 -req -in $1_srv.csr -out $1_srv.crt -CA $1_CA.crt -CAkey $1_CA.key -CAcreateserial -days 365 && openssl verify -CAfile $1_CA.crt $1_srv.crt"
+else
+# CCI doesn't permit mounting, so let's do as per https://circleci.com/docs/2.0/building-docker-images/#mounting-folders:
+docker run --name oqsossl -it $IMAGE sh -c "mkdir /home/oqs/tmp && cd /home/oqs/tmp && openssl req -x509 -new -newkey $1 -keyout $1_CA.key -out $1_CA.crt -nodes -subj \"/CN=oqstest CA\" -days 365 -config /opt/oqssa/ssl/openssl.cnf && openssl genpkey -algorithm $1 -out $1_srv.key && openssl req -new -newkey $1 -keyout $1_srv.key -out $1_srv.csr -nodes -subj \"/CN=oqstest server\" -config /opt/oqssa/ssl/openssl.cnf && openssl x509 -req -in $1_srv.csr -out $1_srv.crt -CA $1_CA.crt -CAkey $1_CA.key -CAcreateserial -days 365 && openssl verify -CAfile $1_CA.crt $1_srv.crt"
+docker cp oqsossl:/home/oqs/tmp .
+docker rm oqsossl
+fi
+
--- /dev/null
+#!/bin/bash
+
+# Use dockerimage to verify certs for alg $1
+
+IMAGE=openquantumsafe/curl
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 <algorithmname>. Exiting."
+ exit 1
+fi
+
+if [ ! -d tmp ]; then
+ echo "Test folder tmp not existing. Exiting."
+ exit 1
+fi
+
+if [ ! -f tmp/$1_srv.crt ]; then
+ echo "Cert to test not present. Exiting."
+ exit 1
+fi
+
+if [[ -z "$CIRCLECI" ]]; then
+docker run -v `pwd`/tmp:/home/oqs/data -it $IMAGE sh -c "cd /home/oqs/data && openssl verify -CAfile $1_CA.crt $1_srv.crt"
+else
+# CCI doesn't permit mounting, so let's do as per https://circleci.com/docs/2.0/building-docker-images/#mounting-folders:
+docker create -v /certs --name certs alpine /bin/true && \
+chmod gou+rw tmp/* && \
+docker cp tmp/ certs:/certs && \
+docker run --volumes-from certs -it $IMAGE sh -c "cd /certs/tmp && openssl verify -CAfile $1_CA.crt $1_srv.crt" && \
+docker rm /certs
+fi
--- /dev/null
+#!/bin/bash
+
+# Use dockerimage to generate CMS data for alg $1
+
+IMAGE=openquantumsafe/curl
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 <algorithmname>. Exiting."
+ exit 1
+fi
+
+# Assumes certgen has been run before: Quick check
+
+if [ -f tmp/$1_CA.crt ]; then
+ echo "Sometext to sign" > tmp/inputfile
+else
+ echo "File tmp/$1_CA.crt not found. Did certgen run before? Exiting."
+ exit -1
+fi
+
+openssl_version=$($OPENSSL_APP version)
+
+if [[ "$openssl_version" == "OpenSSL 3.0."* ]]; then
+ echo "Skipping CMS test for OpenSSL 3.0"
+ exit 0
+fi
+
+if [[ -z "$CIRCLECI" ]]; then
+docker run -v `pwd`/tmp:/home/oqs/data -it $IMAGE sh -c "cd /home/oqs/data && openssl cms -in inputfile -sign -signer $1_srv.crt -inkey $1_srv.key -nodetach -outform pem -binary -out signedfile.cms && openssl cms -verify -CAfile $1_CA.crt -inform pem -in signedfile.cms -crlfeol -out signeddatafile "
+else
+# CCI doesn't permit mounting, so let's do as per https://circleci.com/docs/2.0/building-docker-images/#mounting-folders:
+docker create -v /certs --name certs alpine /bin/true && \
+touch tmp/signedfile.cms && touch tmp/signeddatafile && chmod gou+rw tmp/* && \
+docker cp tmp/ certs:/certs && \
+docker run --volumes-from certs --rm --name oqsossl -it $IMAGE sh -c "cd /certs/tmp && openssl cms -in inputfile -sign -signer $1_srv.crt -inkey $1_srv.key -nodetach -outform pem -binary -out signedfile.cms && openssl cms -verify -CAfile $1_CA.crt -inform pem -in signedfile.cms -crlfeol -out signeddatafile " && \
+docker cp certs:/certs/tmp . && \
+docker rm certs
+fi
+
--- /dev/null
+#!/bin/bash
+
+#set -x
+
+# Use dockerimage to verify certs for alg $1
+
+IMAGE=openquantumsafe/curl
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 <algorithmname>. Exiting."
+ exit 1
+fi
+
+if [ ! -d tmp ]; then
+ echo "Test folder tmp not existing. Exiting."
+ exit 1
+fi
+
+if [ ! -f tmp/$1_srv.crt ]; then
+ echo "Cert to test not present. Exiting."
+ exit 1
+fi
+
+openssl_version=$($OPENSSL_APP version)
+
+if [[ "$openssl_version" == "OpenSSL 3.0."* ]]; then
+ echo "Skipping CMS test for OpenSSL 3.0"
+ exit 0
+fi
+
+if [[ -z "$CIRCLECI" ]]; then
+docker run -v `pwd`/tmp:/home/oqs/data -it $IMAGE sh -c "cd /home/oqs/data && openssl cms -verify -CAfile $1_CA.crt -inform pem -in signedfile.cms -crlfeol -out signeddatafile && diff signeddatafile inputfile"
+else
+# CCI doesn't permit mounting, so let's do as per https://circleci.com/docs/2.0/building-docker-images/#mounting-folders:
+docker create -v /certs --name certs alpine /bin/true && \
+chmod gou+rw tmp/* && \
+docker cp tmp/ certs:/certs && \
+docker run --volumes-from certs -it $IMAGE sh -c "cd /certs/tmp && openssl cms -verify -CAfile $1_CA.crt -inform pem -in signedfile.cms -crlfeol -out signeddatafile && diff signeddatafile inputfile" && \
+docker rm certs
+fi
--- /dev/null
+#!/bin/bash
+
+# Test openssl CA functionality using oqsprovider for alg $1
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 <algorithmname>. Exiting."
+ exit 1
+fi
+
+if [ -z "$OPENSSL_APP" ]; then
+ echo "OPENSSL_APP env var not set. Exiting."
+ exit 1
+fi
+
+if [ -z "$OPENSSL_MODULES" ]; then
+ echo "Warning: OPENSSL_MODULES env var not set."
+fi
+
+if [ -z "$OPENSSL_CONF" ]; then
+ echo "Warning: OPENSSL_CONF env var not set."
+fi
+
+# Set OSX DYLD_LIBRARY_PATH if not already externally set
+if [ -z "$DYLD_LIBRARY_PATH" ]; then
+ export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
+fi
+
+echo "oqsprovider-ca.sh commencing..."
+
+#rm -rf tmp
+mkdir -p tmp && cd tmp
+rm -rf demoCA && mkdir -p demoCA/newcerts
+touch demoCA/index.txt
+echo '01' > demoCA/serial
+$OPENSSL_APP req -x509 -new -newkey $1 -keyout $1_rootCA.key -out $1_rootCA.crt -subj "/CN=test CA" -nodes
+
+if [ $? -ne 0 ]; then
+ echo "Failed to generate root CA. Exiting."
+ exit 1
+fi
+
+$OPENSSL_APP req -new -newkey $1 -keyout $1.key -out $1.csr -nodes -subj "/CN=test Server"
+
+if [ $? -ne 0 ]; then
+ echo "Failed to generate test server CSR. Exiting."
+ exit 1
+fi
+
+$OPENSSL_APP ca -batch -startdate 150123080000Z -enddate 250823090000Z -keyfile $1_rootCA.key -cert $1_rootCA.crt -policy policy_anything -notext -out $1.crt -infiles $1.csr
+
+if [ $? -ne 0 ]; then
+ echo "Failed to generate server CRT. Exiting."
+ exit 1
+fi
+
+# Don't forget to use provider(s) when not activated via config file
+$OPENSSL_APP verify -CAfile $1_rootCA.crt $1.crt
+
--- /dev/null
+#!/bin/bash
+
+# Use newly built oqsprovider to generate certs for alg $1
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 <algorithmname>. Exiting."
+ exit 1
+fi
+
+if [ -z "$OPENSSL_APP" ]; then
+ echo "OPENSSL_APP env var not set. Exiting."
+ exit 1
+fi
+
+if [ -z "$OPENSSL_MODULES" ]; then
+ echo "Warning: OPENSSL_MODULES env var not set."
+fi
+
+# Set OSX DYLD_LIBRARY_PATH if not already externally set
+if [ -z "$DYLD_LIBRARY_PATH" ]; then
+ export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
+fi
+
+echo "oqsprovider-certgen.sh commencing..."
+
+#rm -rf tmp
+mkdir -p tmp
+
+$OPENSSL_APP req -x509 -new -newkey $1 -keyout tmp/$1_CA.key -out tmp/$1_CA.crt -nodes -subj "/CN=oqstest CA" -days 365 && \
+$OPENSSL_APP genpkey -algorithm $1 -out tmp/$1_srv.key && \
+$OPENSSL_APP req -new -newkey $1 -keyout tmp/$1_srv.key -out tmp/$1_srv.csr -nodes -subj "/CN=oqstest server" && \
+$OPENSSL_APP x509 -req -in tmp/$1_srv.csr -out tmp/$1_srv.crt -CA tmp/$1_CA.crt -CAkey tmp/$1_CA.key -CAcreateserial -days 365 && \
+$OPENSSL_APP verify -CAfile tmp/$1_CA.crt tmp/$1_srv.crt
+
+#fails:
+#$OPENSSL_APP verify -CAfile tmp/$1_CA.crt tmp/$1_srv.crt -provider oqsprovider -provider default
+
--- /dev/null
+#!/bin/bash
+
+# Use newly built oqsprovider to generate certs for alg $1
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 <algorithmname>. Exiting."
+ exit 1
+fi
+
+if [ -z "$OPENSSL_APP" ]; then
+ echo "OPENSSL_APP env var not set. Exiting."
+ exit 1
+fi
+
+if [ -z "$OPENSSL_MODULES" ]; then
+ echo "Warning: OPENSSL_MODULES env var not set."
+fi
+
+# Set OSX DYLD_LIBRARY_PATH if not already externally set
+if [ -z "$DYLD_LIBRARY_PATH" ]; then
+ export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
+fi
+
+echo "oqsprovider-certverify.sh commencing..."
+
+# check that CSR can be output OK
+
+$OPENSSL_APP req -text -in tmp/$1_srv.csr -noout 2>&1 | grep Error
+if [ $? -eq 0 ]; then
+ echo "Couldn't print CSR correctly. Exiting."
+ exit 1
+fi
+
+$OPENSSL_APP verify -CAfile tmp/$1_CA.crt tmp/$1_srv.crt
+
--- /dev/null
+#!/bin/bash
+
+# Use newly built oqsprovider to generate CMS signed files for alg $1
+# Also used to test X509 pubkey extract and sign/verify using openssl dgst
+# Assumed oqsprovider-certgen.sh to have run before for same algorithm
+
+# uncomment to see what's happening:
+#set -x
+
+if [ $# -lt 1 ]; then
+ echo "Usage: $0 <algorithmname> [digestname]. Exiting."
+ exit 1
+fi
+
+echo "oqsprovider-cmssign.sh commencing..."
+
+if [ $# -eq 2 ]; then
+ DGSTNAME=$2
+else
+ DGSTNAME="sha512"
+fi
+
+if [ -z "$OPENSSL_APP" ]; then
+ echo "OPENSSL_APP env var not set. Exiting."
+ exit 1
+fi
+
+if [ -z "$OPENSSL_MODULES" ]; then
+ echo "Warning: OPENSSL_MODULES env var not set."
+fi
+
+# Set OSX DYLD_LIBRARY_PATH if not already externally set
+if [ -z "$DYLD_LIBRARY_PATH" ]; then
+ export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
+fi
+
+# Assumes certgen has been run before: Quick check
+
+if [ -f tmp/$1_CA.crt ]; then
+ echo "Sometext to sign" > tmp/inputfile
+ # Activate to test with zero-length inputfile:
+ #cat /dev/null > tmp/inputfile
+else
+ echo "File tmp/$1_CA.crt not found. Did certgen run before? Exiting."
+ exit -1
+fi
+
+openssl_version=$($OPENSSL_APP version)
+
+if [[ "$openssl_version" == "OpenSSL 3.0."* ]]; then
+ echo "Skipping CMS test for OpenSSL 3.0: Support only starting with 3.2"
+ exit 0
+fi
+
+# dgst test:
+$OPENSSL_APP x509 -in tmp/$1_srv.crt -pubkey -noout > tmp/$1_srv.pubkey && $OPENSSL_APP cms -in tmp/inputfile -sign -signer tmp/$1_srv.crt -inkey tmp/$1_srv.key -nodetach -outform pem -binary -out tmp/signedfile.cms -md $DGSTNAME && $OPENSSL_APP dgst -sign tmp/$1_srv.key -out tmp/dgstsignfile tmp/inputfile
+
+if [ $? -eq 0 ]; then
+# cms test:
+ $OPENSSL_APP cms -verify -CAfile tmp/$1_CA.crt -inform pem -in tmp/signedfile.cms -crlfeol -out tmp/signeddatafile && diff tmp/signeddatafile tmp/inputfile && $OPENSSL_APP dgst -signature tmp/dgstsignfile -verify tmp/$1_srv.pubkey tmp/inputfile
+else
+ exit -1
+fi
+
--- /dev/null
+#!/bin/bash
+
+# Use newly built oqsprovider to generate CMS signed files for alg $1
+# Assumed oqsprovider-certgen.sh to have run before for same algorithm
+
+# uncomment to see what's happening:
+# set -x
+
+if [ $# -ne 1 ]; then
+ echo "Usage: $0 <algorithmname>. Exiting."
+ exit 1
+fi
+
+if [ -z "$OPENSSL_APP" ]; then
+ echo "OPENSSL_APP env var not set. Exiting."
+ exit 1
+fi
+
+if [ -z "$OPENSSL_MODULES" ]; then
+ echo "Warning: OPENSSL_MODULES env var not set."
+fi
+
+# Set OSX DYLD_LIBRARY_PATH if not already externally set
+if [ -z "$DYLD_LIBRARY_PATH" ]; then
+ export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
+fi
+
+openssl_version=$($OPENSSL_APP version)
+
+if [[ "$openssl_version" == "OpenSSL 3.0."* ]]; then
+ echo "Skipping CMS test for OpenSSL 3.0"
+ exit 0
+fi
+
+# Assumes certgen has been run before: Quick check for CMS file:
+
+if [ -f tmp/signedfile.cms ]; then
+ $OPENSSL_APP cms -verify -CAfile tmp/$1_CA.crt -inform pem -in tmp/signedfile.cms -crlfeol -out tmp/signeddatafile
+ diff tmp/signeddatafile tmp/inputfile
+else
+ echo "File tmp/signedfile.cms not found. Did CMS sign run before? Exiting."
+ exit -1
+fi
+
--- /dev/null
+class Oqsprovider < Formula
+ desc "OpenSSL3 provider integrating quantum safe cryptography"
+ homepage "https://www.openquantumsafe.org"
+ url "https://github.com/open-quantum-safe/oqs-provider/archive/refs/tags/0.5.0.tar.gz"
+ sha256 "8b954eac7109084600825ab6f3a1dd861c5de043d2b6e4563ffc68406c2b20a5"
+ license "MIT"
+ head "https://github.com/open-quantum-safe/oqs-provider.git", branch: "main"
+
+ depends_on "cmake" => :build
+ depends_on "liboqs"
+ depends_on "openssl@3"
+
+ def install
+ system "cmake", "-S", ".", "-B", "build", *std_cmake_args
+ system "cmake", "--build", "build"
+ with_env(CC: DevelopmentTools.locate(DevelopmentTools.default_compiler)) do
+ system "ctest", "--parallel", "5", "--test-dir", "build", "--rerun-failed", "--output-on-failure"
+ end
+# Do not install as part of testing -- only when deployed; so comment out for now:
+# system "cmake", "--install", "build"
+# ohai "Update system openssl.cnf to activate oqsprovider by default;"
+# ohai " otherwise use 'openssl <command> -provider oqsprovider' to activate."
+ end
+
+ test do
+ # This checks oqsprovider is available and executes within standard openssl installation
+ output = shell_output("openssl list -providers -provider-path #{lib} -provider oqsprovider")
+ assert_match("OpenSSL OQS Provider", output)
+ end
+end
--- /dev/null
+#!/bin/bash
+
+# This script reverts to a possibly set "main" code generator script
+
+if [ -f oqs-template/generate.yml-main ]; then
+ rm -rf liboqs && git clone --depth 1 --branch main https://github.com/open-quantum-safe/liboqs.git
+ mv oqs-template/generate.yml-main oqs-template/generate.yml
+ LIBOQS_SRC_DIR=`pwd`/liboqs python3 oqs-template/generate.py
+ if [ $? -ne 0 ]; then
+ echo "Code generation failure for main branch. Exiting."
+ exit -1
+ fi
+ # remove liboqs.a to ensure rebuild against newly generated code
+ rm .local/lib/liboqs.a
+ git status
+fi
+
--- /dev/null
+#!/bin/sh
+
+set -e
+
+rv=0
+
+provider2openssl() {
+ echo
+ echo "Testing oqsprovider->oqs-openssl interop for $1:"
+ "${OQS_PROVIDER_TESTSCRIPTS}/oqsprovider-certgen.sh" "$1" && "${OQS_PROVIDER_TESTSCRIPTS}/oqsprovider-cmssign.sh" "$1" sha3-384 && "${OQS_PROVIDER_TESTSCRIPTS}/oqs-openssl-certverify.sh" "$1" && "${OQS_PROVIDER_TESTSCRIPTS}/oqs-openssl-cmsverify.sh" "$1"
+}
+
+openssl2provider() {
+ echo
+ echo "Testing oqs-openssl->oqsprovider interop for $1:"
+ "${OQS_PROVIDER_TESTSCRIPTS}/oqs-openssl-certgen.sh" "$1" && "${OQS_PROVIDER_TESTSCRIPTS}/oqs-openssl-cmssign.sh" "$1" && "${OQS_PROVIDER_TESTSCRIPTS}/oqsprovider-certverify.sh" "$1" && "${OQS_PROVIDER_TESTSCRIPTS}/oqsprovider-cmsverify.sh" "$1"
+}
+
+localalgtest() {
+ if ! ( "${OQS_PROVIDER_TESTSCRIPTS}/oqsprovider-certgen.sh" "$1" >> interop.log 2>&1 && "${OQS_PROVIDER_TESTSCRIPTS}/oqsprovider-certverify.sh" "$1" >> interop.log 2>&1 && "${OQS_PROVIDER_TESTSCRIPTS}/oqsprovider-cmssign.sh" "$1" >> interop.log 2>&1 && "${OQS_PROVIDER_TESTSCRIPTS}/oqsprovider-ca.sh" "$1" >> interop.log 2>&1 ); then
+ echo "localalgtest $1 failed. Exiting.".
+ cat interop.log
+ exit 1
+ fi
+}
+
+interop() {
+ echo ".\c"
+ # check if we want to run this algorithm:
+ if [ -n "${OQS_SKIP_TESTS}" ]; then
+ GREPTEST=$(echo "${OQS_SKIP_TESTS}" | sed "s/\,/\\\|/g")
+ if echo "$1" | grep -q "${GREPTEST}"; then
+ echo "Not testing $1" >> interop.log
+ return
+ fi
+ fi
+
+ # Check whether algorithm is supported at all:
+ retcode=0
+ "${OPENSSL_APP}" list -signature-algorithms | grep -q "$1" || retcode=$?
+ if [ "${retcode}" -ne 1 ]; then
+ if [ -z "${LOCALTESTONLY}" ]; then
+ provider2openssl "$1" >> interop.log 2>&1 && openssl2provider "$1" >> interop.log 2>&1
+ else
+ localalgtest "$1"
+ fi
+ else
+ echo "Algorithm $1 not enabled. Exit testing."
+ exit 1
+ fi
+
+ if [ "${retcode}" -ne 0 ]; then
+ echo "Test for $1 failed. Terminating testing."
+ cat interop.log
+ exit 1
+ fi
+}
+
+if [ -z "${OQS_PROVIDER_TESTSCRIPTS}" ]; then
+ export OQS_PROVIDER_TESTSCRIPTS="$(pwd)/scripts"
+fi
+
+if [ -n "${OPENSSL_INSTALL}" ]; then
+ # trying to set config variables suitably for pre-existing OpenSSL installation
+ if [ -f "${OPENSSL_INSTALL}/bin/openssl" ]; then
+ export OPENSSL_APP="${OPENSSL_INSTALL}/bin/openssl"
+ fi
+ if [ -z "${LD_LIBRARY_PATH}" ]; then
+ if [ -d "${OPENSSL_INSTALL}/lib64" ]; then
+ export LD_LIBRARY_PATH="${OPENSSL_INSTALL}/lib64"
+ elif [ -d "${OPENSSL_INSTALL}/lib" ]; then
+ export LD_LIBRARY_PATH="${OPENSSL_INSTALL}/lib"
+ fi
+ fi
+ if [ -f "${OPENSSL_INSTALL}/ssl/openssl.cnf" ]; then
+ export OPENSSL_CONF="${OPENSSL_INSTALL}/ssl/openssl.cnf"
+ fi
+fi
+
+if [ -z "${OPENSSL_CONF}" ]; then
+ export OPENSSL_CONF="$(pwd)/scripts/openssl-ca.cnf"
+fi
+
+if [ -z "${OPENSSL_APP}" ]; then
+ if [ -f "$(pwd)/openssl/apps/openssl" ]; then
+ export OPENSSL_APP="$(pwd)/openssl/apps/openssl"
+ else # if no local openssl src directory is found, rely on PATH...
+ export OPENSSL_APP=openssl
+ fi
+fi
+
+if [ -z "${OPENSSL_MODULES}" ]; then
+ export OPENSSL_MODULES="$(pwd)/_build/lib"
+fi
+
+if [ -z "${LD_LIBRARY_PATH}" ]; then
+ if [ -d "$(pwd)/.local/lib64" ]; then
+ export LD_LIBRARY_PATH="$(pwd)/.local/lib64"
+ else
+ if [ -d "$(pwd)/.local/lib" ]; then
+ export LD_LIBRARY_PATH="$(pwd)/.local/lib"
+ fi
+ fi
+fi
+
+if [ -n "${OQS_SKIP_TESTS}" ]; then
+ echo "Skipping algs ${OQS_SKIP_TESTS}"
+fi
+
+# Set OSX DYLD_LIBRARY_PATH if not already externally set
+if [ -z "${DYLD_LIBRARY_PATH}" ]; then
+ export DYLD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
+fi
+
+echo "Test setup:"
+echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"
+echo "OPENSSL_APP=${OPENSSL_APP}"
+echo "OPENSSL_CONF=${OPENSSL_CONF}"
+echo "OPENSSL_MODULES=${OPENSSL_MODULES}"
+if uname -s | grep -q "^Darwin"; then
+echo "DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}"
+fi
+
+# check if we can use docker or not:
+if ! docker info 2>&1 | grep -q Server; then
+ echo "No OQS-OpenSSL111 interop test because of absence of docker"
+ export LOCALTESTONLY="Yes"
+fi
+
+# by default, do not run interop tests as per
+# https://github.com/open-quantum-safe/oqs-provider/issues/32
+# comment the following line if they should be run; be sure to
+# have alignment in algorithms supported in that case
+export LOCALTESTONLY="Yes"
+
+echo "Version information:"
+"${OPENSSL_APP}" version
+
+# Disable testing for version 3.0.1: Buggy as hell:
+if "${OPENSSL_APP}" version | grep -q "OpenSSL 3.0.1"; then
+ echo "Skipping testing of buggy OpenSSL 3.0.1"
+ exit 0
+fi
+
+if ! "${OPENSSL_APP}" list -providers -verbose; then
+ echo "Baseline openssl invocation failed. Exiting test."
+ exit 1
+fi
+
+# Ensure "oqsprovider" is registered:
+if ! "${OPENSSL_APP}" list -providers -verbose | grep -q oqsprovider; then
+ echo "oqsprovider not registered. Exit test."
+ exit 1
+fi
+
+# Run interop-tests:
+# cleanup log from previous runs:
+rm -f interop.log
+
+echo "Cert gen/verify, CMS sign/verify, CA tests for all enabled OQS signature algorithms commencing: "
+
+# auto-detect all available signature algorithms:
+for alg in $("${OPENSSL_APP}" list -signature-algorithms | grep oqsprovider | sed -e "s/ @ .*//g" | sed -e "s/^ //g")
+do
+ if [ "$1" = "-V" ]; then
+ echo "Testing $alg"
+ fi
+ interop "${alg}"
+ certsgenerated=1
+done
+
+if [ -z "${certsgenerated}" ]; then
+ echo "No OQS signature algorithms found in provider 'oqsprovider'. No certs generated. Exiting."
+ exit 1
+else
+ if [ "$1" = "-V" ]; then
+ echo "Certificates successfully generated in $(pwd)/tmp"
+ fi
+fi
+
+echo
+
+# Run built-in tests:
+# Without removing OPENSSL_CONF ctest hangs... ???
+unset OPENSSL_CONF
+rv=0
+if ! ( cd _build && ctest $@ ); then
+ rv=1
+fi
+
+# cleanup: TBC:
+# decide for testing strategy when integrating to OpenSSL test harness:
+# Keep scripts generating certs (testing more code paths) or use API?
+#rm -rf tmp
+echo
+
+if [ "${rv}" -ne 0 ]; then
+ echo "Tests failed."
+else
+ echo "All oqsprovider tests passed."
+fi
+exit "${rv}"
+
--- /dev/null
+#/bin/bash
+
+OQS_ENCODING_DILITHIUM2=draft-uni-qsckeys-dilithium-00/sk-pk \
+OQS_ENCODING_DILITHIUM3=draft-uni-qsckeys-dilithium-00/sk-pk \
+OQS_ENCODING_DILITHIUM5=draft-uni-qsckeys-dilithium-00/sk-pk \
+OQS_ENCODING_DILITHIUM2_AES=draft-uni-qsckeys-dilithium-00/sk-pk \
+OQS_ENCODING_DILITHIUM3_AES=draft-uni-qsckeys-dilithium-00/sk-pk \
+OQS_ENCODING_DILITHIUM5_AES=draft-uni-qsckeys-dilithium-00/sk-pk \
+OQS_ENCODING_FALCON512=draft-uni-qsckeys-falcon-00/sk-pk \
+OQS_ENCODING_FALCON1024=draft-uni-qsckeys-falcon-00/sk-pk \
+OQS_ENCODING_SPHINCSHARAKA128FROBUST=draft-uni-qsckeys-sphincsplus-00/sk-pk \
+OQS_ENCODING_SPHINCSHARAKA128FSIMPLE=draft-uni-qsckeys-sphincsplus-00/sk-pk \
+OQS_ENCODING_SPHINCSSHA256128FROBUST=draft-uni-qsckeys-sphincsplus-00/sk-pk \
+OQS_ENCODING_SPHINCSSHA256128SSIMPLE=draft-uni-qsckeys-sphincsplus-00/sk-pk \
+OQS_ENCODING_SPHINCSSHAKE256128FSIMPLE=draft-uni-qsckeys-sphincsplus-00/sk-pk \
+OQS_ENCODING_DILITHIUM2_ALGNAME=Dilithium2 \
+OQS_ENCODING_DILITHIUM3_ALGNAME=Dilithium3 \
+OQS_ENCODING_DILITHIUM5_ALGNAME=Dilithium5 \
+OQS_ENCODING_DILITHIUM2_AES_ALGNAME=Dilithium2_AES \
+OQS_ENCODING_DILITHIUM3_AES_ALGNAME=Dilithium3_AES \
+OQS_ENCODING_DILITHIUM5_AES_ALGNAME=Dilithium5_AES \
+OQS_ENCODING_FALCON512_ALGNAME=Falcon512 \
+OQS_ENCODING_FALCON1024_ALGNAME=Falcon1024 \
+OQS_ENCODING_SPHINCSHARAKA128FROBUST_ALGNAME=sphincs-haraka-128f-robust \
+OQS_ENCODING_SPHINCSHARAKA128FSIMPLE_ALGNAME=sphincs-haraka-128f-simple \
+OQS_ENCODING_SPHINCSSHA256128FROBUST_ALGNAME=sphincs-sha256-128f-robust \
+OQS_ENCODING_SPHINCSSHA256128SSIMPLE_ALGNAME=sphincs-sha256-128s-simple \
+OQS_ENCODING_SPHINCSSHAKE256128FSIMPLE_ALGNAME=sphincs-shake256-128f-simple \
+scripts/runtests.sh $@
\ No newline at end of file
--- /dev/null
+include(GNUInstallDirs)
+set(OQS_PROV_BINARY_DIR ${CMAKE_BINARY_DIR}/lib)
+
+add_test(
+ NAME oqs_signatures
+ COMMAND oqs_test_signatures
+ "oqsprovider"
+ "${CMAKE_SOURCE_DIR}/test/oqs.cnf"
+)
+# openssl under MSVC seems to have a bug registering NIDs:
+# It only works when setting OPENSSL_CONF, not when loading the same cnf file:
+if (MSVC)
+set_tests_properties(oqs_signatures
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR};OPENSSL_CONF=${CMAKE_CURRENT_SOURCE_DIR}/openssl-ca.cnf"
+)
+else()
+set_tests_properties(oqs_signatures
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR}"
+)
+endif()
+
+add_executable(oqs_test_signatures oqs_test_signatures.c test_common.c)
+target_link_libraries(oqs_test_signatures PRIVATE ${OPENSSL_CRYPTO_LIBRARY} ${OQS_ADDL_SOCKET_LIBS})
+
+add_test(
+ NAME oqs_kems
+ COMMAND oqs_test_kems
+ "oqsprovider"
+ "${CMAKE_SOURCE_DIR}/test/oqs.cnf"
+)
+# openssl under MSVC seems to have a bug registering NIDs:
+# It only works when setting OPENSSL_CONF, not when loading the same cnf file:
+if (MSVC)
+set_tests_properties(oqs_kems
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR};OPENSSL_CONF=${CMAKE_CURRENT_SOURCE_DIR}/openssl-ca.cnf"
+)
+else()
+set_tests_properties(oqs_kems
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR}"
+)
+endif()
+
+add_executable(oqs_test_kems oqs_test_kems.c test_common.c)
+target_link_libraries(oqs_test_kems PRIVATE ${OPENSSL_CRYPTO_LIBRARY} ${OQS_ADDL_SOCKET_LIBS})
+
+add_test(
+ NAME oqs_groups
+ COMMAND oqs_test_groups
+ "oqsprovider"
+ "${CMAKE_CURRENT_SOURCE_DIR}/oqs.cnf"
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+)
+# openssl under MSVC seems to have a bug registering NIDs:
+# It only works when setting OPENSSL_CONF, not when loading the same cnf file:
+if (MSVC)
+set_tests_properties(oqs_groups
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR};OPENSSL_CONF=${CMAKE_CURRENT_SOURCE_DIR}/openssl-ca.cnf"
+)
+else()
+set_tests_properties(oqs_groups
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR}"
+)
+endif()
+add_executable(oqs_test_groups oqs_test_groups.c test_common.c tlstest_helpers.c)
+target_link_libraries(oqs_test_groups PRIVATE ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} ${OQS_ADDL_SOCKET_LIBS})
+
+add_test(
+ NAME oqs_tlssig
+ COMMAND oqs_test_tlssig
+ "oqsprovider"
+ "${CMAKE_CURRENT_SOURCE_DIR}/openssl-ca.cnf"
+ "${CMAKE_CURRENT_BINARY_DIR}/tmp"
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+)
+# openssl under MSVC seems to have a bug registering NIDs:
+# It only works when setting OPENSSL_CONF, not when loading the same cnf file:
+if (MSVC)
+set_tests_properties(oqs_tlssig
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR};OPENSSL_CONF=${CMAKE_CURRENT_SOURCE_DIR}/openssl-ca.cnf"
+)
+else()
+set_tests_properties(oqs_tlssig
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR}"
+)
+endif()
+add_executable(oqs_test_tlssig oqs_test_tlssig.c test_common.c tlstest_helpers.c)
+target_link_libraries(oqs_test_tlssig PRIVATE ${OPENSSL_SSL_LIBRARY} ${OPENSSL_CRYPTO_LIBRARY} ${OQS_ADDL_SOCKET_LIBS})
+
+add_executable(oqs_test_endecode oqs_test_endecode.c test_common.c)
+target_link_libraries(oqs_test_endecode PRIVATE ${OPENSSL_CRYPTO_LIBRARY} ${OQS_ADDL_SOCKET_LIBS})
+add_test(
+ NAME oqs_endecode
+ COMMAND oqs_test_endecode
+ "oqsprovider"
+ "${CMAKE_CURRENT_SOURCE_DIR}/openssl-ca.cnf"
+)
+# openssl under MSVC seems to have a bug registering NIDs:
+# It only works when setting OPENSSL_CONF, not when loading the same cnf file:
+if (MSVC)
+set_tests_properties(oqs_endecode
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR};OPENSSL_CONF=${CMAKE_CURRENT_SOURCE_DIR}/openssl-ca.cnf"
+)
+else()
+set_tests_properties(oqs_endecode
+ PROPERTIES ENVIRONMENT "OPENSSL_MODULES=${OQS_PROV_BINARY_DIR}"
+)
+endif()
+
+if (OQS_PROVIDER_BUILD_STATIC)
+ targets_set_static_provider(oqs_test_signatures
+ oqs_test_kems
+ oqs_test_groups
+ oqs_test_tlssig
+ oqs_test_endecode
+ )
+endif()
--- /dev/null
+# oqs-provider testing
+
+The tests in this folder are running separately from the OpenSSL test framework, but some tests utilize some of its plumbing. Therefore the OpenSSL code base, incl. its "test" directory must be locally available for all tests to be executed. The script `../scripts/fullbuild.sh` ensures this if no explicit hint to an OpenSSL binary installation is given (via the environment variable "OPENSSL_INSTALL").
+
--- /dev/null
+#
+# OpenSSL example configuration file.
+# See doc/man5/config.pod for more info.
+#
+# This is mostly being used for generation of certificate requests,
+# but may be used for auto loading of providers
+
+# Note that you can include other files from the main configuration
+# file using the .include directive.
+#.include filename
+
+# This definition stops the following lines choking if HOME isn't
+# defined.
+HOME = .
+
+# Use this in order to automatically load providers.
+openssl_conf = openssl_init
+
+# Comment out the next line to ignore configuration errors
+config_diagnostics = 1
+
+# Extra OBJECT IDENTIFIER info:
+# oid_file = $ENV::HOME/.oid
+oid_section = new_oids
+
+# To use this configuration file with the "-extfile" option of the
+# "openssl x509" utility, name here the section containing the
+# X.509v3 extensions to use:
+# extensions =
+# (Alternatively, use a configuration file that has only
+# X.509v3 extensions in its main [= default] section.)
+
+[ new_oids ]
+# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.
+# Add a simple OID like this:
+# testoid1=1.2.3.4
+# Or use config file substitution like this:
+# testoid2=${testoid1}.5.6
+
+# Policies used by the TSA examples.
+tsa_policy1 = 1.2.3.4.1
+tsa_policy2 = 1.2.3.4.5.6
+tsa_policy3 = 1.2.3.4.5.7
+
+# For FIPS
+# Optionally include a file that is generated by the OpenSSL fipsinstall
+# application. This file contains configuration data required by the OpenSSL
+# fips provider. It contains a named section e.g. [fips_sect] which is
+# referenced from the [provider_sect] below.
+# Refer to the OpenSSL security policy for more information.
+# .include fipsmodule.cnf
+
+[openssl_init]
+providers = provider_sect
+
+# List of providers to load
+[provider_sect]
+default = default_sect
+oqsprovider = oqsprovider_sect
+oqsprovider2 = oqsprovider2_sect
+
+# The fips section name should match the section name inside the
+# included fipsmodule.cnf.
+# fips = fips_sect
+
+# If no providers are activated explicitly, the default one is activated implicitly.
+# See man 7 OSSL_PROVIDER-default for more details.
+#
+# If you add a section explicitly activating any other provider(s), you most
+# probably need to explicitly activate the default provider, otherwise it
+# becomes unavailable in openssl. As a consequence applications depending on
+# OpenSSL may not work correctly which could lead to significant system
+# problems including inability to remotely access the system.
+[default_sect]
+activate = 1
+
+[oqsprovider_sect]
+activate = 1
+# This second provider instance can be activated (for testing) for example
+# by creating a softlink with suitable name "oqsprovider2" to the originally
+# created oqsprovider.{so|dylib|dll}
+[oqsprovider2_sect]
+activate = 1
+
+# activate = 1
+
+
+####################################################################
+[ ca ]
+default_ca = CA_default # The default ca section
+
+####################################################################
+[ CA_default ]
+
+dir = ./demoCA # Where everything is kept
+certs = $dir/certs # Where the issued certs are kept
+crl_dir = $dir/crl # Where the issued crl are kept
+database = $dir/index.txt # database index file.
+#unique_subject = no # Set to 'no' to allow creation of
+ # several certs with same subject.
+new_certs_dir = $dir/newcerts # default place for new certs.
+
+certificate = $dir/cacert.pem # The CA certificate
+serial = $dir/serial # The current serial number
+rand_serial = no
+crlnumber = $dir/crlnumber # the current crl number
+ # must be commented out to leave a V1 CRL
+crl = $dir/crl.pem # The current CRL
+private_key = $dir/private/cakey.pem # The private key
+
+x509_extensions = usr_cert # The extensions to add to the cert
+
+# Comment out the following two lines for the "traditional"
+# (and highly broken) format.
+name_opt = ca_default # Subject Name options
+cert_opt = ca_default # Certificate field options
+
+# Extension copying option: use with caution.
+# copy_extensions = copy
+
+# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs
+# so this is commented out by default to leave a V1 CRL.
+# crlnumber must also be commented out to leave a V1 CRL.
+# crl_extensions = crl_ext
+
+default_days = 365 # how long to certify for
+default_crl_days= 30 # how long before next CRL
+default_md = sha256 # use public key default MD
+preserve = no # keep passed DN ordering
+email_in_dn = no
+# A few difference way of specifying how similar the request should look
+# For type CA, the listed attributes must be the same, and the optional
+# and supplied fields are just that :-)
+policy = policy_match
+
+# For the CA policy
+[ policy_match ]
+countryName = match
+stateOrProvinceName = match
+organizationName = match
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+# For the 'anything' policy
+# At this point in time, you must list all acceptable 'object'
+# types.
+[ policy_anything ]
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = supplied
+emailAddress = optional
+
+####################################################################
+[ req ]
+default_bits = 2048
+default_keyfile = privkey.pem
+distinguished_name = req_distinguished_name
+attributes = req_attributes
+x509_extensions = v3_ca # The extensions to add to the self signed cert
+
+# Passwords for private keys if not present they will be prompted for
+# input_password = secret
+# output_password = secret
+
+# This sets a mask for permitted string types. There are several options.
+# default: PrintableString, T61String, BMPString.
+# pkix : PrintableString, BMPString (PKIX recommendation before 2004)
+# utf8only: only UTF8Strings (PKIX recommendation after 2004).
+# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).
+# MASK:XXXX a literal mask value.
+# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.
+string_mask = utf8only
+
+# req_extensions = v3_req # The extensions to add to a certificate request
+
+[ req_distinguished_name ]
+countryName = Country Name (2 letter code)
+countryName_default = AU
+countryName_min = 2
+countryName_max = 2
+
+stateOrProvinceName = State or Province Name (full name)
+stateOrProvinceName_default = Some-State
+
+localityName = Locality Name (eg, city)
+
+0.organizationName = Organization Name (eg, company)
+0.organizationName_default = Internet Widgits Pty Ltd
+
+# we can do this but it is not needed normally :-)
+#1.organizationName = Second Organization Name (eg, company)
+#1.organizationName_default = World Wide Web Pty Ltd
+
+organizationalUnitName = Organizational Unit Name (eg, section)
+#organizationalUnitName_default =
+
+commonName = Common Name (e.g. server FQDN or YOUR name)
+commonName_max = 64
+
+emailAddress = Email Address
+emailAddress_max = 64
+
+# SET-ex3 = SET extension number 3
+
+[ req_attributes ]
+challengePassword = A challenge password
+challengePassword_min = 4
+challengePassword_max = 20
+
+unstructuredName = An optional company name
+
+[ usr_cert ]
+
+# These extensions are added when 'ca' signs a request.
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+# This is required for TSA certificates.
+# extendedKeyUsage = critical,timeStamping
+
+[ v3_req ]
+
+# Extensions to add to a certificate request
+
+basicConstraints = CA:FALSE
+keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+[ v3_ca ]
+
+
+# Extensions for a typical CA
+
+
+# PKIX recommendation.
+
+subjectKeyIdentifier=hash
+
+authorityKeyIdentifier=keyid:always,issuer
+
+basicConstraints = critical,CA:true
+
+# Key usage: this is typical for a CA certificate. However since it will
+# prevent it being used as an test self-signed certificate it is best
+# left out by default.
+# keyUsage = cRLSign, keyCertSign
+
+# Include email address in subject alt name: another PKIX recommendation
+# subjectAltName=email:copy
+# Copy issuer details
+# issuerAltName=issuer:copy
+
+# DER hex encoding of an extension: beware experts only!
+# obj=DER:02:03
+# Where 'obj' is a standard or added object
+# You can even override a supported extension:
+# basicConstraints= critical, DER:30:03:01:01:FF
+
+[ crl_ext ]
+
+# CRL extensions.
+# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.
+
+# issuerAltName=issuer:copy
+authorityKeyIdentifier=keyid:always
+
+[ proxy_cert_ext ]
+# These extensions should be added when creating a proxy certificate
+
+# This goes against PKIX guidelines but some CAs do it and some software
+# requires this to avoid interpreting an end user certificate as a CA.
+
+basicConstraints=CA:FALSE
+
+# This is typical in keyUsage for a client certificate.
+# keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+
+# PKIX recommendations harmless if included in all certificates.
+subjectKeyIdentifier=hash
+authorityKeyIdentifier=keyid,issuer
+
+# This stuff is for subjectAltName and issuerAltname.
+# Import the email address.
+# subjectAltName=email:copy
+# An alternative to produce certificates that aren't
+# deprecated according to PKIX.
+# subjectAltName=email:move
+
+# Copy subject details
+# issuerAltName=issuer:copy
+
+# This really needs to be in place for it to be a proxy certificate.
+proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
+
+####################################################################
+[ tsa ]
+
+default_tsa = tsa_config1 # the default TSA section
+
+[ tsa_config1 ]
+
+# These are used by the TSA reply generation only.
+dir = ./demoCA # TSA root directory
+serial = $dir/tsaserial # The current serial number (mandatory)
+crypto_device = builtin # OpenSSL engine to use for signing
+signer_cert = $dir/tsacert.pem # The TSA signing certificate
+ # (optional)
+certs = $dir/cacert.pem # Certificate chain to include in reply
+ # (optional)
+signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
+signer_digest = sha256 # Signing digest to use. (Optional)
+default_policy = tsa_policy1 # Policy if request did not specify it
+ # (optional)
+other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
+digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory)
+accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
+clock_precision_digits = 0 # number of digits after dot. (optional)
+ordering = yes # Is ordering defined for timestamps?
+ # (optional, default: no)
+tsa_name = yes # Must the TSA name be included in the reply?
+ # (optional, default: no)
+ess_cert_id_chain = no # Must the ESS cert id chain be included?
+ # (optional, default: no)
+ess_cert_id_alg = sha1 # algorithm to compute certificate
+ # identifier (optional, default: sha1)
+
+[insta] # CMP using Insta Demo CA
+# Message transfer
+server = pki.certificate.fi:8700
+# proxy = # set this as far as needed, e.g., http://192.168.1.1:8080
+# tls_use = 0
+path = pkix/
+
+# Server authentication
+recipient = "/C=FI/O=Insta Demo/CN=Insta Demo CA" # or set srvcert or issuer
+ignore_keyusage = 1 # potentially needed quirk
+unprotected_errors = 1 # potentially needed quirk
+extracertsout = insta.extracerts.pem
+
+# Client authentication
+ref = 3078 # user identification
+secret = pass:insta # can be used for both client and server side
+
+# Generic message options
+cmd = ir # default operation, can be overridden on cmd line with, e.g., kur
+
+# Certificate enrollment
+subject = "/CN=openssl-cmp-test"
+newkey = insta.priv.pem
+out_trusted = insta.ca.crt
+certout = insta.cert.pem
+
+[pbm] # Password-based protection for Insta CA
+# Server and client authentication
+ref = $insta::ref # 3078
+secret = $insta::secret # pass:insta
+
+[signature] # Signature-based protection for Insta CA
+# Server authentication
+trusted = insta.ca.crt # does not include keyUsage digitalSignature
+
+# Client authentication
+secret = # disable PBM
+key = $insta::newkey # insta.priv.pem
+cert = $insta::certout # insta.cert.pem
+
+[ir]
+cmd = ir
+
+[cr]
+cmd = cr
+
+[kur]
+# Certificate update
+cmd = kur
+oldcert = $insta::certout # insta.cert.pem
+
+[rr]
+# Certificate revocation
+cmd = rr
+oldcert = $insta::certout # insta.cert.pem
+
+[pkcs12]
+certBagAttr = cb_attr
+
+# Uncomment this if you need Java compatible PKCS12 files
+[cb_attr]
+#jdkTrustedKeyUsage = anyExtendedKeyUsage
--- /dev/null
+openssl_conf = openssl_init
+
+[openssl_init]
+providers = provider_sect
+
+[provider_sect]
+oqsprovider = oqsprovider_sect
+default = default_sect
+# fips = fips_sect
+
+[default_sect]
+activate = 1
+
+#[fips_sect]
+#activate = 1
+
+[oqsprovider_sect]
+activate = 1
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+#include <openssl/provider.h>
+#include <openssl/encoder.h>
+#include <openssl/decoder.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+#include <openssl/buffer.h>
+#include <string.h>
+#include "test_common.h"
+#include <openssl/core_names.h>
+#include <openssl/trace.h>
+#include "oqs/oqs.h"
+
+static OSSL_LIB_CTX *libctx = NULL;
+static char *modulename = NULL;
+static char *configfile = NULL;
+static char *testpropq = NULL;
+static OSSL_LIB_CTX *keyctx = NULL;
+static OSSL_LIB_CTX *testctx = NULL;
+
+static OSSL_PROVIDER *dfltprov = NULL;
+static OSSL_PROVIDER *keyprov = NULL;
+
+#define nelem(a) (sizeof(a)/sizeof((a)[0]))
+
+typedef struct endecode_params_st {
+ char *format;
+ char *structure;
+ char *keytype;
+ char *pass;
+ int selection;
+
+} ENDECODE_PARAMS;
+
+static ENDECODE_PARAMS test_params_list[] = {
+ {"PEM", "PrivateKeyInfo", NULL, NULL,
+ OSSL_KEYMGMT_SELECT_KEYPAIR |
+ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS},
+ {"PEM", "EncryptedPrivateKeyInfo", NULL, "Pass the holy handgrenade of antioch", OSSL_KEYMGMT_SELECT_KEYPAIR |
+ OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS},
+ {"PEM", "SubjectPublicKeyInfo", NULL, NULL, OSSL_KEYMGMT_SELECT_PUBLIC_KEY |
+ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS},
+ {"DER", "PrivateKeyInfo", NULL, NULL, OSSL_KEYMGMT_SELECT_KEYPAIR |
+ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS},
+ {"DER", "EncryptedPrivateKeyInfo", NULL, "Pass the holy handgrenade of antioch", OSSL_KEYMGMT_SELECT_KEYPAIR |
+ OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS},
+ {"DER", "SubjectPublicKeyInfo", NULL, NULL, OSSL_KEYMGMT_SELECT_PUBLIC_KEY |
+ OSSL_KEYMGMT_SELECT_ALL_PARAMETERS},
+};
+
+static EVP_PKEY *oqstest_make_key(const char *type, EVP_PKEY *template,
+ OSSL_PARAM *genparams) {
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+
+ if (!alg_is_enabled(type)) {
+ printf("Not generating key for disabled algorithm %s.\n", type);
+ return NULL;
+ }
+
+ ctx = (template != NULL)
+ ? EVP_PKEY_CTX_new_from_pkey(keyctx, template, testpropq)
+ : EVP_PKEY_CTX_new_from_name(keyctx, type, testpropq);
+
+ /*
+ * No real need to check the errors other than for the cascade
+ * effect. |pkey| will simply remain NULL if something goes wrong.
+ */
+ (void) (ctx != NULL
+ && EVP_PKEY_keygen_init(ctx) > 0
+ && (genparams == NULL
+ || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
+ && EVP_PKEY_keygen(ctx, &pkey) > 0);
+ EVP_PKEY_CTX_free(ctx);
+ return pkey;
+}
+
+static int encode_EVP_PKEY_prov(const EVP_PKEY *pkey, const char *format, const char *structure, const char *pass,
+ const int selection, void **encoded, long *encoded_len) {
+ OSSL_ENCODER_CTX *ectx;
+ BIO *mem_ser = NULL;
+ BUF_MEM *mem_buf = NULL;
+ const char *cipher = "AES-256-CBC";
+ int ok = 0;
+
+ ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey,
+ selection,
+ format, structure,
+ NULL);
+ if (ectx == NULL) {
+ printf("No suitable encoder found\n");
+ goto end;
+ }
+
+ if (pass != NULL) {
+ OSSL_ENCODER_CTX_set_passphrase(ectx, (const unsigned char *) pass, strlen(pass));
+ OSSL_ENCODER_CTX_set_cipher(ectx, cipher, NULL);
+ }
+ mem_ser = BIO_new(BIO_s_mem());
+ if (!OSSL_ENCODER_to_bio(ectx, mem_ser)) {
+ /* encoding failure */
+ goto end;
+ }
+
+ BIO_get_mem_ptr(mem_ser, &mem_buf);
+ if (mem_buf == NULL || mem_buf->length == 0)
+ goto end;
+
+ /* pkey was successfully encoded into the bio */
+ *encoded = mem_buf->data;
+ *encoded_len = mem_buf->length;
+
+ /* Detach the encoded output */
+ mem_buf->data = NULL;
+ mem_buf->length = 0;
+ ok = 1;
+
+ end:
+ BIO_free(mem_ser);
+ OSSL_ENCODER_CTX_free(ectx);
+ return ok;
+}
+
+static int decode_EVP_PKEY_prov(const char *input_type, const char *structure, const char *pass,
+ const char *keytype, const int selection, EVP_PKEY **object,
+ const void *encoded, const long encoded_len) {
+ EVP_PKEY *pkey = NULL;
+ OSSL_DECODER_CTX *dctx = NULL;
+ BIO *encoded_bio = NULL;
+
+ int ok = 0;
+
+ encoded_bio = BIO_new_mem_buf(encoded, encoded_len);
+ if (encoded_bio == NULL)
+ goto end;
+
+ dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey,
+ input_type, structure,
+ keytype, selection,
+ keyctx, NULL);
+ if (dctx == NULL)
+ goto end;
+
+ if (pass != NULL)
+ OSSL_DECODER_CTX_set_passphrase(dctx, (const unsigned char *) pass, strlen(pass));
+
+ if (!OSSL_DECODER_from_bio(dctx, encoded_bio))
+ goto end;
+
+ OSSL_DECODER_CTX_free(dctx);
+ dctx = NULL;
+
+ ok = 1;
+ *object = pkey;
+ pkey = NULL;
+
+ end:
+ EVP_PKEY_free(pkey);
+ BIO_free(encoded_bio);
+ OSSL_DECODER_CTX_free(dctx);
+ return ok;
+}
+
+static int test_oqs_encdec(const char *sigalg_name) {
+ EVP_PKEY *pkey = NULL;
+ EVP_PKEY *decoded_pkey = NULL;
+ void *encoded = NULL;
+ long encoded_len = 0;
+ size_t i;
+ int ok = 0;
+
+ for (i = 0; i < nelem(test_params_list); i++) {
+
+ pkey = oqstest_make_key(sigalg_name, NULL, NULL);
+ if (pkey == NULL)
+ goto end;
+
+
+ if (!encode_EVP_PKEY_prov(pkey, test_params_list[i].format, test_params_list[i].structure,
+ test_params_list[i].pass, test_params_list[i].selection,
+ &encoded, &encoded_len)) {
+ printf("Failed encoding %s", sigalg_name);
+ goto end;
+ }
+ if (!decode_EVP_PKEY_prov(test_params_list[i].format, test_params_list[i].structure,
+ test_params_list[i].pass, test_params_list[i].keytype,
+ test_params_list[i].selection,
+ &decoded_pkey, encoded, encoded_len)) {
+ printf("Failed decoding %s", sigalg_name);
+ goto end;
+ }
+
+ if (EVP_PKEY_eq(pkey, decoded_pkey) != 1)
+ goto end;
+ }
+ ok = 1;
+ end:
+ EVP_PKEY_free(pkey);
+ EVP_PKEY_free(decoded_pkey);
+ return ok;
+}
+
+int main(int argc, char *argv[]) {
+ size_t i;
+ int errcnt = 0, test = 0, query_nocache;
+ OSSL_PROVIDER *oqsprov = NULL;
+ const OSSL_ALGORITHM *sigalgs;
+
+ T((libctx = OSSL_LIB_CTX_new()) != NULL);
+ T(argc == 3);
+ modulename = argv[1];
+ configfile = argv[2];
+
+ load_oqs_provider(libctx, modulename, configfile);
+
+ keyctx = OSSL_LIB_CTX_new();
+
+ load_oqs_provider(keyctx, modulename, configfile);
+
+ dfltprov = OSSL_PROVIDER_load(keyctx, "default");
+ keyprov = OSSL_PROVIDER_load(keyctx, modulename);
+ oqsprov = OSSL_PROVIDER_load(libctx, modulename);
+
+ sigalgs = OSSL_PROVIDER_query_operation(oqsprov, OSSL_OP_SIGNATURE, &query_nocache);
+
+ if (sigalgs) {
+ for (; sigalgs->algorithm_names != NULL; sigalgs++) {
+ if (test_oqs_encdec(sigalgs->algorithm_names)) {
+ fprintf(stderr,
+ cGREEN " Encoding/Decoding test succeeded: %s" cNORM "\n",
+ sigalgs->algorithm_names);
+ } else {
+ fprintf(stderr,
+ cRED " Encoding/Decoding test failed: %s" cNORM "\n",
+ sigalgs->algorithm_names);
+ ERR_print_errors_fp(stderr);
+ errcnt++;
+ }
+ }
+ }
+ else {
+ fprintf(stderr,
+ cRED " No signature algorithms found" cNORM "\n");
+ ERR_print_errors_fp(stderr);
+ errcnt++;
+ }
+
+ OSSL_LIB_CTX_free(libctx);
+ OSSL_PROVIDER_unload(dfltprov);
+ OSSL_PROVIDER_unload(keyprov);
+ if (OPENSSL_VERSION_PREREQ(3,1))
+ OSSL_PROVIDER_unload(oqsprov); // avoid crash in 3.0.x
+ OSSL_LIB_CTX_free(keyctx);
+
+ TEST_ASSERT(errcnt == 0)
+ return !test;
+}
+
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+#include <openssl/provider.h>
+#include <openssl/ssl.h>
+#include <string.h>
+#include "tlstest_helpers.h"
+#include "test_common.h"
+#include <openssl/core_names.h>
+
+static OSSL_LIB_CTX *libctx = NULL;
+static char *modulename = NULL;
+static char *configfile = NULL;
+static char *cert = NULL;
+static char *privkey = NULL;
+static char *certsdir = NULL;
+
+char *test_mk_file_path(const char *dir, const char *file)
+{
+# ifndef OPENSSL_SYS_VMS
+ const char *sep = "/";
+# else
+ const char *sep = "";
+# endif
+ size_t len = strlen(dir) + strlen(sep) + strlen(file) + 1;
+ char *full_file = OPENSSL_zalloc(len);
+
+ if (full_file != NULL) {
+ OPENSSL_strlcpy(full_file, dir, len);
+ OPENSSL_strlcat(full_file, sep, len);
+ OPENSSL_strlcat(full_file, file, len);
+ }
+
+ return full_file;
+}
+
+static int test_oqs_groups(const char *group_name)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int ret = 1, testresult = 0;
+
+ if (!alg_is_enabled(group_name)) {
+ printf("Not testing disabled algorithm %s.\n", group_name);
+ return 1;
+ }
+ testresult =
+ create_tls1_3_ctx_pair(libctx, &sctx, &cctx, cert, privkey);
+ if (!testresult) {
+ ret = -1; goto err;
+ }
+
+ testresult =
+ create_tls_objects(sctx, cctx, &serverssl, &clientssl);
+
+ if (!testresult) {
+ ret = -2; goto err;
+ }
+
+ testresult =
+ SSL_set1_groups_list(serverssl, group_name);
+ if (!testresult) {
+ ret = -3; goto err;
+ }
+
+ testresult =
+ SSL_set1_groups_list(clientssl, group_name);
+ if (!testresult) {
+ ret = -4; goto err;
+ }
+
+ testresult =
+ create_tls_connection(serverssl, clientssl, SSL_ERROR_NONE);
+ if (!testresult) {
+ ret = -5; goto err;
+ }
+
+ err:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+
+ return ret;
+}
+
+static int test_group(const OSSL_PARAM params[], void *data)
+{
+ int ret = 1;
+ int *errcnt = (int *) data;
+ const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_GROUP_NAME);
+ if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
+ ret = -1;
+ goto err;
+ }
+
+ char* group_name = OPENSSL_strdup(p->data);
+
+ ret = test_oqs_groups(group_name);
+
+ if (ret >= 0) {
+ fprintf(stderr,
+ cGREEN " TLS-KEM handshake test succeeded: %s" cNORM "\n",
+ group_name);
+ } else {
+ fprintf(stderr,
+ cRED " TLS-KEM handshake test failed: %s, return code: %d" cNORM "\n",
+ group_name, ret);
+ ERR_print_errors_fp(stderr);
+ (*errcnt)++;
+ }
+
+ err:
+ OPENSSL_free(group_name);
+ return ret;
+}
+
+static int test_provider_groups(OSSL_PROVIDER *provider, void *vctx)
+{
+ const char* provname = OSSL_PROVIDER_get0_name(provider);
+
+ if (!strcmp(provname, PROVIDER_NAME_OQS))
+ return OSSL_PROVIDER_get_capabilities(provider, "TLS-GROUP",
+ test_group, vctx);
+ else
+ return 1;
+}
+
+int main(int argc, char *argv[])
+{
+ size_t i;
+ int errcnt = 0, test = 0;
+
+ T((libctx = OSSL_LIB_CTX_new()) != NULL);
+ T(argc == 4);
+ modulename = argv[1];
+ configfile = argv[2];
+ certsdir = argv[3];
+
+ T(cert = test_mk_file_path(certsdir, "servercert.pem"));
+ T(privkey = test_mk_file_path(certsdir, "serverkey.pem"));
+
+ load_oqs_provider(libctx, modulename, configfile);
+
+ T(OSSL_PROVIDER_available(libctx, "default"));
+
+ T(OSSL_PROVIDER_do_all(libctx, test_provider_groups, &errcnt));
+
+ OPENSSL_free(cert);
+ OPENSSL_free(privkey);
+ OSSL_LIB_CTX_free(libctx);
+ TEST_ASSERT(errcnt == 0)
+ return !test;
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+#include <openssl/evp.h>
+#include <openssl/provider.h>
+#include "test_common.h"
+#include <string.h>
+#include "oqs/oqs.h"
+
+static OSSL_LIB_CTX *libctx = NULL;
+static char *modulename = NULL;
+static char *configfile = NULL;
+
+static int test_oqs_kems(const char *kemalg_name)
+{
+ EVP_MD_CTX *mdctx = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *key = NULL;
+ unsigned char *out, *secenc, *secdec;
+ size_t outlen, seclen;
+
+ int testresult = 1;
+
+ if (!alg_is_enabled(kemalg_name)) {
+ printf("Not testing disabled algorithm %s.\n", kemalg_name);
+ return 1;
+ }
+ // test with built-in digest only if default provider is active:
+ // TBD revisit when hybrids are activated: They always need default provider
+ if (OSSL_PROVIDER_available(libctx, "default")) {
+ testresult &=
+ (ctx = EVP_PKEY_CTX_new_from_name(libctx, kemalg_name, NULL)) != NULL
+ && EVP_PKEY_keygen_init(ctx)
+ && EVP_PKEY_generate(ctx, &key);
+
+ if (!testresult) goto err;
+ OPENSSL_free(ctx);
+ ctx = NULL;
+
+ testresult &=
+ (ctx = EVP_PKEY_CTX_new_from_pkey(libctx, key, NULL)) != NULL
+ && EVP_PKEY_encapsulate_init(ctx, NULL)
+ && EVP_PKEY_encapsulate(ctx, NULL, &outlen, NULL, &seclen)
+ && (out = OPENSSL_malloc(outlen)) != NULL
+ && (secenc = OPENSSL_malloc(seclen)) != NULL
+ && memset(secenc, 0x11, seclen) != NULL
+ && (secdec = OPENSSL_malloc(seclen)) != NULL
+ && memset(secdec, 0xff, seclen) != NULL
+ && EVP_PKEY_encapsulate(ctx, out, &outlen, secenc, &seclen)
+ && EVP_PKEY_decapsulate_init(ctx, NULL)
+ && EVP_PKEY_decapsulate(ctx, secdec, &seclen, out, outlen)
+ && memcmp(secenc, secdec, seclen) == 0;
+ if (!testresult) goto err;
+
+ out[0] = ~out[0];
+ out[outlen - 1] = ~out[outlen - 1];
+ testresult &=
+ memset(secdec, 0xff, seclen) != NULL
+ && EVP_PKEY_decapsulate_init(ctx, NULL)
+ && (EVP_PKEY_decapsulate(ctx, secdec, &seclen, out, outlen) || 1)
+ && memcmp(secenc, secdec, seclen) != 0;
+ }
+
+err:
+ EVP_PKEY_free(key);
+ OPENSSL_free(ctx);
+ return testresult;
+}
+
+#define nelem(a) (sizeof(a)/sizeof((a)[0]))
+
+int main(int argc, char *argv[])
+{
+ size_t i;
+ int errcnt = 0, test = 0, query_nocache;
+ OSSL_PROVIDER *oqsprov = NULL;
+ const OSSL_ALGORITHM *kemalgs;
+
+ T((libctx = OSSL_LIB_CTX_new()) != NULL);
+ T(argc == 3);
+ modulename = argv[1];
+ configfile = argv[2];
+
+ load_oqs_provider(libctx, modulename, configfile);
+
+ oqsprov = OSSL_PROVIDER_load(libctx, modulename);
+
+ kemalgs = OSSL_PROVIDER_query_operation(oqsprov, OSSL_OP_KEM, &query_nocache);
+ if (kemalgs) {
+ for (; kemalgs->algorithm_names != NULL; kemalgs++) {
+ if (test_oqs_kems(kemalgs->algorithm_names)) {
+ fprintf(stderr,
+ cGREEN " KEM test succeeded: %s" cNORM "\n",
+ kemalgs->algorithm_names);
+ } else {
+ fprintf(stderr,
+ cRED " KEM test failed: %s" cNORM "\n",
+ kemalgs->algorithm_names);
+ ERR_print_errors_fp(stderr);
+ errcnt++;
+ }
+ }
+ }
+
+ OSSL_LIB_CTX_free(libctx);
+
+ TEST_ASSERT(errcnt == 0)
+ return !test;
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+#include <openssl/evp.h>
+#include <openssl/provider.h>
+#include "test_common.h"
+#include "oqs/oqs.h"
+
+static OSSL_LIB_CTX *libctx = NULL;
+static char *modulename = NULL;
+static char *configfile = NULL;
+static char *cert = NULL;
+static char *privkey = NULL;
+static char *certsdir = NULL;
+static char *srpvfile = NULL;
+static char *tmpfilename = NULL;
+
+// sign-and-hash must work with and without providing a digest algorithm
+static int test_oqs_signatures(const char *sigalg_name)
+{
+ EVP_MD_CTX *mdctx = NULL;
+ EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *key = NULL;
+ const char msg[] = "The quick brown fox jumps over... you know what";
+ unsigned char *sig;
+ size_t siglen;
+
+ int testresult = 1;
+
+ if (!alg_is_enabled(sigalg_name)) {
+ printf("Not testing disabled algorithm %s.\n", sigalg_name);
+ return 1;
+ }
+ // test with built-in digest only if default provider is active:
+ // TBD revisit when hybrids are activated: They always need default provider
+ if (OSSL_PROVIDER_available(libctx, "default")) {
+ testresult &=
+ (ctx = EVP_PKEY_CTX_new_from_name(libctx, sigalg_name, NULL)) != NULL
+ && EVP_PKEY_keygen_init(ctx)
+ && EVP_PKEY_generate(ctx, &key)
+ && (mdctx = EVP_MD_CTX_new()) != NULL
+ && EVP_DigestSignInit_ex(mdctx, NULL, "SHA512", libctx, NULL, key, NULL)
+ && EVP_DigestSignUpdate(mdctx, msg, sizeof(msg))
+ && EVP_DigestSignFinal(mdctx, NULL, &siglen)
+ && (sig = OPENSSL_malloc(siglen)) != NULL
+ && EVP_DigestSignFinal(mdctx, sig, &siglen)
+ && EVP_DigestVerifyInit_ex(mdctx, NULL, "SHA512", libctx, NULL, key, NULL)
+ && EVP_DigestVerifyUpdate(mdctx, msg, sizeof(msg))
+ && EVP_DigestVerifyFinal(mdctx, sig, siglen);
+ sig[0] = ~sig[0];
+ testresult &=
+ EVP_DigestVerifyInit_ex(mdctx, NULL, "SHA512", libctx, NULL, key, NULL)
+ && EVP_DigestVerifyUpdate(mdctx, msg, sizeof(msg))
+ && !EVP_DigestVerifyFinal(mdctx, sig, siglen);
+ }
+
+ EVP_MD_CTX_free(mdctx);
+ EVP_PKEY_free(key);
+ OPENSSL_free(ctx);
+ OPENSSL_free(sig);
+ mdctx = NULL;
+ key = NULL;
+
+ // this test must work also with default provider inactive:
+ testresult &=
+ (ctx = EVP_PKEY_CTX_new_from_name(libctx, sigalg_name, NULL)) != NULL
+ && EVP_PKEY_keygen_init(ctx)
+ && EVP_PKEY_generate(ctx, &key)
+ && (mdctx = EVP_MD_CTX_new()) != NULL
+ && EVP_DigestSignInit_ex(mdctx, NULL, NULL, libctx, NULL, key, NULL)
+ && EVP_DigestSignUpdate(mdctx, msg, sizeof(msg))
+ && EVP_DigestSignFinal(mdctx, NULL, &siglen)
+ && (sig = OPENSSL_malloc(siglen)) != NULL
+ && EVP_DigestSignFinal(mdctx, sig, &siglen)
+ && EVP_DigestVerifyInit_ex(mdctx, NULL, NULL, libctx, NULL, key, NULL)
+ && EVP_DigestVerifyUpdate(mdctx, msg, sizeof(msg))
+ && EVP_DigestVerifyFinal(mdctx, sig, siglen);
+ sig[0] = ~sig[0];
+ testresult &=
+ EVP_DigestVerifyInit_ex(mdctx, NULL, NULL, libctx, NULL, key, NULL)
+ && EVP_DigestVerifyUpdate(mdctx, msg, sizeof(msg))
+ && !EVP_DigestVerifyFinal(mdctx, sig, siglen);
+
+ EVP_MD_CTX_free(mdctx);
+ EVP_PKEY_free(key);
+ OPENSSL_free(ctx);
+ OPENSSL_free(sig);
+ return testresult;
+}
+
+#define nelem(a) (sizeof(a)/sizeof((a)[0]))
+
+int main(int argc, char *argv[])
+{
+ size_t i;
+ int errcnt = 0, test = 0, query_nocache;
+ OSSL_PROVIDER *oqsprov = NULL;
+ const OSSL_ALGORITHM *sigalgs;
+
+ T((libctx = OSSL_LIB_CTX_new()) != NULL);
+ T(argc == 3);
+ modulename = argv[1];
+ configfile = argv[2];
+
+ load_oqs_provider(libctx, modulename, configfile);
+
+ oqsprov = OSSL_PROVIDER_load(libctx, modulename);
+
+ sigalgs = OSSL_PROVIDER_query_operation(oqsprov, OSSL_OP_SIGNATURE, &query_nocache);
+ if (sigalgs) {
+ for (; sigalgs->algorithm_names != NULL; sigalgs++) {
+ if (test_oqs_signatures(sigalgs->algorithm_names)) {
+ fprintf(stderr,
+ cGREEN " Signature test succeeded: %s" cNORM "\n",
+ sigalgs->algorithm_names);
+ } else {
+ fprintf(stderr,
+ cRED " Signature test failed: %s" cNORM "\n",
+ sigalgs->algorithm_names);
+ ERR_print_errors_fp(stderr);
+ errcnt++;
+ }
+ }
+ }
+
+ OSSL_LIB_CTX_free(libctx);
+
+ TEST_ASSERT(errcnt == 0)
+ return !test;
+}
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+#include <openssl/provider.h>
+#include <openssl/ssl.h>
+#include <string.h>
+#include "tlstest_helpers.h"
+#include "test_common.h"
+#include <openssl/core_names.h>
+
+#include <openssl/trace.h>
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+
+static OSSL_LIB_CTX *libctx = NULL;
+static char *modulename = NULL;
+static char *configfile = NULL;
+static char *certsdir = NULL;
+
+#ifdef OSSL_CAPABILITY_TLS_SIGALG_NAME
+static int test_oqs_tlssig(const char *sig_name)
+{
+ SSL_CTX *cctx = NULL, *sctx = NULL;
+ SSL *clientssl = NULL, *serverssl = NULL;
+ int ret = 1, testresult = 0;
+ char certpath[300];
+ char privkeypath[300];
+# ifndef OPENSSL_SYS_VMS
+ const char *sep = "/";
+# else
+ const char *sep = "";
+# endif
+
+ if (!alg_is_enabled(sig_name)) {
+ printf("Not testing disabled algorithm %s.\n", sig_name);
+ return 1;
+ }
+
+ sprintf(certpath, "%s%s%s%s", certsdir, sep, sig_name, "_srv.crt");
+ sprintf(privkeypath, "%s%s%s%s", certsdir, sep, sig_name, "_srv.key");
+ /* ensure certsdir exists */
+ if (mkdir(certsdir, 0700)) {
+ if (errno != EEXIST) {
+ fprintf(stderr, "Couldn't create certsdir %s: Err = %d\n", certsdir, errno);
+ ret = -1;
+ goto err;
+ }
+ }
+ if (!create_cert_key(libctx, (char*)sig_name, certpath, privkeypath)) {
+ fprintf(stderr, "Cert/keygen failed for %s at %s/%s\n", sig_name, certpath, privkeypath);
+ ret = -1; goto err;
+ }
+
+ testresult =
+ create_tls1_3_ctx_pair(libctx, &sctx, &cctx, certpath, privkeypath);
+
+ if (!testresult) {
+ ret = -1; goto err;
+ }
+
+ testresult =
+ create_tls_objects(sctx, cctx, &serverssl, &clientssl);
+
+ if (!testresult) {
+ ret = -2; goto err;
+ }
+
+ testresult =
+ create_tls_connection(serverssl, clientssl, SSL_ERROR_NONE);
+ if (!testresult) {
+ ret = -5; goto err;
+ }
+
+ err:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ SSL_CTX_free(sctx);
+ SSL_CTX_free(cctx);
+ return ret;
+}
+
+/* reactivate when EVP_SIGNATURE_do_all_provided doesn't crash any more:
+static void test_oqs_sigs(EVP_SIGNATURE *evpsig, void *vp) {
+ OSSL_PROVIDER* prov = EVP_SIGNATURE_get0_provider(evpsig);
+ if (!strcmp(OSSL_PROVIDER_get0_name(prov), "oqsprovider")) {
+ printf("Commencing test of %s:\n", EVP_SIGNATURE_get0_name(evpsig));
+ test_oqs_tlssig(EVP_SIGNATURE_get0_name(evpsig));
+ }
+}
+*/
+
+static int test_signature(const OSSL_PARAM params[], void *data)
+{
+ int ret = 0;
+ int *errcnt = (int *) data;
+ const OSSL_PARAM *p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_NAME);
+
+ if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING) {
+ ret = -1;
+ goto err;
+ }
+
+ char* sigalg_name = OPENSSL_strdup(p->data);
+
+ if (sigalg_name == NULL) return 0;
+
+ ret = test_oqs_tlssig(sigalg_name);
+
+ if (ret >= 0) {
+ fprintf(stderr,
+ cGREEN " TLS-SIG handshake test succeeded: %s" cNORM "\n",
+ sigalg_name);
+ } else {
+ fprintf(stderr,
+ cRED " TLS-SIG handshake test failed: %s, return code: %d" cNORM "\n",
+ sigalg_name, ret);
+ ERR_print_errors_fp(stderr);
+ (*errcnt)++;
+ }
+
+ err:
+ OPENSSL_free(sigalg_name);
+ return ret;
+}
+
+static int test_provider_signatures(OSSL_PROVIDER *provider, void *vctx)
+{
+ const char* provname = OSSL_PROVIDER_get0_name(provider);
+
+ if (!strcmp(provname, PROVIDER_NAME_OQS))
+ return OSSL_PROVIDER_get_capabilities(provider, "TLS-SIGALG",
+ test_signature, vctx);
+ else
+ return 1;
+}
+#endif /* OSSL_CAPABILITY_TLS_SIGALG_NAME */
+
+int main(int argc, char *argv[])
+{
+ size_t i;
+ int errcnt = 0, test = 0;
+
+#ifndef OPENSSL_NO_TRACE
+ fprintf(stderr, "Full tracing enabled via openssl config 'enable-trace'.\n");
+ BIO *err = BIO_new_fp(stderr, BIO_NOCLOSE | BIO_FP_TEXT);
+ OSSL_trace_set_channel(OSSL_TRACE_CATEGORY_ALL, err);
+#endif
+
+ T((libctx = OSSL_LIB_CTX_new()) != NULL);
+ T(argc == 4);
+ modulename = argv[1];
+ configfile = argv[2];
+ certsdir = argv[3];
+
+ load_oqs_provider(libctx, modulename, configfile);
+
+ T(OSSL_PROVIDER_available(libctx, "default"));
+
+#ifdef OSSL_CAPABILITY_TLS_SIGALG_NAME
+ // crashes: EVP_SIGNATURE_do_all_provided(libctx, test_oqs_sigs, &errcnt);
+ OSSL_PROVIDER_do_all(libctx, test_provider_signatures, &errcnt);
+#else
+ fprintf(stderr, "TLS-SIG handshake test not enabled. Update OpenSSL to more current version.\n");
+#endif
+
+ OSSL_LIB_CTX_free(libctx);
+ TEST_ASSERT(errcnt == 0)
+ return !test;
+}
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIDJTCCAg2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290
+IENBMCAXDTE2MDExNDIyMjk0NloYDzIxMTYwMTE1MjIyOTQ2WjAZMRcwFQYDVQQD
+DA5zZXJ2ZXIuZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ANVdYGrf/GHuSKqMEUhDpW22Ul2qmEmxYZI1sfw6BCUMbXn/tNXJ6VwcO+Crs7h9
+o95tveDd11q/FEcRQl6mgtBhwX/dE0bmCYUHDvLU/Bpk0gqtIKsga5bwrczEGVNV
+3AEdpLPvirRJU12KBRzx3OFEv8XX4ncZV1yXC3XuiENxD8pswbSyUKd3RmxYDxG/
+8XYkWq45QrdRZynh0FUwbxfkkeqt+CjCQ2+iZKn7nZiSYkg+6w1PgkqK/z9y7pa1
+rqHBmLrvfZB1bf9aUp6r9cB+0IdD24UHBw99OHr90dPuZR3T6jlqhzfuStPgDW71
+cKzCvfFu85KVXqnwoWWVk40CAwEAAaN9MHswHQYDVR0OBBYEFMDnhL/oWSczELBS
+T1FSLwbWwHrNMB8GA1UdIwQYMBaAFHB/Lq6DaFmYBCMqzes+F80k3QFJMAkGA1Ud
+EwQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGQYDVR0RBBIwEIIOc2VydmVyLmV4
+YW1wbGUwDQYJKoZIhvcNAQELBQADggEBAHvTBEN1ig8RrsT716Ginv4gGNX0LzGI
+RrZ1jO7lm5emuaPNYJpGw0iX5Zdo91qGNXPZaZ75X3S55pQTActq3OPEBOll2pyk
+iyjz+Zp/v5cfRZLlBbFW5gv2R94eibYr4U3fSn4B0yPcl4xH/l/HzJhGDsSDW8qK
+8VIJvmvsPwmL0JMCv+FR59F+NFYZdND/KCXet59WUpF9ICmFCoBEX3EyJXEPwhbi
+X2sdPzJbCjx0HLli8e0HUKNttLQxCsBTRGo6iISLLamwN47mGDa9miBADwGSiz2q
+YeeuLO02zToHhnQ6KbPXOrQAqcL1kngO4g+j/ru+4AZThFkdkGnltvk=
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDVXWBq3/xh7kiq
+jBFIQ6VttlJdqphJsWGSNbH8OgQlDG15/7TVyelcHDvgq7O4faPebb3g3ddavxRH
+EUJepoLQYcF/3RNG5gmFBw7y1PwaZNIKrSCrIGuW8K3MxBlTVdwBHaSz74q0SVNd
+igUc8dzhRL/F1+J3GVdclwt17ohDcQ/KbMG0slCnd0ZsWA8Rv/F2JFquOUK3UWcp
+4dBVMG8X5JHqrfgowkNvomSp+52YkmJIPusNT4JKiv8/cu6Wta6hwZi6732QdW3/
+WlKeq/XAftCHQ9uFBwcPfTh6/dHT7mUd0+o5aoc37krT4A1u9XCswr3xbvOSlV6p
+8KFllZONAgMBAAECggEADLTt7A+A2Vg2jamf0dztejY0e42QWjstI2b9PZc67fXq
+gyx+WYkX07t+uWegYWliG/oPJ9guXiIpE/5sJHToL37S5kmFP2CtynVcJ4wVo4DD
+nY0n9+kLX0bgIuS+2V6wpoRcbbbjXM9NHrH8kfe5ftT4UtEDlLI2qLX6IcDd7p4u
+OYjILChR8GSGTw96yIy2Ws/1Uq9PMw64JoT4RcK5QqnkcPMDFRH1SeLOL+zXP2c4
+nEl9yOy3HauZKxwl/Ry/XK1s3DdjopIAU29ut+hAuMiTb06kzZnumL9NoplKoZtU
+otw/gVcCKhT+Ep+p6i8InLF0XEME8A0qUR0niWebgQKBgQD6vkxR49B8ZZQrzjw4
+XKs1lI9cP7cgPiuWlDHMNjYou3WbOaGrMeScvbB1Ldh9A8pjAhxlw8AaV/xs4qcA
+trmVmSISVMVyc1wSGlJXWi2nUzTNs9OE3vj22SyStihf8UUZtWwX2b5Y4JrYhA/V
++ThGGqHR03oLNLShNLtJc2c7YQKBgQDZ1nkibEyrepexw/fnwkw61IJKq9wRIh1G
+PREakhbe9wU5ie0knuf9razt7awzQiwFmlixmWqsM7UEtLuXNnNPciwdrKhhbvrd
+vD/rkbIEHEPllIhFlDtOzn3hRBWTzWmXFjpou/2LvHTSbVis4IYVZymTp2jb1ZLs
+7VbiG9JTrQKBgQDc6n75g1szzpdehQT/r33U5j/syeJBUSU8NPMu9fB/sLHsgjlT
+SNEf2+y1QSBE/Or6kmiMrIv7advn30W+Vj9qc5HWTsPrk4HiHTjA553jl2alebN5
+lK4LZspjtIQcC8mS3goPdXPEgJdM/gWpwzr2YQ6DfOxBJT2j7n64NyoT4QKBgH7/
+yx+GhCx1DHtXBPDZFhg2TL+78lEK0oZgk9gp06up2CHzh44SFq6O0oLkTcCUk5Ww
+poTkLIy4mJBlzfgahp+KsK2cO46SZS9g0ONFzcMXt33hWpE2Gl2XhUwPpYTF/QlY
+rDTjZK5S8Mi9dzVSsNlJi7PJphiEK2R1+nFYRwcBAoGBANWoIG85jpXAOnq/Kcgx
+Rl3YivR0Ke6r1tFlP58rT7X3EkiboXyQl5vLIFCAwUte6RGrLl1dy3Qyh80B9ySL
+Jx6vj42CK7vgv6A96TuVYhnXTnEI6ZvwAQ2VGaw4BizhjALs/kdSE/og9aSCs3ws
+KQypwAFz0tbHxaNag/bSAN0J
+-----END PRIVATE KEY-----
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+#include "test_common.h"
+#include <string.h>
+
+
+void hexdump(const void *ptr, size_t len)
+{
+ const unsigned char *p = ptr;
+ size_t i, j;
+
+ for (i = 0; i < len; i += j) {
+ for (j = 0; j < 16 && i + j < len; j++)
+ printf("%s%02x", j? "" : " ", p[i + j]);
+ }
+ printf("\n");
+}
+
+#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
+int alg_is_enabled(const char *algname) {
+ char *alglist = getenv("OQS_SKIP_TESTS");
+ char *comma = NULL;
+ char totest[200];
+
+ if (alglist == NULL) return 1;
+
+ while((comma = strchr(alglist, ','))) {
+ memcpy(totest, alglist, MIN(200,comma-alglist));
+ totest[comma-alglist]='\0';
+ if (strstr(algname, totest)) return 0;
+ alglist = comma+1;
+ }
+ return strstr(algname, alglist) == NULL;
+}
+
+#ifdef OQS_PROVIDER_STATIC
+#define OQS_PROVIDER_ENTRYPOINT_NAME oqs_provider_init
+#else
+#define OQS_PROVIDER_ENTRYPOINT_NAME OSSL_provider_init
+#endif // ifdef OQS_PROVIDER_STATIC
+
+#ifndef OQS_PROVIDER_STATIC
+
+/* Loads the oqs-provider from a shared module (.so). */
+void load_oqs_provider(OSSL_LIB_CTX *libctx, const char *modulename, const char *configfile) {
+ T(OSSL_LIB_CTX_load_config(libctx, configfile));
+ T(OSSL_PROVIDER_available(libctx, modulename));
+}
+
+#else
+
+extern OSSL_provider_init_fn OQS_PROVIDER_ENTRYPOINT_NAME;
+
+/* Loads the statically linked oqs-provider. */
+void load_oqs_provider(OSSL_LIB_CTX *libctx, const char *modulename, const char *configfile) {
+ (void)configfile;
+ T(OSSL_PROVIDER_add_builtin(libctx, modulename, OQS_PROVIDER_ENTRYPOINT_NAME));
+ T(OSSL_PROVIDER_load(libctx, "default"));
+}
+
+# endif // ifndef OQS_PROVIDER_STATIC
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/provider.h>
+
+/* For controlled success */
+#define T(e) \
+ if (!(e)) { \
+ ERR_print_errors_fp(stderr); \
+ OPENSSL_die(#e, __FILE__, __LINE__); \
+ }
+/* For controlled failure */
+#define TF(e) \
+ if ((e)) { \
+ ERR_print_errors_fp(stderr); \
+ } else { \
+ OPENSSL_die(#e, __FILE__, __LINE__); \
+ }
+#define cRED "\033[1;31m"
+#define cDRED "\033[0;31m"
+#define cGREEN "\033[1;32m"
+#define cDGREEN "\033[0;32m"
+#define cBLUE "\033[1;34m"
+#define cDBLUE "\033[0;34m"
+#define cNORM "\033[m"
+#define PROVIDER_NAME_OQS "oqsprovider"
+#define TEST_ASSERT(e) \
+ { \
+ if (!(test = (e))) \
+ printf(cRED " Test FAILED" cNORM "\n"); \
+ else \
+ printf(cGREEN " Test passed" cNORM "\n"); \
+ }
+
+void hexdump(const void *ptr, size_t len);
+int alg_is_enabled(const char *algname);
+
+/* Loads the oqs-provider. */
+void load_oqs_provider(OSSL_LIB_CTX *libctx, const char *modulename, const char *configfile);
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+
+#define MAXLOOPS 1000000
+
+/* Stolen from openssl/tests/sslapitest.c: */
+int create_cert_key(OSSL_LIB_CTX *libctx, char *algname, char *certfilename, char *privkeyfilename)
+{
+ EVP_PKEY_CTX * evpctx = EVP_PKEY_CTX_new_from_name(libctx, algname, NULL);
+ EVP_PKEY *pkey = NULL;
+ X509 *x509 = X509_new();
+ X509_NAME *name = NULL;
+ BIO *keybio = NULL, *certbio = NULL;
+ int ret = 1;
+
+ if (!evpctx
+ || !EVP_PKEY_keygen_init(evpctx)
+ || !EVP_PKEY_generate(evpctx, &pkey)
+ || !pkey
+ || !x509
+ || !ASN1_INTEGER_set(X509_get_serialNumber(x509), 1)
+ || !X509_gmtime_adj(X509_getm_notBefore(x509), 0)
+ || !X509_gmtime_adj(X509_getm_notAfter(x509), 31536000L)
+ || !X509_set_pubkey(x509, pkey)
+ || !(name = X509_get_subject_name(x509))
+ || !X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
+ (unsigned char *)"CH", -1, -1, 0)
+ || !X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
+ (unsigned char *)"test.org", -1, -1, 0)
+ || !X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
+ (unsigned char *)"localhost", -1, -1, 0)
+ || !X509_set_issuer_name(x509, name)
+ || !X509_sign(x509, pkey, EVP_sha1())
+ || !(keybio = BIO_new_file(privkeyfilename, "wb"))
+ || !PEM_write_bio_PrivateKey(keybio, pkey, NULL, NULL, 0, NULL, NULL)
+ || !(certbio = BIO_new_file(certfilename, "wb"))
+ || !PEM_write_bio_X509(certbio, x509))
+ ret = 0;
+
+ EVP_PKEY_free(pkey);
+ X509_free(x509);
+ EVP_PKEY_CTX_free(evpctx);
+ BIO_free(keybio);
+ BIO_free(certbio);
+ return ret;
+}
+/* end steal */
+int create_tls1_3_ctx_pair(OSSL_LIB_CTX *libctx, SSL_CTX **sctx, SSL_CTX **cctx,
+ char *certfile, char *privkeyfile) {
+ SSL_CTX *serverctx = NULL, *clientctx = NULL;
+
+ if (sctx == NULL || cctx == NULL)
+ goto err;
+
+ serverctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method());
+ clientctx = SSL_CTX_new_ex(libctx, NULL, TLS_client_method());
+
+ if (serverctx == NULL || clientctx == NULL)
+ goto err;
+
+ SSL_CTX_set_options(serverctx,SSL_OP_ALLOW_CLIENT_RENEGOTIATION);
+ SSL_CTX_set_min_proto_version(serverctx,TLS1_3_VERSION);
+ SSL_CTX_set_max_proto_version(serverctx,TLS1_3_VERSION);
+ SSL_CTX_set_min_proto_version(clientctx,TLS1_3_VERSION);
+ SSL_CTX_set_max_proto_version(clientctx,TLS1_3_VERSION);
+
+ if (!SSL_CTX_use_certificate_file(serverctx, certfile,
+ SSL_FILETYPE_PEM) )
+ goto err;
+
+ if (!SSL_CTX_use_PrivateKey_file(serverctx,privkeyfile,
+ SSL_FILETYPE_PEM))
+ goto err;
+
+ if (!SSL_CTX_check_private_key(serverctx))
+ goto err;
+
+ *sctx = serverctx;
+ *cctx = clientctx;
+ return 1;
+
+ err:
+ SSL_CTX_free(serverctx);
+ SSL_CTX_free(clientctx);
+ return 0;
+}
+
+int create_tls_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
+ SSL **cssl) {
+ SSL *serverssl = NULL, *clientssl = NULL;
+ BIO *s_to_c_bio = NULL, *c_to_s_bio = NULL;
+
+ if(serverctx == NULL || clientctx == NULL)
+ goto err;
+
+ serverssl = SSL_new(serverctx);
+ clientssl = SSL_new(clientctx);
+
+ if (serverssl == NULL || clientssl == NULL)
+ goto err;
+
+ s_to_c_bio = BIO_new(BIO_s_mem());
+ c_to_s_bio = BIO_new(BIO_s_mem());
+
+ if (s_to_c_bio == NULL || c_to_s_bio == NULL)
+ goto err;
+
+ /* Set Non-blocking IO behaviour */
+ BIO_set_mem_eof_return(s_to_c_bio, -1);
+ BIO_set_mem_eof_return(c_to_s_bio, -1);
+
+ /* Up ref these as we are passing them to two SSL objects */
+ SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio);
+ BIO_up_ref(s_to_c_bio);
+ BIO_up_ref(c_to_s_bio);
+ SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio);
+
+ *sssl = serverssl;
+ *cssl = clientssl;
+
+ return 1;
+
+ err:
+ SSL_free(serverssl);
+ SSL_free(clientssl);
+ BIO_free(s_to_c_bio);
+ BIO_free(c_to_s_bio);
+
+ return 0;
+}
+
+/* Create an SSL connection, but does not read any post-handshake
+* NewSessionTicket messages.
+* We stop the connection attempt (and return a failure value) if either peer
+* has SSL_get_error() return the value in the |want| parameter. The connection
+* attempt could be restarted by a subsequent call to this function.
+*/
+int create_bare_tls_connection(SSL *serverssl, SSL *clientssl, int want,
+ int read)
+{
+ int retc = -1, rets = -1, err, abortctr = 0;
+ int clienterr = 0, servererr = 0;
+
+
+ do {
+ err = SSL_ERROR_WANT_WRITE;
+ while (!clienterr && retc <= 0 && err == SSL_ERROR_WANT_WRITE) {
+ retc = SSL_connect(clientssl);
+ if (retc <= 0)
+ err = SSL_get_error(clientssl, retc);
+ }
+
+ if (!clienterr && retc <= 0 && err != SSL_ERROR_WANT_READ) {
+ fprintf(stderr, "SSL_connect() failed %d, %d", retc, err);
+ if (want != SSL_ERROR_SSL)
+ ERR_clear_error();
+ clienterr = 1;
+ }
+ if (want != SSL_ERROR_NONE && err == want)
+ return 0;
+
+ err = SSL_ERROR_WANT_WRITE;
+ while (!servererr && rets <= 0 && err == SSL_ERROR_WANT_WRITE) {
+ rets = SSL_accept(serverssl);
+ if (rets <= 0)
+ err = SSL_get_error(serverssl, rets);
+ }
+
+ if (!servererr && rets <= 0
+ && err != SSL_ERROR_WANT_READ
+ && err != SSL_ERROR_WANT_X509_LOOKUP) {
+ fprintf(stderr, "SSL_accept() failed %d, %d", rets, err);
+ if (want != SSL_ERROR_SSL)
+ ERR_clear_error();
+ servererr = 1;
+ }
+ if (want != SSL_ERROR_NONE && err == want)
+ return 0;
+ if (clienterr && servererr)
+ return 0;
+
+ if (++abortctr == MAXLOOPS) {
+ fprintf(stderr, "No progress made");
+ return 0;
+ }
+
+ } while (retc <=0 || rets <= 0);
+
+ return 1;
+}
+
+/*
+ * Create an SSL connection including any post handshake NewSessionTicket
+ * messages.
+ */
+int create_tls_connection(SSL *serverssl, SSL *clientssl, int want)
+{
+ int i;
+ unsigned char buf;
+ size_t readbytes;
+
+ if (!create_bare_tls_connection(serverssl, clientssl, want, 1))
+ return 0;
+
+ /*
+ * We attempt to read some data on the client side which we expect to fail.
+ * This will ensure we have received the NewSessionTicket in TLSv1.3 where
+ * appropriate. We do this twice because there are 2 NewSessionTickets.
+ */
+ for (i = 0; i < 2; i++) {
+ if (SSL_read_ex(clientssl, &buf, sizeof(buf), &readbytes) > 0) {
+ if (readbytes !=0)
+ return 0;
+ } else if (SSL_get_error(clientssl, 0) != SSL_ERROR_WANT_READ) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
--- /dev/null
+// SPDX-License-Identifier: Apache-2.0 AND MIT
+
+int create_cert_key(OSSL_LIB_CTX *libctx, char *algname, char *certfilename, char *privkeyfilename);
+
+int create_tls1_3_ctx_pair(OSSL_LIB_CTX *libctx, SSL_CTX **sctx, SSL_CTX **cctx,
+ char *certfile, char *privkeyfile);
+
+int create_tls_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
+ SSL **cssl);
+
+int create_tls_connection(SSL *serverssl, SSL *clientssl, int want);