diff --git a/.github/actions/bench/action.yml b/.github/actions/bench/action.yml index e028dd7c4..4ca8c67bd 100644 --- a/.github/actions/bench/action.yml +++ b/.github/actions/bench/action.yml @@ -17,6 +17,9 @@ inputs: archflags: description: ARCHFLAGS to pass to compilation default: "" + ldflags: + description: LDFLAGS to pass to compilation + default: "" opt: description: opt flag to set for tests script default: "true" @@ -75,11 +78,13 @@ runs: run: | ./scripts/tests bench -c ${{ inputs.perf }} --cross-prefix="${{ inputs.cross_prefix }}" \ --cflags="${{ inputs.cflags }} ${{ inputs.archflags }}" \ + --ldflags="${{ inputs.ldflags }}" \ --opt=$([[ ${{ inputs.opt }} == "false" ]] && echo "no_opt" || echo "opt") \ -v --output=output.json ${{ inputs.bench_extra_args }} ./scripts/tests bench --components -c ${{ inputs.perf }} --cross-prefix="${{ inputs.cross_prefix }}" \ --cflags="${{ inputs.cflags }} ${{ inputs.archflags }}" \ + --ldflags="${{ inputs.ldflags }}" \ --opt=$([[ ${{ inputs.opt }} == "false" ]] && echo "no_opt" || echo "opt") \ -v ${{ inputs.bench_extra_args }} - name: Check namespace diff --git a/.github/actions/config-variations/action.yml b/.github/actions/config-variations/action.yml index 82a309f57..d27093ae8 100644 --- a/.github/actions/config-variations/action.yml +++ b/.github/actions/config-variations/action.yml @@ -24,6 +24,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-DMLK_CONFIG_KEYGEN_PCT -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -52,6 +53,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/custom_zeroize_config.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -64,6 +66,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/custom_native_capability_config_1.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -76,6 +79,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/custom_native_capability_config_0.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -88,6 +92,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -march=armv8.4-a+sha3 -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/custom_native_capability_config_ID_AA64PFR1_EL1.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -100,6 +105,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -mavx2 -mbmi2 -mpopcnt -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/custom_native_capability_config_CPUID_AVX2.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -112,6 +118,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/no_asm_config.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -124,6 +131,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/custom_randombytes_config.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -136,6 +144,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/custom_memcpy_config.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -148,6 +157,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/custom_memset_config.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -160,6 +170,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-std=c11 -D_GNU_SOURCE -DMLK_CONFIG_FILE=\\\\\\\"../../test/custom_stdlib_config.h\\\\\\\" -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -172,6 +183,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -DMLKEM_GEN_MATRIX_NBLOCKS=1" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -184,6 +196,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -DMLKEM_GEN_MATRIX_NBLOCKS=2" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true @@ -196,6 +209,7 @@ runs: gh_token: ${{ inputs.gh_token }} compile_mode: native cflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -DMLKEM_GEN_MATRIX_NBLOCKS=4" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" func: true kat: true acvp: true diff --git a/.github/actions/functest/action.yml b/.github/actions/functest/action.yml index cf3944238..d6a123dca 100644 --- a/.github/actions/functest/action.yml +++ b/.github/actions/functest/action.yml @@ -22,6 +22,9 @@ inputs: cflags: description: CFLAGS to pass to compilation default: "" + ldflags: + description: LDFLAGS to pass to linking + default: "" cross_prefix: description: Binary prefix for cross compilation default: "" @@ -99,7 +102,7 @@ runs: shell: ${{ env.SHELL }} run: | make clean - ./scripts/tests all ${{ inputs.check_namespace == 'true' && '--check-namespace' || ''}} --exec-wrapper="${{ inputs.exec_wrapper }}" --cross-prefix="${{ inputs.cross_prefix }}" --cflags="${{ inputs.cflags }}" --opt=${{ inputs.opt }} --${{ env.FUNC }} --${{ env.KAT }} --${{ env.ACVP }} --${{ env.EXAMPLES }} --${{ env.STACK }} -v ${{ inputs.extra_args }} + ./scripts/tests all ${{ inputs.check_namespace == 'true' && '--check-namespace' || ''}} --exec-wrapper="${{ inputs.exec_wrapper }}" --cross-prefix="${{ inputs.cross_prefix }}" --cflags="${{ inputs.cflags }}" --ldflags="${{ inputs.ldflags }}" --opt=${{ inputs.opt }} --${{ env.FUNC }} --${{ env.KAT }} --${{ env.ACVP }} --${{ env.EXAMPLES }} --${{ env.STACK }} -v ${{ inputs.extra_args }} - name: Post ${{ env.MODE }} Tests shell: ${{ env.SHELL }} if: success() || failure() diff --git a/.github/actions/multi-functest/action.yml b/.github/actions/multi-functest/action.yml index 252931918..bc520feb9 100644 --- a/.github/actions/multi-functest/action.yml +++ b/.github/actions/multi-functest/action.yml @@ -22,6 +22,9 @@ inputs: cflags: description: CFLAGS to pass to compilation default: "" + ldflags: + description: LDFLAGS to pass to linking + default: "" compile_mode: description: all | native | cross-x86_64 | cross-aarch64 | cross-riscv64 | cross-riscv32 default: "native" @@ -62,6 +65,7 @@ runs: gh_token: ${{ inputs.gh_token }} custom_shell: ${{ inputs.custom_shell }} cflags: ${{ inputs.cflags }} + ldflags: ${{ inputs.ldflags }} opt: ${{ inputs.opt }} func: ${{ inputs.func }} kat: ${{ inputs.kat }} @@ -80,6 +84,7 @@ runs: gh_token: ${{ inputs.gh_token }} custom_shell: ${{ inputs.custom_shell }} cflags: "${{ inputs.cflags }} -DMLK_FORCE_X86_64" + ldflags: ${{ inputs.ldflags }} cross_prefix: x86_64-unknown-linux-gnu- exec_wrapper: qemu-x86_64 opt: ${{ inputs.opt }} @@ -100,6 +105,7 @@ runs: gh_token: ${{ inputs.gh_token }} custom_shell: ${{ inputs.custom_shell }} cflags: "${{ inputs.cflags }} -DMLK_FORCE_AARCH64" + ldflags: ${{ inputs.ldflags }} cross_prefix: aarch64-unknown-linux-gnu- exec_wrapper: qemu-aarch64 opt: ${{ inputs.opt }} @@ -120,6 +126,7 @@ runs: gh_token: ${{ inputs.gh_token }} custom_shell: ${{ inputs.custom_shell }} cflags: "${{ inputs.cflags }} -DMLK_FORCE_PPC64LE" + ldflags: ${{ inputs.ldflags }} cross_prefix: powerpc64le-unknown-linux-gnu- exec_wrapper: qemu-ppc64le opt: ${{ inputs.opt }} @@ -140,6 +147,7 @@ runs: gh_token: ${{ inputs.gh_token }} custom_shell: ${{ inputs.custom_shell }} cflags: "${{ inputs.cflags }} -static -DMLK_FORCE_AARCH64_EB" + ldflags: "${{ inputs.ldflags }} -static" cross_prefix: aarch64_be-none-linux-gnu- exec_wrapper: qemu-aarch64_be opt: ${{ inputs.opt }} @@ -160,6 +168,7 @@ runs: gh_token: ${{ inputs.gh_token }} custom_shell: ${{ inputs.custom_shell }} cflags: "${{ inputs.cflags }} -DMLK_FORCE_RISCV64" + ldflags: ${{ inputs.ldflags }} cross_prefix: riscv64-unknown-linux-gnu- exec_wrapper: qemu-riscv64 opt: ${{ inputs.opt }} @@ -180,6 +189,7 @@ runs: gh_token: ${{ inputs.gh_token }} custom_shell: ${{ inputs.custom_shell }} cflags: "${{ inputs.cflags }} -DMLK_FORCE_RISCV32" + ldflags: ${{ inputs.ldflags }} cross_prefix: riscv32-unknown-linux-gnu- exec_wrapper: qemu-riscv32 opt: ${{ inputs.opt }} diff --git a/.github/workflows/all.yml b/.github/workflows/all.yml index 86b002775..e7510b656 100644 --- a/.github/workflows/all.yml +++ b/.github/workflows/all.yml @@ -87,3 +87,11 @@ jobs: needs: [ base, nix ] uses: ./.github/workflows/slothy.yml secrets: inherit + baremetal: + name: Baremetal + permissions: + contents: 'read' + id-token: 'write' + needs: [ base ] + uses: ./.github/workflows/baremetal.yml + secrets: inherit diff --git a/.github/workflows/baremetal.yml b/.github/workflows/baremetal.yml new file mode 100644 index 000000000..23dab64f8 --- /dev/null +++ b/.github/workflows/baremetal.yml @@ -0,0 +1,38 @@ +# Copyright (c) The mldsa-native project authors +# Copyright (c) The mlkem-native project authors +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +name: Baremetal +permissions: + contents: read +on: + workflow_call: + workflow_dispatch: + +jobs: + baremetal_tests: + name: Baremetal tests (${{ matrix.target.name }}) + strategy: + fail-fast: false + matrix: + target: + - runner: ubuntu-latest + name: 'M55-AN547' + makefile: test/baremetal/platform/m55-an547/platform.mk + nix-shell: arm-embedded + runs-on: ${{ matrix.target.runner }} + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - name: baremetal build + test + uses: ./.github/actions/functest + env: + EXTRA_MAKEFILE: ${{ matrix.target.makefile }} + with: + nix-shell: ${{ matrix.target.nix-shell }} + gh_token: ${{ secrets.GITHUB_TOKEN }} + opt: no_opt + func: true + kat: true + acvp: true + examples: false + stack: false diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 3571f46c4..4d379e021 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -32,6 +32,7 @@ jobs: bench_pmu: PMU archflags: -mcpu=cortex-a72 -DMLK_SYS_AARCH64_SLOW_BARREL_SHIFTER cflags: "-flto -DMLK_FORCE_AARCH64" + ldflags: "-flto" bench_extra_args: "" nix_shell: ci-bench - system: rpi5 @@ -39,20 +40,23 @@ jobs: bench_pmu: PERF archflags: "-mcpu=cortex-a76 -march=armv8.2-a" cflags: "-flto -DMLK_FORCE_AARCH64" + ldflags: "-flto" bench_extra_args: "" nix_shell: ci-bench - system: a55 name: Arm Cortex-A55 (Snapdragon 888) benchmarks bench_pmu: PERF archflags: "-mcpu=cortex-a55 -march=armv8.2-a" - cflags: "-flto -static -DMLK_FORCE_AARCH64 -DMLK_CONFIG_FIPS202_BACKEND_FILE=\\\\\\\"fips202/native/aarch64/x1_scalar.h\\\\\\\"" + cflags: "-flto -DMLK_FORCE_AARCH64 -DMLK_CONFIG_FIPS202_BACKEND_FILE=\\\\\\\"fips202/native/aarch64/x1_scalar.h\\\\\\\"" + ldflags: "-flto -static" bench_extra_args: -w exec-on-a55 nix_shell: ci-bench - system: bpi name: SpacemiT K1 8 (Banana Pi F3) benchmarks bench_pmu: PERF archflags: "-march=rv64imafdcv_zicsr_zifencei" - cflags: "-static" + cflags: "" + ldflags: "-static" bench_extra_args: -w exec-on-bpi cross_prefix: riscv64-unknown-linux-gnu- nix_shell: ci-cross-riscv64 @@ -61,6 +65,7 @@ jobs: bench_pmu: MAC archflags: "-mcpu=apple-m1 -march=armv8.4-a+sha3" cflags: "-flto" + ldflags: "-flto" bench_extra_args: "-r" nix_shell: ci-bench if: github.repository_owner == 'pq-code-package' && (github.event.label.name == 'benchmark' || github.ref == 'refs/heads/main') @@ -72,6 +77,7 @@ jobs: name: ${{ matrix.target.name }} cflags: ${{ matrix.target.cflags }} archflags: ${{ matrix.target.archflags }} + ldflags: ${{ matrix.target.ldflags }} perf: ${{ matrix.target.bench_pmu }} store_results: ${{ github.repository_owner == 'pq-code-package' && github.ref == 'refs/heads/main' }} bench_extra_args: ${{ matrix.target.bench_extra_args }} @@ -94,42 +100,49 @@ jobs: ec2_ami: ubuntu-latest (aarch64) archflags: -mcpu=cortex-a76 -march=armv8.2-a cflags: "-flto -DMLK_FORCE_AARCH64" + ldflags: "-flto" perf: PERF - name: Graviton3 ec2_instance_type: c7g.medium ec2_ami: ubuntu-latest (aarch64) archflags: -march=armv8.4-a+sha3 cflags: "-flto -DMLK_FORCE_AARCH64" + ldflags: "-flto" perf: PERF - name: Graviton4 ec2_instance_type: c8g.medium ec2_ami: ubuntu-latest (aarch64) archflags: -march=armv9-a+sha3 cflags: "-flto -DMLK_FORCE_AARCH64" + ldflags: "-flto" perf: PERF - name: AMD EPYC 4th gen (c7a) ec2_instance_type: c7a.medium ec2_ami: ubuntu-latest (x86_64) archflags: -mavx2 -mbmi2 -mpopcnt -march=znver4 cflags: "-flto -DMLK_FORCE_X86_64" + ldflags: "-flto" perf: PMU - name: Intel Xeon 4th gen (c7i) ec2_instance_type: c7i.metal-24xl ec2_ami: ubuntu-latest (x86_64) archflags: -mavx2 -mbmi2 -mpopcnt -march=sapphirerapids cflags: "-flto -DMLK_FORCE_X86_64" + ldflags: "-flto" perf: PMU - name: AMD EPYC 3rd gen (c6a) ec2_instance_type: c6a.large ec2_ami: ubuntu-latest (x86_64) archflags: -mavx2 -mbmi2 -mpopcnt -march=znver3 cflags: "-flto -DMLK_FORCE_X86_64" + ldflags: "-flto" perf: PMU - name: Intel Xeon 3rd gen (c6i) ec2_instance_type: c6i.large ec2_ami: ubuntu-latest (x86_64) archflags: -mavx2 -mbmi2 -mpopcnt -march=icelake-server cflags: "-flto -DMLK_FORCE_X86_64" + ldflags: "-flto" perf: PMU uses: ./.github/workflows/bench_ec2_reusable.yml if: github.repository_owner == 'pq-code-package' && (github.event.label.name == 'benchmark' || github.ref == 'refs/heads/main') @@ -138,6 +151,7 @@ jobs: ec2_ami: ${{ matrix.target.ec2_ami }} archflags: ${{ matrix.target.archflags }} cflags: ${{ matrix.target.cflags }} + ldflags: ${{ matrix.target.ldflags }} opt: "all" store_results: ${{ github.repository_owner == 'pq-code-package' && github.ref == 'refs/heads/main' }} # Only store optimized results name: ${{ matrix.target.name }} diff --git a/.github/workflows/bench_ec2_any.yml b/.github/workflows/bench_ec2_any.yml index 63312e8df..a9b7bba80 100644 --- a/.github/workflows/bench_ec2_any.yml +++ b/.github/workflows/bench_ec2_any.yml @@ -30,6 +30,9 @@ on: archflags: description: Custom ARCH flags for compilation default: '' + ldflags: + description: Custom LDFLAGS for linking + default: '' opt: description: Benchmark optimized, non-optimized, or both type: choice @@ -43,9 +46,6 @@ on: compiler: description: Compiler to use. When unset, default nix shell is used. default: '' - additional_packages: - description: Additional packages to install when custom compiler is used. - default: '' jobs: bench-ec2-any: name: Ad-hoc benchmark on $${{ inputs.ec2_instance_type }} @@ -58,11 +58,11 @@ jobs: ec2_ami: ${{ inputs.ec2_ami }} ec2_ami_id: ${{ inputs.ec2_ami_id }} cflags: ${{ inputs.cflags }} + ldflags: ${{ inputs.ldflags }} archflags: ${{ inputs.archflags }} opt: ${{ inputs.opt }} name: ${{ inputs.name }} store_results: false bench_extra_args: ${{ inputs.bench_extra_args }} compiler: ${{ inputs.compiler }} - additional_packages: ${{ inputs.additional_packages }} secrets: inherit diff --git a/.github/workflows/bench_ec2_reusable.yml b/.github/workflows/bench_ec2_reusable.yml index 855a19440..257e15a4e 100644 --- a/.github/workflows/bench_ec2_reusable.yml +++ b/.github/workflows/bench_ec2_reusable.yml @@ -28,6 +28,10 @@ on: type: string description: Custom ARCH flags for compilation default: -mcpu=neoverse-n1 -march=armv8.2-a + ldflags: + type: string + description: Custom LDFLAGS for linking + default: "" opt: type: string description: Runs with optimized code if enabled (opt, no_opt, all) @@ -131,6 +135,7 @@ jobs: name: ${{ inputs.name }} cflags: ${{ inputs.cflags }} archflags: ${{ inputs.archflags }} + ldflags: ${{ inputs.ldflags }} opt: true perf: ${{ inputs.perf }} store_results: ${{ inputs.store_results }} @@ -143,6 +148,7 @@ jobs: name: ${{ inputs.name }} (no-opt) cflags: ${{ inputs.cflags }} archflags: ${{ inputs.archflags }} + ldflags: ${{ inputs.ldflags }} opt: false perf: ${{ inputs.perf }} store_results: ${{ inputs.store_results }} @@ -175,6 +181,7 @@ jobs: name: ${{ inputs.name }} (${{ inputs.compiler }}) cflags: ${{ inputs.cflags }} archflags: ${{ inputs.archflags }} + ldflags: ${{ inputs.ldflags }} opt: true perf: ${{ inputs.perf }} store_results: ${{ inputs.store_results }} @@ -190,6 +197,7 @@ jobs: name: ${{ inputs.name }} (${{ inputs.compiler }}) (no-opt) cflags: ${{ inputs.cflags }} archflags: ${{ inputs.archflags }} + ldflags: ${{ inputs.ldflags }} opt: false perf: ${{ inputs.perf }} store_results: ${{ inputs.store_results }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92c25ff06..bca8c267c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -150,6 +150,7 @@ jobs: gh_token: ${{ secrets.GITHUB_TOKEN }} compile_mode: native cflags: "-DMLKEM_DEBUG -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" check_namespace: 'false' backend_tests: name: AArch64 FIPS202 backends (${{ matrix.backend }}) @@ -170,6 +171,7 @@ jobs: opt: 'opt' examples: 'false' cflags: "-DMLKEM_DEBUG -fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" + ldflags: "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all" check_namespace: 'false' extra_args: "--fips202-aarch64-backend ${{ matrix.backend }}" compiler_tests: diff --git a/Makefile b/Makefile index bec1a9c9f..30e5913c6 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,11 @@ SHELL := /bin/bash all: build +# Extra Makefile to include, e.g., for baremetal targets +ifneq ($(EXTRA_MAKEFILE),) +include $(EXTRA_MAKEFILE) +endif + W := $(EXEC_WRAPPER) include test/mk/config.mk @@ -71,7 +76,7 @@ run_unit_1024: unit_1024 run_unit: run_unit_512 run_unit_768 run_unit_1024 run_acvp: acvp - python3 ./test/acvp_client.py $(if $(ACVP_VERSION),--version $(ACVP_VERSION)) + EXEC_WRAPPER="$(EXEC_WRAPPER)" python3 ./test/acvp_client.py $(if $(ACVP_VERSION),--version $(ACVP_VERSION)) func_512: $(MLKEM512_DIR)/bin/test_mlkem512 $(Q)echo " FUNC ML-KEM-512: $^" diff --git a/flake.nix b/flake.nix index b9ba94eed..c6638800c 100644 --- a/flake.nix +++ b/flake.nix @@ -82,6 +82,15 @@ } ++ pkgs.lib.optionals (!pkgs.stdenv.isDarwin) [ config.packages.valgrind_varlat ]; }; + # arm-none-eabi-gcc + platform files from pqmx + packages.m55-an547 = util.m55-an547; + devShells.arm-embedded = util.mkShell { + packages = builtins.attrValues + { + inherit (config.packages) m55-an547; + inherit (pkgs) gcc-arm-embedded qemu coreutils python3 git; + }; + }; devShells.hol_light = util.mkShell { packages = builtins.attrValues { inherit (config.packages) linters hol_light s2n_bignum; diff --git a/nix/m55-an547-arm-none-eabi/default.nix b/nix/m55-an547-arm-none-eabi/default.nix new file mode 100644 index 000000000..0bbb9ee2b --- /dev/null +++ b/nix/m55-an547-arm-none-eabi/default.nix @@ -0,0 +1,39 @@ +# Copyright (c) The mldsa-native project authors +# Copyright (c) The mlkem-native project authors +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +{ stdenvNoCC +, fetchFromGitHub +, writeText +}: + +stdenvNoCC.mkDerivation { + pname = "mlkem-native-m55-an547"; + version = "main-2025-10-02"; + + + # Fetch platform files from pqmx (envs/m55-an547) + src = fetchFromGitHub { + owner = "slothy-optimizer"; + repo = "pqmx"; + rev = "4ed493d3cf2af62a08fd9fe36c3472a0dc50ad9f"; + hash = "sha256-jLIqwknjRwcoDeEAETlMhRqZQ5a3QGCDZX9DENelGeQ="; + }; + + dontBuild = true; + + installPhase = '' + mkdir -p $out/platform/m55-an547/src/platform/ + cp -r envs/m55-an547/src/platform/. $out/platform/m55-an547/src/platform/ + cp integration/*.c $out/platform/m55-an547/src/platform/ + ''; + + setupHook = writeText "setup-hook.sh" '' + export M55_AN547_PATH="$1/platform/m55-an547/src/platform/" + ''; + + meta = { + description = "Platform files for the Cortex-M55 (AN547)"; + homepage = "https://github.com/slothy-optimizer/pqmx"; + }; +} diff --git a/nix/util.nix b/nix/util.nix index be3544789..461911c36 100644 --- a/nix/util.nix +++ b/nix/util.nix @@ -28,6 +28,7 @@ rec { riscv64-gcc = wrap-gcc pkgs.pkgsCross.riscv64; riscv32-gcc = wrap-gcc pkgs.pkgsCross.riscv32; ppc64le-gcc = wrap-gcc pkgs.pkgsCross.powernv; + arm-embedded-gcc = wrap-gcc pkgs.armToolchain; aarch64_be-gcc = (pkgs.callPackage ./aarch64_be-none-linux-gnu-gcc.nix { }); in # NOTE: @@ -100,6 +101,7 @@ rec { hol_light' = pkgs.callPackage ./hol_light { }; s2n_bignum = pkgs.callPackage ./s2n_bignum { }; slothy = pkgs.callPackage ./slothy { }; + m55-an547 = pkgs.callPackage ./m55-an547-arm-none-eabi { }; # Helper function to build individual cross toolchains _individual_toolchain = { name, cross_compilers }: diff --git a/scripts/tests b/scripts/tests index e6362a65c..7c8189e82 100755 --- a/scripts/tests +++ b/scripts/tests @@ -436,6 +436,9 @@ class Tests: cflags = self.args.cflags if cflags is None: cflags = "" + ldflags = self.args.ldflags + if ldflags is None: + ldflags = "" if test_type.is_example() and self.args.cross_prefix != "": cflags += " -static" @@ -455,6 +458,8 @@ class Tests: env_update = {} if cflags != "": env_update["CFLAGS"] = cflags + if ldflags != "": + env_update["LDFLAGS"] = ldflags if self.args.cross_prefix != "": env_update["CROSS_PREFIX"] = self.args.cross_prefix @@ -984,6 +989,9 @@ def cli(): common_parser.add_argument( "--cflags", help="Extra cflags to passed in (e.g. '-mcpu=cortex-a72')" ) + common_parser.add_argument( + "--ldflags", help="Extra ldflags to passed in (e.g. '-static')" + ) common_parser.add_argument( "-j", help="Number of jobs to be used for `make` invocations", diff --git a/test/baremetal/platform/m55-an547/exec_wrapper.py b/test/baremetal/platform/m55-an547/exec_wrapper.py new file mode 100755 index 000000000..940fa0f47 --- /dev/null +++ b/test/baremetal/platform/m55-an547/exec_wrapper.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# Copyright (c) The mldsa-native project authors +# Copyright (c) The mlkem-native project authors +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +import struct as st +import sys +import subprocess +import tempfile +import os + + +def err(msg, **kwargs): + print(msg, file=sys.stderr, **kwargs) + + +binpath = sys.argv[1] +args = sys.argv[1:] +cmdline_offset = 0x70000 + +arg0_offset = cmdline_offset + 4 + len(args) * 4 + +arg_offsets = [sum(map(len, args[:i])) + i + arg0_offset for i in range(len(args))] + +binargs = st.pack( + f"<{1+len(args)}I" + "".join(f"{len(a)+1}s" for a in args), + len(args), + *arg_offsets, + *map(lambda x: x.encode("utf-8"), args), +) + +with tempfile.NamedTemporaryFile(mode="wb", delete=False, suffix=".bin") as fd: + args_file = fd.name + fd.write(binargs) + +try: + qemu_cmd = f"qemu-system-arm -M mps3-an547 -nographic -semihosting -kernel {binpath} -device loader,file={args_file},addr=0x{cmdline_offset:x}".split() + result = subprocess.run(qemu_cmd, encoding="utf-8", capture_output=True) +finally: + os.unlink(args_file) +if result.returncode != 0: + err("FAIL!") + err(f"{qemu_cmd} failed with error code {result.returncode}") + err(result.stderr) + exit(1) + +for line in result.stdout.splitlines(): + print(line) diff --git a/test/baremetal/platform/m55-an547/platform.mk b/test/baremetal/platform/m55-an547/platform.mk new file mode 100644 index 000000000..6938e0b25 --- /dev/null +++ b/test/baremetal/platform/m55-an547/platform.mk @@ -0,0 +1,62 @@ +# Copyright (c) The mldsa-native project authors +# Copyright (c) The mlkem-native project authors +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +PLATFORM_PATH:=test/baremetal/platform/m55-an547 + +CROSS_PREFIX=arm-none-eabi- +CC=gcc + +CFLAGS += \ + -O3 \ + -Wall -Wextra -Wshadow \ + -Wno-pedantic \ + -Wno-redundant-decls \ + -Wno-missing-prototypes \ + -fno-common \ + -ffunction-sections \ + -fdata-sections \ + --sysroot=$(SYSROOT) \ + -DDEVICE=an547 \ + -I$(M55_AN547_PATH) \ + -DARMCM55 \ + -DSEMIHOSTING + +ARCH_FLAGS += \ + -march=armv8.1-m.main+mve.fp \ + -mcpu=cortex-m55 \ + -mthumb \ + -mfloat-abi=hard -mfpu=fpv4-sp-d16 + +CFLAGS += \ + $(ARCH_FLAGS) \ + --specs=nosys.specs + +CFLAGS += $(CFLAGS_EXTRA) + +LDSCRIPT = $(M55_AN547_PATH)/mps3.ld + +LDFLAGS += \ + -Wl,--gc-sections \ + -Wl,--no-warn-rwx-segments \ + -L. + +LDFLAGS += \ + --specs=nosys.specs \ + -Wl,--wrap=_open \ + -Wl,--wrap=_close \ + -Wl,--wrap=_read \ + -Wl,--wrap=_write \ + -Wl,--wrap=_fstat \ + -Wl,--wrap=_getpid \ + -Wl,--wrap=_isatty \ + -Wl,--wrap=_kill \ + -Wl,--wrap=_lseek \ + -Wl,--wrap=main \ + -ffreestanding \ + -T$(LDSCRIPT) \ + $(ARCH_FLAGS) + +# Extra sources to be included in test binaries +EXTRA_SOURCES = $(wildcard $(M55_AN547_PATH)/*.c) +EXEC_WRAPPER := $(realpath $(PLATFORM_PATH)/exec_wrapper.py) diff --git a/test/mk/components.mk b/test/mk/components.mk index cdcc3eb5d..bda0f3356 100644 --- a/test/mk/components.mk +++ b/test/mk/components.mk @@ -99,6 +99,6 @@ $(foreach scheme,mlkem512 mlkem768 mlkem1024, \ $(eval $(call ADD_SOURCE_UNIT,$(scheme))) \ ) -$(ALL_TESTS:%=$(MLKEM512_DIR)/bin/%512): $(call MAKE_OBJS, $(MLKEM512_DIR), $(wildcard test/notrandombytes/*.c)) -$(ALL_TESTS:%=$(MLKEM768_DIR)/bin/%768): $(call MAKE_OBJS, $(MLKEM768_DIR), $(wildcard test/notrandombytes/*.c)) -$(ALL_TESTS:%=$(MLKEM1024_DIR)/bin/%1024): $(call MAKE_OBJS, $(MLKEM1024_DIR), $(wildcard test/notrandombytes/*.c)) +$(ALL_TESTS:%=$(MLKEM512_DIR)/bin/%512): $(call MAKE_OBJS, $(MLKEM512_DIR), $(wildcard test/notrandombytes/*.c) $(EXTRA_SOURCES)) +$(ALL_TESTS:%=$(MLKEM768_DIR)/bin/%768): $(call MAKE_OBJS, $(MLKEM768_DIR), $(wildcard test/notrandombytes/*.c) $(EXTRA_SOURCES)) +$(ALL_TESTS:%=$(MLKEM1024_DIR)/bin/%1024): $(call MAKE_OBJS, $(MLKEM1024_DIR), $(wildcard test/notrandombytes/*.c) $(EXTRA_SOURCES)) diff --git a/test/mk/config.mk b/test/mk/config.mk index 832e89608..b7c25d8d8 100644 --- a/test/mk/config.mk +++ b/test/mk/config.mk @@ -76,7 +76,14 @@ endif # Include retained variables # ############################## + +# Force AUTO=0 when cross-compiling to avoid host architecture detection +ifneq ($(CROSS_PREFIX),) +override AUTO:=0 +else AUTO ?= 1 +endif + CYCLES ?= OPT ?= 1 RETAINED_VARS := CROSS_PREFIX CYCLES OPT AUTO diff --git a/test/mk/rules.mk b/test/mk/rules.mk index 81f3e8e50..a414221da 100644 --- a/test/mk/rules.mk +++ b/test/mk/rules.mk @@ -3,17 +3,17 @@ $(BUILD_DIR)/mlkem512/bin/%: $(CONFIG) $(Q)echo " LD $@" $(Q)[ -d $(@D) ] || mkdir -p $(@D) - $(Q)$(LD) $(CFLAGS) -o $@ $(filter %.o,$^) $(LDLIBS) + $(Q)$(LD) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LDLIBS) $(BUILD_DIR)/mlkem768/bin/%: $(CONFIG) $(Q)echo " LD $@" $(Q)[ -d $(@D) ] || mkdir -p $(@D) - $(Q)$(LD) $(CFLAGS) -o $@ $(filter %.o,$^) $(LDLIBS) + $(Q)$(LD) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LDLIBS) $(BUILD_DIR)/mlkem1024/bin/%: $(CONFIG) $(Q)echo " LD $@" $(Q)[ -d $(@D) ] || mkdir -p $(@D) - $(Q)$(LD) $(CFLAGS) -o $@ $(filter %.o,$^) $(LDLIBS) + $(Q)$(LD) $(LDFLAGS) -o $@ $(filter %.o,$^) $(LDLIBS) $(BUILD_DIR)/%.a: $(CONFIG) $(Q)echo " AR $@"