diff --git a/.github/actions/setup-yum/action.yml b/.github/actions/setup-yum/action.yml new file mode 100644 index 000000000..f5a793c89 --- /dev/null +++ b/.github/actions/setup-yum/action.yml @@ -0,0 +1,28 @@ +# Copyright (c) The mlkem-native project authors +# Copyright (c) The mldsa-native project authors +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +name: Dependencies (yum) +description: Install dependencies via yum + +inputs: + packages: + description: Space-separated list of additional packages to install + required: false + default: '' + sudo: + required: false + default: 'sudo' + +runs: + using: composite + steps: + - name: Install base packages + shell: bash + run: | + ${{ inputs.sudo }} yum install make gcc python3 git -y + - name: Install additional packages + if: ${{ inputs.packages != ''}} + shell: bash + run: | + ${{ inputs.sudo }} yum install ${{ inputs.packages }} -y diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7403cd91..5c2615554 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -612,6 +612,92 @@ jobs: nix-shell: "" custom_shell: ${{ matrix.container.nix_shell && format('{0} --run \"bash -e {{0}}\"', matrix.container.nix_shell) || 'bash' }} gh_token: ${{ secrets.GITHUB_TOKEN }} + ec2_compatibilitytests: + strategy: + max-parallel: 8 + fail-fast: false + matrix: + container: + - id: amazonlinux-2-aarch:base + # TODO: Python 3.7 on Amazon Linux 2 lacks `sha512_224` in hashlib; set to false to skip acvp. + quickcheck: false + acvptest: false + - id: amazonlinux-2-aarch:gcc-7x + # TODO: Python 3.7 on Amazon Linux 2 lacks `sha512_224` in hashlib; set to false to skip acvp. + quickcheck: false + acvptest: false + - id: amazonlinux-2-aarch:clang-7x + # TODO: Python 3.7 on Amazon Linux 2 lacks `sha512_224` in hashlib; set to false to skip acvp. + quickcheck: false + acvptest: false + - id: amazonlinux-2023-aarch:base + quickcheck: true + acvptest: true + - id: amazonlinux-2023-aarch:gcc-11x + quickcheck: true + acvptest: true + - id: amazonlinux-2023-aarch:clang-15x + quickcheck: true + acvptest: true + - id: amazonlinux-2023-aarch:clang-15x-sanitizer + quickcheck: true + acvptest: true + # - id: amazonlinux-2023-aarch:cryptofuzz Not yet supported + - id: ubuntu-22.04-aarch:gcc-12x + quickcheck: true + acvptest: true + - id: ubuntu-22.04-aarch:gcc-11x + quickcheck: true + acvptest: true + - id: ubuntu-20.04-aarch:gcc-8x + quickcheck: true + acvptest: true + - id: ubuntu-20.04-aarch:gcc-7x + quickcheck: true + acvptest: true + - id: ubuntu-20.04-aarch:clang-9x + quickcheck: true + acvptest: true + - id: ubuntu-20.04-aarch:clang-8x + quickcheck: true + acvptest: true + - id: ubuntu-20.04-aarch:clang-7x-bm-framework + quickcheck: true + acvptest: true + - id: ubuntu-20.04-aarch:clang-7x + quickcheck: true + acvptest: true + - id: ubuntu-20.04-aarch:clang-10x + quickcheck: true + acvptest: true + - id: ubuntu-22.04-aarch:base + quickcheck: true + acvptest: true + - id: ubuntu-20.04-aarch:base + quickcheck: true + acvptest: true + name: Compatibility tests (${{ matrix.container.id }}) + permissions: + contents: 'read' + id-token: 'write' + uses: ./.github/workflows/ci_ec2_container.yml + if: github.repository_owner == 'pq-code-package' && !github.event.pull_request.head.repo.fork + with: + container: ${{ matrix.container.id }} + name: ${{ matrix.container.id }} + ec2_instance_type: t4g.small + ec2_ami: ubuntu-latest (custom AMI) + ec2_ami_id: ami-0c9bc1901ef0d1066 # Has docker images preinstalled + compile_mode: native + opt: all + functest: true + kattest: true + acvptest: ${{ matrix.container.acvptest }} + quickcheck: ${{ matrix.container.quickcheck }} + lint: false + verbose: true + cflags: "-O0" + secrets: inherit check_autogenerated_files: strategy: fail-fast: false diff --git a/.github/workflows/ci_ec2_container.yml b/.github/workflows/ci_ec2_container.yml new file mode 100644 index 000000000..94257efc5 --- /dev/null +++ b/.github/workflows/ci_ec2_container.yml @@ -0,0 +1,213 @@ +# Copyright (c) The mlkem-native project authors +# Copyright (c) The mldsa-native project authors +# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT + +name: ci-ec2-reusable +permissions: + contents: read +on: + workflow_call: + inputs: + name: + type: string + description: Alternative name of instance + default: Graviton2 + ec2_instance_type: + type: string + description: Type if EC2 instance to benchmark on + default: t4g.small + ec2_ami: + type: string + description: Textual description of AMI + default: ubuntu-latest (aarch64) + ec2_ami_id: + type: string + description: AMI ID + default: ami-0e8c824f386e1de06 + cflags: + type: string + description: Custom CFLAGS for compilation + default: "" + verbose: + description: Determine for the log verbosity + type: boolean + default: false + compile_mode: + type: string + description: either all, native, cross or none + default: all + opt: + type: string + description: either all, opt or no_opt + default: all + functest: + type: boolean + default: true + kattest: + type: boolean + default: true + acvptest: + type: boolean + default: true + quickcheck: + type: boolean + default: true + lint: + type: boolean + default: true + cbmc: + type: boolean + default: false + cbmc_mldsa_parameter_set: + type: string + default: 44 + container: + type: string + default: '' +env: + AWS_ROLE: arn:aws:iam::559050233797:role/mlkem-c-aarch64-gh-action + AWS_REGION: us-east-1 + AMI_UBUNTU_LATEST_X86_64: ami-0e86e20dae9224db8 + AMI_UBUNTU_LATEST_AARCH64: ami-096ea6a12ea24a797 +jobs: + start-ec2-runner: + name: Start instance (${{ inputs.ec2_instance_type }}) + permissions: + contents: 'read' + id-token: 'write' + runs-on: ubuntu-latest + if: ${{ always() }} # The point is to make this step non-cancellable, + # avoiding race conditions where an instance is started, + # but isn't yet done registering as a runner and reporting back. + outputs: + label: ${{ steps.remember-runner.outputs.label }} + ec2-instance-id: ${{ steps.remember-runner.outputs.ec2-instance-id }} + steps: + - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - name: Determine AMI ID + id: det_ami_id + run: | + if [[ "${{ inputs.ec2_ami }}" == "ubuntu-latest (x86_64)" ]]; then + AMI_ID=${{ env.AMI_UBUNTU_LATEST_X86_64 }} + elif [[ "${{ inputs.ec2_ami }}" == "ubuntu-latest (aarch64)" ]]; then + AMI_ID=${{ env.AMI_UBUNTU_LATEST_AARCH64 }} + elif [[ "${{ inputs.ec2_ami }}" == "ubuntu-latest (custom AMI)" ]]; then + AMI_ID=${{ inputs.ec2_ami_id }} + fi + echo "Using AMI ID: $AMI_ID" + echo "AMI_ID=$AMI_ID" >> $GITHUB_OUTPUT + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + with: + role-to-assume: ${{ env.AWS_ROLE }} + aws-region: ${{ env.AWS_REGION }} + - name: Start EC2 runner + id: start-ec2-runner-first + continue-on-error: true + uses: machulav/ec2-github-runner@a6dbcefcf8a31a861f5e078bb153ed332130c512 # v2.4.3 + with: + mode: start + github-token: ${{ secrets.AWS_GITHUB_TOKEN }} + ec2-image-id: ${{ steps.det_ami_id.outputs.AMI_ID }} + ec2-instance-type: ${{ inputs.ec2_instance_type }} + subnet-id: subnet-07b2729e5e065962f + security-group-id: sg-0ab2e297196c8c381 + - name: Start EC2 runner (wait before retry) + if: steps.start-ec2-runner-first.outcome == 'failure' + shell: bash + run: | + sleep 30 # Wait 30s before retrying + sleep $((1 + RANDOM % 30)) + - name: Start EC2 runner (retry) + id: start-ec2-runner-second + if: steps.start-ec2-runner-first.outcome == 'failure' + uses: machulav/ec2-github-runner@a6dbcefcf8a31a861f5e078bb153ed332130c512 # v2.4.3 + with: + mode: start + github-token: ${{ secrets.AWS_GITHUB_TOKEN }} + ec2-image-id: ${{ steps.det_ami_id.outputs.AMI_ID }} + ec2-instance-type: ${{ inputs.ec2_instance_type }} + subnet-id: subnet-07b2729e5e065962f + security-group-id: sg-0ab2e297196c8c381 + - name: Remember runner + id: remember-runner + shell: bash + run: | + if [[ "${{ steps.start-ec2-runner-first.outcome }}" == "failure" ]]; then + echo "label=${{ steps.start-ec2-runner-second.outputs.label }}" >> "$GITHUB_OUTPUT" + echo "ec2-instance-id=${{ steps.start-ec2-runner-second.outputs.ec2-instance-id }}" >> "$GITHUB_OUTPUT" + else + echo "label=${{ steps.start-ec2-runner-first.outputs.label }}" >> "$GITHUB_OUTPUT" + echo "ec2-instance-id=${{ steps.start-ec2-runner-first.outputs.ec2-instance-id }}" >> "$GITHUB_OUTPUT" + fi + + tests: + name: Run tests + needs: start-ec2-runner + if: ${{ inputs.container != '' }} + runs-on: ${{ needs.start-ec2-runner.outputs.label }} + container: + localhost:5000/${{ inputs.container }} + steps: + # We're not using the checkout action here because on it's not supported + # on all containers we want to test. Resort to a manual checkout. + # + # We can't hoist this into an action since calling an action can only + # be done after checkout. + - name: Manual checkout + shell: bash + run: | + if /usr/bin/which yum; then + yum install git -y + elif /usr/bin/which apt; then + apt update + apt install git -y + fi + + git init + git remote add origin $GITHUB_SERVER_URL/$GITHUB_REPOSITORY + git fetch origin --depth 1 $GITHUB_SHA + git checkout FETCH_HEAD + - uses: ./.github/actions/setup-os + with: + sudo: "" + - name: make quickcheck + if: ${{ inputs.quickcheck }} + run: | + OPT=0 make quickcheck + make clean >/dev/null + OPT=1 make quickcheck + - name: Functional Tests + uses: ./.github/actions/multi-functest + with: + nix-shell: "" + gh_token: ${{ secrets.AWS_GITHUB_TOKEN }} + cflags: ${{ inputs.cflags }} + compile_mode: ${{ inputs.compile_mode }} + opt: ${{ inputs.opt }} + func: ${{ inputs.functest }} + kat: ${{ inputs.kattest }} + acvp: ${{ inputs.acvptest }} + stop-ec2-runner: + name: Stop instance (${{ inputs.ec2_instance_type }}) + permissions: + contents: 'read' + id-token: 'write' + needs: + - start-ec2-runner + - tests + runs-on: ubuntu-latest + if: ${{ always() }} # required to stop the runner even if the error happened in the previous jobs + steps: + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 # v5.1.0 + with: + role-to-assume: ${{ env.AWS_ROLE }} + aws-region: ${{ env.AWS_REGION }} + - name: Stop EC2 runner + uses: machulav/ec2-github-runner@a6dbcefcf8a31a861f5e078bb153ed332130c512 # v2.4.3 + with: + mode: stop + github-token: ${{ secrets.AWS_GITHUB_TOKEN }} + label: ${{ needs.start-ec2-runner.outputs.label }} + ec2-instance-id: ${{ needs.start-ec2-runner.outputs.ec2-instance-id }}