diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 1b9a3d7dc..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,308 +0,0 @@ -version: 2.1 - -require_stylecheck: &require_stylecheck - requires: - - stylecheck - -require_buildcheck: &require_buildcheck - requires: - - stylecheck - - buildcheck - -require_testapproval: &require_testapproval - requires: - - stylecheck - - buildcheck - - testapproval - -# 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: |- - PROJECT_PATH=$(cd ${CIRCLE_WORKING_DIRECTORY}; pwd) - mkdir -p ${PROJECT_PATH} - git config --global --add safe.directory /tmp/_circleci_local_build_repo - 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: - stylecheck: - description: Validate formatting of code and documentation - docker: - - image: openquantumsafe/ci-ubuntu-focal-x86_64:latest -# Re-enable iff docker enforces rate limitations without auth: -# auth: -# username: $DOCKER_LOGIN -# password: $DOCKER_PASSWORD - steps: - - checkout # change this from "checkout" to "*localCheckout" when running CircleCI locally - - run: - name: Ensure code conventions are upheld - command: python3 -m pytest --verbose tests/test_code_conventions.py - - run: - name: Check that doxygen can parse the documentation - command: mkdir -p build/docs && ./scripts/run_doxygen.sh doxygen docs/.Doxyfile build/docs - - buildcheck: - description: Test that we can build a single KEM/Signature pair as part of a minimal build. - parameters: - CONTAINER: - description: "The docker container to use." - type: string - CMAKE_ARGS: - description: "Arguments to pass to CMake." - type: string - default: '' - KEM_NAME: - description: "The KEM to build." - type: string - SIG_NAME: - description: "The signature scheme to build." - type: string - docker: - - image: << parameters.CONTAINER >> - steps: - - checkout # change this from "checkout" to "*localCheckout" when running CircleCI locally - - run: - name: Configure - command: |2 - mkdir build && cd build && source ~/.bashrc && \ - cmake .. --warn-uninitialized \ - -GNinja << parameters.CMAKE_ARGS >> \ - -DOQS_MINIMAL_BUILD="KEM_<< parameters.KEM_NAME >>;SIG_<< parameters.SIG_NAME >>" \ - > config.log 2>&1 && \ - cat config.log && \ - cmake -LA -N .. && ! (grep "uninitialized variable" config.log) - - run: - name: Build - command: ninja - working_directory: build - - linux_oqs: - description: A template for running liboqs tests on Linux Docker VMs - parameters: - CONTAINER: - description: "The docker container to use." - type: string - CMAKE_ARGS: - description: "Arguments to pass to CMake." - type: string - default: '' - PYTEST_ARGS: - description: "Arguments to pass to pytest." - type: string - # Not every executor handles --numprocesses=auto being passed to pytest well - # See https://github.com/open-quantum-safe/liboqs/issues/738#issuecomment-621394744 - default: --numprocesses=auto - SKIP_ALGS: - description: "Algorithms not to test in test_constant_time." - type: string - default: '' - docker: - - image: << parameters.CONTAINER >> -# Re-enable iff docker enforces rate limitations without auth: -# auth: -# username: $DOCKER_LOGIN -# password: $DOCKER_PASSWORD - steps: - - checkout # change this from "checkout" to "*localCheckout" when running CircleCI locally - - run: - name: Configure - command: mkdir build && cd build && source ~/.bashrc && cmake -GNinja << parameters.CMAKE_ARGS >> .. && cmake -LA -N .. - - run: - name: Build - command: ninja - working_directory: build - - run: - name: Run tests - no_output_timeout: 1h - command: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_speed.py --ignore=tests/test_code_conventions.py --junitxml=build/test-results/pytest/test-results.xml << parameters.PYTEST_ARGS >> - environment: - SKIP_ALGS: << parameters.SKIP_ALGS >> - - store_test_results: # Note that this command will fail when running CircleCI locally, that is expected behaviour - path: build/test-results - - store_artifacts: - path: build/test-results - - - scan_build: - description: Executing scan-build test - parameters: - CONTAINER: - description: "The docker container to use." - type: string - docker: - - image: << parameters.CONTAINER >> - steps: - - checkout # change this from "checkout" to "*localCheckout" when running CircleCI locally - - run: - name: Configure - command: mkdir build && cd build && pwd && source ~/.bashrc && scan-build-15 cmake -GNinja .. - - run: - name: Build - command: scan-build-15 --status-bugs ninja - working_directory: build - - 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-OpenSSL CI - command: |2 - curl --silent \ - --write-out "\n%{response_code}\n" \ - --user ${BUILD_TRIGGER_TOKEN}: \ - --request POST \ - --header "Content-Type: application/json" \ - --data '{ "branch": "OQS-OpenSSL_1_1_1-stable", "parameters": { "run_downstream_tests": true } }' \ - https://circleci.com/api/v2/project/gh/open-quantum-safe/openssl/pipeline | tee curl_out \ - && grep -q "201" curl_out - - - run: - name: Trigger OQS-BoringSSL CI - command: |2 - curl --silent \ - --write-out "\n%{response_code}\n" \ - --user ${BUILD_TRIGGER_TOKEN}: \ - --request POST \ - --header "Content-Type: application/json" \ - --data '{ "branch": "master", "parameters": { "run_downstream_tests": true } }' \ - https://circleci.com/api/v2/project/gh/open-quantum-safe/boringssl/pipeline | tee curl_out \ - && grep -q "201" curl_out - - run: - name: Trigger OQS-OpenSSH CI - command: |2 - curl --silent \ - --write-out "\n%{response_code}\n" \ - --user ${BUILD_TRIGGER_TOKEN}: \ - --request POST \ - --header "Content-Type: application/json" \ - --data '{ "branch": "OQS-v8", "parameters": { "run_downstream_tests": true } }' \ - https://circleci.com/api/v2/project/gh/open-quantum-safe/openssh/pipeline | tee curl_out \ - && grep -q "201" curl_out - - run: - name: Trigger oqs-provider CI - command: |2 - curl --silent \ - --write-out "\n%{response_code}\n" \ - --user ${BUILD_TRIGGER_TOKEN}: \ - --request POST \ - --header "Content-Type: application/json" \ - --data '{ "branch": "main" }' \ - https://circleci.com/api/v2/project/gh/open-quantum-safe/oqs-provider/pipeline | tee curl_out \ - && grep -q "201" curl_out - - run: - name: Trigger liboqs-dotnet CI - command: |2 - curl --silent \ - --write-out "\n%{response_code}\n" \ - --user ${BUILD_TRIGGER_TOKEN}: \ - --request POST \ - --header "Content-Type: application/json" \ - --data '{ "branch": "master" }' \ - https://circleci.com/api/v2/project/gh/open-quantum-safe/liboqs-dotnet/pipeline | tee curl_out \ - && grep -q "201" curl_out - - run: - name: Trigger liboqs-java CI - command: |2 - curl --silent \ - --write-out "\n%{response_code}\n" \ - --user ${BUILD_TRIGGER_TOKEN}: \ - --request POST \ - --header "Content-Type: application/json" \ - --data '{ "branch": "master" }' \ - https://circleci.com/api/v2/project/gh/open-quantum-safe/liboqs-java/pipeline | tee curl_out \ - && grep -q "201" curl_out - - run: - name: Trigger liboqs-python CI - command: |2 - curl --silent \ - --write-out "\n%{response_code}\n" \ - --request POST \ - --header "Accept: application/vnd.github+json" \ - --header "Authorization: Bearer $OQSBOT_GITHUB_ACTIONS" \ - --header "X-GitHub-Api-Version: 2022-11-28" \ - --data '{"event_type":"liboqs-upstream-trigger"}' \ - https://api.github.com/repos/open-quantum-safe/liboqs-python/dispatches | tee curl_out \ - && grep -q "204" curl_out - -workflows: - version: 2.1 - build: - when: - and: - - not: - equal: [ main, << pipeline.git.branch >> ] - - not: - matches: { pattern: "^ghactionsonly-.*", value: << pipeline.git.branch >> } - jobs: - - stylecheck - - buildcheck: - <<: *require_stylecheck - context: openquantumsafe - CONTAINER: openquantumsafe/ci-ubuntu-focal-x86_64:latest - KEM_NAME: kyber_768 - SIG_NAME: dilithium_3 - # Disabling testapproval as no jobs currently need it. - #- testapproval: - # <<: *require_buildcheck - # type: approval - # Disabling centos-8 and debian-buster. - # Re-enable if specific configurations (package versions etc) that need to be tested are identified. - #- linux_oqs: - # <<: *require_buildcheck - # name: centos-8 - # context: openquantumsafe - # CONTAINER: openquantumsafe/ci-centos-8-amd64:latest - # CMAKE_ARGS: -DCMAKE_C_COMPILER=clang - #- linux_oqs: - # <<: *require_buildcheck - # name: debian-buster - # context: openquantumsafe - # CONTAINER: openquantumsafe/ci-debian-buster-amd64:latest - - scan_build: - <<: *require_buildcheck - name: scan_build - context: openquantumsafe - CONTAINER: openquantumsafe/ci-ubuntu-focal-x86_64:latest - - linux_oqs: - <<: *require_buildcheck - name: ubuntu-focal-noopenssl - context: openquantumsafe - CONTAINER: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DCMAKE_C_COMPILER=gcc-8 -DOQS_USE_OPENSSL=OFF - PYTEST_ARGS: --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py - - linux_oqs: - <<: *require_buildcheck - name: ubuntu-focal-shared-noopenssl - context: openquantumsafe - CONTAINER: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DCMAKE_C_COMPILER=gcc-7 -DOQS_DIST_BUILD=OFF -DOQS_USE_OPENSSL=OFF -DBUILD_SHARED_LIBS=ON - PYTEST_ARGS: --ignore=tests/test_namespace.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --numprocesses=auto - - linux_oqs: - <<: *require_buildcheck - name: ubuntu-focal-clang15 - context: openquantumsafe - CONTAINER: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DCMAKE_C_COMPILER=clang-15 -DOQS_OPT_TARGET=skylake - PYTEST_ARGS: --ignore=tests/test_kat_all.py - - linux_oqs: - <<: *require_buildcheck - name: ubuntu-bionic-i386 - context: openquantumsafe - CONTAINER: openquantumsafe/ci-ubuntu-bionic-i386:latest - CMAKE_ARGS: -DCMAKE_TOOLCHAIN_FILE=../.CMake/toolchain_x86.cmake - PYTEST_ARGS: --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py - - commit-to-main: - when: - equal: [ main, << pipeline.git.branch >> ] - jobs: - - trigger-downstream-ci: - context: openquantumsafe diff --git a/.github/workflows/commit-to-main.yml b/.github/workflows/commit-to-main.yml new file mode 100644 index 000000000..7c1daa6f3 --- /dev/null +++ b/.github/workflows/commit-to-main.yml @@ -0,0 +1,87 @@ +name: Trigger basic downstream CI + +permissions: + contents: read + +on: + push: + branches: [ "main" ] + +jobs: + trigger-downstream-ci: + strategy: + fail-fast: false + runs-on: ubuntu-latest + steps: + # TODO: missing projects? + - name: Trigger OQS-OpenSSL CI + run: | + curl --silent \ + --write-out "\n%{response_code}\n" \ + --user ${{ secrets.BUILD_TRIGGER_TOKEN }}: \ + --request POST \ + --header "Content-Type: application/json" \ + --data '{ "branch": "OQS-OpenSSL_1_1_1-stable", "parameters": { "run_downstream_tests": true } }' \ + https://circleci.com/api/v2/project/gh/open-quantum-safe/openssl/pipeline | tee curl_out \ + && grep -q "201" curl_out + - name: Trigger OQS-BoringSSL CI + run: | + curl --silent \ + --write-out "\n%{response_code}\n" \ + --user ${{ secrets.BUILD_TRIGGER_TOKEN }}: \ + --request POST \ + --header "Content-Type: application/json" \ + --data '{ "branch": "master", "parameters": { "run_downstream_tests": true } }' \ + https://circleci.com/api/v2/project/gh/open-quantum-safe/boringssl/pipeline | tee curl_out \ + && grep -q "201" curl_out + - name: Trigger OQS-OpenSSH CI + run: | + curl --silent \ + --write-out "\n%{response_code}\n" \ + --user ${{ secrets.BUILD_TRIGGER_TOKEN }}: \ + --request POST \ + --header "Content-Type: application/json" \ + --data '{ "branch": "OQS-v8", "parameters": { "run_downstream_tests": true } }' \ + https://circleci.com/api/v2/project/gh/open-quantum-safe/openssh/pipeline | tee curl_out \ + && grep -q "201" curl_out + - name: Trigger oqs-provider CI + run: | + curl --silent \ + --write-out "\n%{response_code}\n" \ + --user ${{ secrets.BUILD_TRIGGER_TOKEN }}: \ + --request POST \ + --header "Content-Type: application/json" \ + --data '{ "branch": "main" }' \ + https://circleci.com/api/v2/project/gh/open-quantum-safe/oqs-provider/pipeline | tee curl_out \ + && grep -q "201" curl_out + - name: Trigger liboqs-dotnet CI + run: | + curl --silent \ + --write-out "\n%{response_code}\n" \ + --user ${{ secrets.BUILD_TRIGGER_TOKEN }}: \ + --request POST \ + --header "Content-Type: application/json" \ + --data '{ "branch": "master" }' \ + https://circleci.com/api/v2/project/gh/open-quantum-safe/liboqs-dotnet/pipeline | tee curl_out \ + && grep -q "201" curl_out + - name: Trigger liboqs-java CI + run: | + curl --silent \ + --write-out "\n%{response_code}\n" \ + --user ${{ secrets.BUILD_TRIGGER_TOKEN }}: \ + --request POST \ + --header "Content-Type: application/json" \ + --data '{ "branch": "master" }' \ + https://circleci.com/api/v2/project/gh/open-quantum-safe/liboqs-java/pipeline | tee curl_out \ + && grep -q "201" curl_out + - name: Trigger liboqs-python CI + run: | + curl --silent \ + --write-out "\n%{response_code}\n" \ + --request POST \ + --header "Accept: application/vnd.github+json" \ + --header "Authorization: Bearer ${{ secrets.OQSBOT_GITHUB_ACTIONS }}" \ + --header "X-GitHub-Api-Version: 2022-11-28" \ + --data '{"event_type":"liboqs-upstream-trigger"}' \ + https://api.github.com/repos/open-quantum-safe/liboqs-python/dispatches | tee curl_out \ + && grep -q "204" curl_out diff --git a/.github/workflows/unix.yml b/.github/workflows/unix.yml index 07deb8544..9bac98d3b 100644 --- a/.github/workflows/unix.yml +++ b/.github/workflows/unix.yml @@ -85,7 +85,7 @@ jobs: - name: arm64 runner: oqs-arm64 container: openquantumsafe/ci-ubuntu-focal-arm64:latest - PYTEST_ARGS: --numprocesses=auto --maxprocesses=10 --ignore=tests/test_kat_all.py + PYTEST_ARGS: --maxprocesses=10 --ignore=tests/test_kat_all.py CMAKE_ARGS: -DOQS_ENABLE_SIG_STFL_LMS=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON - name: alpine runner: ubuntu-latest @@ -117,6 +117,21 @@ jobs: container: openquantumsafe/ci-ubuntu-focal-x86_64:latest CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DOQS_ALGS_ENABLED=NIST_SIG_ONRAMP PYTEST_ARGS: --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py + - name: focal-noopenssl + runner: ubuntu-latest + container: openquantumsafe/ci-ubuntu-focal-x86_64:latest + CMAKE_ARGS: -DCMAKE_C_COMPILER=gcc-8 -DOQS_USE_OPENSSL=OFF + PYTEST_ARGS: --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py + - name: focal-shared-noopenssl + runner: ubuntu-latest + container: openquantumsafe/ci-ubuntu-focal-x86_64:latest + CMAKE_ARGS: -DCMAKE_C_COMPILER=gcc-7 -DOQS_DIST_BUILD=OFF -DOQS_USE_OPENSSL=OFF -DBUILD_SHARED_LIBS=ON + PYTEST_ARGS: --ignore=tests/test_namespace.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py + - name: focal-clang15 + runner: ubuntu-latest + container: openquantumsafe/ci-ubuntu-focal-x86_64:latest + CMAKE_ARGS: -DOQS_STRICT_WARNINGS=ON -DCMAKE_C_COMPILER=clang-15 + PYTEST_ARGS: --ignore=tests/test_kat_all.py - name: jammy-std-openssl3 runner: ubuntu-latest container: openquantumsafe/ci-ubuntu-jammy:latest @@ -131,12 +146,12 @@ jobs: runner: ubuntu-latest container: openquantumsafe/ci-ubuntu-focal-x86_64:latest CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON - PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --numprocesses=auto --maxprocesses=10 + PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --maxprocesses=10 - name: address-sanitizer-no-stfl-key-sig-gen runner: ubuntu-latest container: openquantumsafe/ci-ubuntu-focal-x86_64:latest CMAKE_ARGS: -DCMAKE_C_COMPILER=clang-9 -DCMAKE_BUILD_TYPE=Debug -DUSE_SANITIZER=Address -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON - PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --numprocesses=auto --maxprocesses=10 + PYTEST_ARGS: --ignore=tests/test_distbuild.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py --maxprocesses=10 runs-on: ${{ matrix.runner }} container: image: ${{ matrix.container }} @@ -150,7 +165,7 @@ jobs: working-directory: build - name: Run tests timeout-minutes: 60 - run: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_code_conventions.py ${{ matrix.PYTEST_ARGS }} + run: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_code_conventions.py --numprocesses=auto ${{ matrix.PYTEST_ARGS }} - name: Package .deb if: matrix.name == 'jammy-std-openssl3' run: cpack @@ -175,16 +190,16 @@ jobs: include: - name: armhf ARCH: armhf - CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_DIST_BUILD=OFF -DOQS_OPT_TARGET=generic -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py - name: armhf-no-stfl-key-sig-gen ARCH: armhf - CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON + CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_DIST_BUILD=OFF -DOQS_OPT_TARGET=generic -DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=OFF -DOQS_ENABLE_SIG_STFL_XMSS=ON -DOQS_ENABLE_SIG_STFL_LMS=ON PYTEST_ARGS: --ignore=tests/test_alg_info.py --ignore=tests/test_kat_all.py # no longer supporting armel # - name: armel # ARCH: armel - # CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_OPT_TARGET=generic + # CMAKE_ARGS: -DOQS_ENABLE_SIG_SPHINCS=OFF -DOQS_USE_OPENSSL=OFF -DOQS_DIST_BUILD=OFF -DOQS_OPT_TARGET=generic steps: - name: Checkout code uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4 @@ -270,7 +285,7 @@ jobs: run: ninja working-directory: build - name: Run tests - run: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_code_conventions.py --ignore=tests/test_kat_all.py ${{ matrix.PYTEST_ARGS }} + run: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_code_conventions.py --ignore=tests/test_kat_all.py timeout-minutes: 60 linux_openssl330-dev: @@ -319,3 +334,16 @@ jobs: - name: Run tests timeout-minutes: 60 run: mkdir -p tmp && python3 -m pytest --verbose --ignore=tests/test_code_conventions.py --ignore=tests/test_leaks.py --ignore=tests/test_kat_all.py + + scan_build: + needs: buildcheck + runs-on: ubuntu-latest + container: openquantumsafe/ci-ubuntu-focal-x86_64:latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Configure + run: mkdir build && cd build && scan-build-15 cmake -GNinja .. + - name: Build + run: scan-build-15 --status-bugs ninja + working-directory: build diff --git a/.github/workflows/weekly.yml b/.github/workflows/weekly.yml index a3bebf325..d79fda6f1 100644 --- a/.github/workflows/weekly.yml +++ b/.github/workflows/weekly.yml @@ -21,7 +21,7 @@ jobs: SKIP_ALGS: 'SPHINCS\+-SHA(.)*s-simple,SPHINCS\+-SHAKE-(.)*,Classic-McEliece-[^3](.)*' - name: extensions container: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DOQS_DIST_BUILD=OFF -DOQS_OPT_TARGET=haswell -DCMAKE_BUILD_TYPE=Debug -DOQS_ENABLE_TEST_CONSTANT_TIME=ON + CMAKE_ARGS: -DOQS_DIST_BUILD=OFF -DOQS_OPT_TARGET=auto -DCMAKE_BUILD_TYPE=Debug -DOQS_ENABLE_TEST_CONSTANT_TIME=ON PYTEST_ARGS: --numprocesses=auto -k 'test_constant_time' SKIP_ALGS: 'SPHINCS\+-SHA(.)*s-simple,SPHINCS\+-SHAKE-(.)*,Classic-McEliece-[^3](.)*' container: @@ -50,7 +50,7 @@ jobs: PYTEST_ARGS: --numprocesses=auto -k 'test_kat_all' - name: extensions container: openquantumsafe/ci-ubuntu-focal-x86_64:latest - CMAKE_ARGS: -DOQS_DIST_BUILD=OFF -DOQS_OPT_TARGET=haswell + CMAKE_ARGS: -DOQS_DIST_BUILD=OFF -DOQS_OPT_TARGET=auto PYTEST_ARGS: --numprocesses=auto -k 'test_kat_all' container: image: ${{ matrix.container }} @@ -64,4 +64,4 @@ jobs: working-directory: build - name: Run tests timeout-minutes: 360 - run: mkdir -p tmp && SKIP_ALGS='${{ matrix.SKIP_ALGS }}' python3 -m pytest --verbose ${{ matrix.PYTEST_ARGS }} + run: mkdir -p tmp && python3 -m pytest --verbose ${{ matrix.PYTEST_ARGS }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d2fb783d..c37061702 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,24 +26,16 @@ them before the final "Review" stage. This project has adopted a slightly modified [Google code formatting style](https://astyle.sourceforge.net/astyle.html#_style=google) for the core components of the library as documented in the [style template](.astylerc). - -To check adherence of any new code to this, it therefore is highly recommended to -run the following command in the project main directory prior to finishing a PR: - - find src tests -name '*.[ch]' | grep -v '/external/' | grep -v 'kem/.*/.*/.*' | grep -v 'sig/.*/.*/.*' | xargs astyle --dry-run --options=.astylerc | grep Format +The `astyle` tool is used to check formatting in CI. +Due to variations in behaviour across version and platforms, it is possible to encounter CI failures even if code has been locally formatted with `astyle`. +To assist with this inconvenience, we provide a convenience script which runs `astyle` in the same Docker image that we use for the CI checks: +```bash +LIBOQS_DIR= ./scripts/format_code.sh +``` +This script has been tested on x86\_64 Ubuntu and arm64 macOS. Contributions for other platforms are welcome and appreciated! ### Running CI locally -#### CircleCI - -If encountering CI errors in CircleCI, it may be helpful to execute the test jobs -locally to debug. This can be facilitated by executing the command - - circleci local execute --job some-test-job - -assuming "some-test-job" is the name of the test to be executed and the CircleCI -[command line tools have been installed](https://circleci.com/docs/local-cli). - #### Github CI [Act](https://github.com/nektos/act) is a tool facilitating local execution of @@ -57,7 +49,7 @@ When installing `act` as a github extension, prefix the commands with `gh `. ### New features Any PR introducing a new feature is expected to contain a test of this feature -and this test should be part of the CI pipeline, preferably using Github CI. +and this test should be part of the CI pipeline. ## Failsafe diff --git a/README.md b/README.md index fc2f3ceef..7a6b6adf1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![CircleCI Build Status](https://circleci.com/gh/open-quantum-safe/liboqs/tree/main.svg?style=shield) ![Build Status](https://img.shields.io/travis/com/open-quantum-safe/liboqs?logo=travis&label=travis%20ci) +![Travis Build Status](https://img.shields.io/travis/com/open-quantum-safe/liboqs?logo=travis&label=travis%20ci) liboqs ====================== diff --git a/scripts/format_code.sh b/scripts/format_code.sh new file mode 100755 index 000000000..e8b617b83 --- /dev/null +++ b/scripts/format_code.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# SPDX-License-Identifier: MIT + +# usage: LIBOQS_DIR= ./scripts/format_code.sh + +arch=$(uname -m) + +# tested on Ubuntu 22 / x86_64 and macOS 13 / arm64 +if [ "$arch" != "x86_64" ] && [ "$arch" != "arm64" ] +then + echo "This script does not currently support systems where \`uname -m\` returns $arch." + exit 1 +fi + +if [ ! -d "$LIBOQS_DIR" ] +then + echo "Please set the environment variable LIBOQS_DIR to point to your liboqs directory." + exit 1 +fi + +docker run --rm -v"$LIBOQS_DIR":/root/liboqs -w /root/liboqs openquantumsafe/ci-ubuntu-focal-$arch:latest ./tests/run_astyle.sh --no-dry-run diff --git a/src/common/common.c b/src/common/common.c index 6688b9b75..f0044fe9b 100644 --- a/src/common/common.c +++ b/src/common/common.c @@ -39,7 +39,7 @@ static pthread_once_t once_control = PTHREAD_ONCE_INIT; #if defined(OQS_DIST_X86_64_BUILD) /* set_available_cpu_extensions_x86_64() has been written using: - * https://github.com/google/cpu_features/blob/master/src/cpuinfo_x86.c + * https://github.com/google/cpu_features/blob/339bfd32be1285877ff517cba8b82ce72e946afd/src/cpuinfo_x86.c */ #include "x86_64_helpers.h" static void set_available_cpu_extensions(void) { @@ -105,11 +105,11 @@ static unsigned int macos_feature_detection(const char *feature_name) { } } static void set_available_cpu_extensions(void) { - /* mark that this function has been called */ cpu_ext_data[OQS_CPU_EXT_ARM_AES] = 1; cpu_ext_data[OQS_CPU_EXT_ARM_SHA2] = 1; cpu_ext_data[OQS_CPU_EXT_ARM_SHA3] = macos_feature_detection("hw.optional.armv8_2_sha3"); cpu_ext_data[OQS_CPU_EXT_ARM_NEON] = macos_feature_detection("hw.optional.neon"); + /* mark that this function has been called */ cpu_ext_data[OQS_CPU_EXT_INIT] = 1; } #elif defined(__FreeBSD__) || defined(__FreeBSD) diff --git a/src/common/common.h b/src/common/common.h index b092baa03..18993d0a5 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -24,12 +24,12 @@ extern "C" { * Macro for terminating the program if x is * a null pointer. */ -#define OQS_EXIT_IF_NULLPTR(x, loc) \ - do { \ - if ( (x) == (void*)0 ) { \ +#define OQS_EXIT_IF_NULLPTR(x, loc) \ + do { \ + if ( (x) == (void*)0 ) { \ fprintf(stderr, "Unexpected NULL returned from %s API. Exiting.\n", loc); \ - exit(EXIT_FAILURE); \ - } \ + exit(EXIT_FAILURE); \ + } \ } while (0) /** @@ -43,13 +43,26 @@ extern "C" { * This is a temporary workaround until a better error * handling strategy is developed. */ -#define OQS_OPENSSL_GUARD(x) \ - do { \ - if( 1 != (x) ) { \ +#ifdef OQS_USE_OPENSSL +#ifdef OPENSSL_NO_STDIO +#define OQS_OPENSSL_GUARD(x) \ + do { \ + if( 1 != (x) ) { \ fprintf(stderr, "Error return value from OpenSSL API: %d. Exiting.\n", x); \ - exit(EXIT_FAILURE); \ - } \ + exit(EXIT_FAILURE); \ + } \ } while (0) +#else // OPENSSL_NO_STDIO +#define OQS_OPENSSL_GUARD(x) \ + do { \ + if( 1 != (x) ) { \ + fprintf(stderr, "Error return value from OpenSSL API: %d. Exiting.\n", x); \ + OSSL_FUNC(ERR_print_errors_fp)(stderr); \ + exit(EXIT_FAILURE); \ + } \ + } while (0) +#endif // OPENSSL_NO_STDIO +#endif // OQS_USE_OPENSSL /** * Certain functions (such as OQS_randombytes_openssl in diff --git a/src/common/rand/rand_nist.c b/src/common/rand/rand_nist.c index 07db63b3b..12407a08d 100644 --- a/src/common/rand/rand_nist.c +++ b/src/common/rand/rand_nist.c @@ -32,20 +32,6 @@ void OQS_randombytes_nist_kat(unsigned char *x, size_t xlen); static OQS_NIST_DRBG_struct DRBG_ctx; static void AES256_CTR_DRBG_Update(unsigned char *provided_data, unsigned char *Key, unsigned char *V); -#ifdef OQS_USE_OPENSSL -# if defined(_MSC_VER) -__declspec(noreturn) -# else -__attribute__((noreturn)) -# endif -static void handleErrors(void) { -#ifndef OPENSSL_NO_STDIO - OSSL_FUNC(ERR_print_errors_fp)(stderr); -#endif - abort(); -} -#endif - // Use whatever AES implementation you have. This uses AES from openSSL library // key - 256-bit AES key // ctr - a 128-bit plaintext value @@ -57,17 +43,11 @@ static void AES256_ECB(unsigned char *key, unsigned char *ctr, unsigned char *bu int len; /* Create and initialise the context */ - if (!(ctx = OSSL_FUNC(EVP_CIPHER_CTX_new)())) { - handleErrors(); - } - - if (1 != OSSL_FUNC(EVP_EncryptInit_ex)(ctx, oqs_aes_256_ecb(), NULL, key, NULL)) { - handleErrors(); - } + ctx = OSSL_FUNC(EVP_CIPHER_CTX_new)(); + OQS_EXIT_IF_NULLPTR(ctx, "OpenSSL"); - if (1 != OSSL_FUNC(EVP_EncryptUpdate)(ctx, buffer, &len, ctr, 16)) { - handleErrors(); - } + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptInit_ex)(ctx, oqs_aes_256_ecb(), NULL, key, NULL)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_EncryptUpdate)(ctx, buffer, &len, ctr, 16)); /* Clean up */ OSSL_FUNC(EVP_CIPHER_CTX_free)(ctx); diff --git a/src/common/sha2/sha2_ossl.c b/src/common/sha2/sha2_ossl.c index 3aff58fab..234d4b1e3 100644 --- a/src/common/sha2/sha2_ossl.c +++ b/src/common/sha2/sha2_ossl.c @@ -18,9 +18,9 @@ static void do_hash(uint8_t *output, const uint8_t *input, size_t inplen, const unsigned int outlen; mdctx = OSSL_FUNC(EVP_MD_CTX_new)(); OQS_EXIT_IF_NULLPTR(mdctx, "OpenSSL"); - OSSL_FUNC(EVP_DigestInit_ex)(mdctx, md, NULL); - OSSL_FUNC(EVP_DigestUpdate)(mdctx, input, inplen); - OSSL_FUNC(EVP_DigestFinal_ex)(mdctx, output, &outlen); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestInit_ex)(mdctx, md, NULL)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestUpdate)(mdctx, input, inplen)); + OQS_OPENSSL_GUARD(OSSL_FUNC(EVP_DigestFinal_ex)(mdctx, output, &outlen)); OSSL_FUNC(EVP_MD_CTX_free)(mdctx); } diff --git a/tests/kat_sig_stfl.c b/tests/kat_sig_stfl.c index 5c99f5d5b..85b089615 100644 --- a/tests/kat_sig_stfl.c +++ b/tests/kat_sig_stfl.c @@ -311,7 +311,10 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { // Echo back remain if (FindMarker(fp_rsp, "remain = ")) { - fscanf(fp_rsp, "%llu", &sigs_remain); + if (EOF == fscanf(fp_rsp, "%llu", &sigs_remain)) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: unable to read 'remain' from <%s>\n", method_name, katfile); + goto err; + }; fprintf(fh, "remain = %llu\n", sigs_remain); } else { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_remaining failed!\n", method_name); @@ -320,7 +323,10 @@ OQS_STATUS sig_stfl_kat(const char *method_name, const char *katfile) { // Echo back max if (FindMarker(fp_rsp, "max = ")) { - fscanf(fp_rsp, "%llu", &sigs_maximum); + if (EOF == fscanf(fp_rsp, "%llu", &sigs_maximum)) { + fprintf(stderr, "[kat_stfl_sig] %s ERROR: unable to read 'max' from <%s>\n", method_name, katfile); + goto err; + }; fprintf(fh, "max = %llu\n", sigs_maximum); } else { fprintf(stderr, "[kat_stfl_sig] %s ERROR: OQS_SIG_STFL_sigs_total failed!\n", method_name); diff --git a/tests/run_astyle.sh b/tests/run_astyle.sh index 53a7414b4..487996a64 100755 --- a/tests/run_astyle.sh +++ b/tests/run_astyle.sh @@ -3,8 +3,14 @@ rv=0 +if [ "$1" = "--no-dry-run" ]; then + dryrun="" +else + dryrun="--dry-run" +fi + # check style of non-external code: -find src tests -name '*.[ch]' | grep -v '/external/' | grep -v 'kem/.*/.*/.*' | grep -v 'sig/.*/.*/.*' | xargs astyle --dry-run --options=.astylerc | grep Format +find src tests -name '*.[ch]' | grep -v '/external/' | grep -v 'kem/.*/.*/.*' | grep -v 'sig/.*/.*/.*' | xargs astyle $dryrun --options=.astylerc | grep Format if [ $? -ne 1 ]; then echo "Error: Some files need reformatting. Check output above." rv=-1 diff --git a/tests/test_kem_vectors.sh b/tests/test_kem_vectors.sh index 0e64ade01..f9e19ba04 100644 --- a/tests/test_kem_vectors.sh +++ b/tests/test_kem_vectors.sh @@ -23,7 +23,7 @@ keygen_sk=$(grep "keygen_dk: " "$file") encaps_c=$(grep "encaps_c: " "$file") encaps_K=$(grep "encaps_K: " "$file") -output=$($build_dir/tests/vectors_kem $1 "$keygen_z$keygen_d$encaps_m" "$encaps_ek" "$encaps_k" "$decaps_dk" "$decaps_c" "$decaps_kprime") +output=$($build_dir/tests/vectors_kem $1 "$keygen_d$keygen_z$encaps_m" "$encaps_ek" "$encaps_k" "$decaps_dk" "$decaps_c" "$decaps_kprime") if [ $? != 0 ]; then echo "$output" exit 1 diff --git a/tests/vectors_kem.c b/tests/vectors_kem.c index 638652928..d7ee657a1 100644 --- a/tests/vectors_kem.c +++ b/tests/vectors_kem.c @@ -222,7 +222,7 @@ int main(int argc, char **argv) { } char *alg_name = argv[1]; - char *prng_output_stream = argv[2]; // z || d || m + char *prng_output_stream = argv[2]; // d || z || m char *encaps_pk = argv[3]; char *encaps_K = argv[4];