Skip to content

Commit 1b53a18

Browse files
committed
AES-GCM-SIV: Add implementation in C and assembly
Added assembly for Intel x64, ARM64, ARM32, Thumb2.
1 parent 9d3152c commit 1b53a18

24 files changed

Lines changed: 25728 additions & 1669 deletions

.github/workflows/aesgcm-siv.yml

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
name: AES-GCM-SIV (RFC 8452) tests
2+
3+
# START OF COMMON SECTION
4+
on:
5+
push:
6+
branches: [ 'release/**' ]
7+
pull_request:
8+
types: [opened, synchronize, reopened, ready_for_review]
9+
branches: [ '*' ]
10+
# Weekday-morning cron (10:00 UTC) seeds the master-scoped ccache that PR runs
11+
# restore (cross job only); re-runs --build-only on the default branch.
12+
schedule:
13+
- cron: '40 10 * * 1-5'
14+
15+
concurrency:
16+
group: ${{ github.workflow }}-${{ github.ref }}
17+
cancel-in-progress: true
18+
# END OF COMMON SECTION
19+
20+
jobs:
21+
# Native x86_64 'make check'. These are --enable-cryptonly (WOLFCRYPT_ONLY)
22+
# builds, so check runs testwolfcrypt - which includes aesgcm_siv_test (the
23+
# RFC 8452 KATs) - but not the TLS-only tests/unit.test (the tests/api group,
24+
# test_wc_AesGcmSivEncryptDecrypt, needs a non-cryptonly build). One runner
25+
# per config:
26+
# - siv-c-only : no asm, software word64-table POLYVAL + C CTR.
27+
# - siv-word32 : GCM_WORD32 forces the word32-table software POLYVAL multiply.
28+
# - siv-small : GCM_SMALL forces the table-free software POLYVAL multiply.
29+
# - siv-intelasm : PCLMUL/AVX/VAES/AVX512 POLYVAL + pipelined CTR, whichever
30+
# the runner CPU selects at runtime.
31+
# - siv-all : SIV alongside --enable-all to catch integration regressions.
32+
# - siv-smallstack : SIV's key schedules / derived keys live on the stack.
33+
make_check:
34+
strategy:
35+
fail-fast: false
36+
matrix:
37+
config:
38+
- '--enable-cryptonly --enable-aesgcm-siv'
39+
- '--enable-cryptonly --enable-aesgcm-siv CPPFLAGS=-DGCM_WORD32'
40+
- '--enable-cryptonly --enable-aesgcm-siv CPPFLAGS=-DGCM_SMALL'
41+
- '--enable-cryptonly --enable-intelasm --enable-sp-asm --enable-aesgcm-siv'
42+
- '--enable-cryptonly --enable-all-crypto --enable-intelasm --enable-sp-asm --enable-aesgcm-siv'
43+
- '--enable-cryptonly --enable-aesgcm-siv --enable-smallstack'
44+
name: make check (${{ matrix.config }})
45+
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
46+
runs-on: ubuntu-24.04
47+
timeout-minutes: 12
48+
steps:
49+
- uses: actions/checkout@v5
50+
name: Checkout wolfSSL
51+
52+
- name: Build and test AES-GCM-SIV
53+
run: |
54+
./autogen.sh
55+
./configure ${{ matrix.config }}
56+
make -j 4
57+
make check
58+
59+
- name: Print errors
60+
if: ${{ failure() }}
61+
run: |
62+
for file in scripts/*.log test-suite.log
63+
do
64+
if [ -f "$file" ]; then
65+
echo "${file}:"
66+
cat "$file"
67+
echo "========================================================================"
68+
fi
69+
done
70+
71+
# Cross-compiled AES-GCM-SIV asm paths, built out-of-tree in parallel and run
72+
# under qemu-user (binfmt). Covers:
73+
# - arm64-pmull : AArch64 PMULL POLYVAL (gcm_siv_arm64_crypto).
74+
# - arm64-no-hw-crypto : AArch64 NEON 8-bit-pmul + table POLYVAL
75+
# (gcm_siv_arm64_neon / _base) via WOLFSSL_ARMASM_NO_HW_CRYPTO.
76+
# - armhf-crypto : ARMv8-A 32-bit vmull.p64 POLYVAL (gcm_siv_arm32_crypto);
77+
# QEMU_CPU=max enables the crypto extensions.
78+
# - armhf-base : AArch32 software-table POLYVAL/CTR (gcm_siv_arm32_base)
79+
# via NO_HW_CRYPTO, run under the default (non-crypto) CPU.
80+
# Known gaps (a defect here would not be caught): the AArch64 base variant
81+
# (AES_GCMSIV_polyval_base) is compiled in every aarch64 armasm build but only
82+
# selected at runtime with NEON+HW-crypto both disabled, a config unsupported
83+
# upstream on aarch64 (no base SHA/ChaCha armasm); and Thumb-2 (gcm_siv_thumb2,
84+
# armv7-m) which qemu-user cannot run. Both are noted for release notes.
85+
cross_check:
86+
name: Cross-arch test
87+
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
88+
runs-on: ubuntu-22.04
89+
timeout-minutes: 25
90+
steps:
91+
- uses: actions/checkout@v5
92+
name: Checkout wolfSSL
93+
94+
- name: Install dependencies
95+
uses: ./.github/actions/install-apt-deps
96+
with:
97+
packages: autoconf automake libtool build-essential crossbuild-essential-arm64 crossbuild-essential-armhf qemu-user
98+
ghcr-debs-tag: ubuntu-22.04-minimal
99+
100+
- name: Set up ccache
101+
uses: ./.github/actions/ccache-setup
102+
with:
103+
workflow-id: aesgcm-siv
104+
read-only: ${{ github.event_name == 'pull_request' }}
105+
max-size: 300M
106+
107+
- name: Build all configs (parallel, out-of-tree)
108+
run: |
109+
cat > "$RUNNER_TEMP/aesgcm-siv-configs.json" <<'EOF'
110+
[
111+
{"name": "arm64-pmull", "minutes": 6,
112+
"cc": "ccache aarch64-linux-gnu-gcc",
113+
"configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly",
114+
"--enable-all-crypto", "--disable-examples", "--enable-armasm",
115+
"--enable-aesgcm-siv", "CFLAGS=-O2"],
116+
"check": false,
117+
"run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "QEMU_CPU=max",
118+
"./wolfcrypt/test/testwolfcrypt"]]},
119+
{"name": "arm64-no-hw-crypto", "minutes": 6,
120+
"cc": "ccache aarch64-linux-gnu-gcc",
121+
"configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly",
122+
"--enable-all-crypto", "--disable-examples", "--enable-armasm",
123+
"--enable-aesgcm-siv", "CPPFLAGS=-DWOLFSSL_ARMASM_NO_HW_CRYPTO",
124+
"CFLAGS=-O2"],
125+
"check": false,
126+
"run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "QEMU_CPU=max",
127+
"./wolfcrypt/test/testwolfcrypt"]]},
128+
{"name": "armhf-crypto", "minutes": 6,
129+
"cc": "ccache arm-linux-gnueabihf-gcc",
130+
"comment": "--disable-aesgcm-stream: WOLFSSL_AESGCM_STREAM's software GHASH only defines its macros for __aarch64__ armasm, not 32-bit __arm__ armasm, so all-crypto + armasm otherwise fails to build aes.c (pre-existing, unrelated to SIV).",
131+
"configure": ["--host=arm-linux-gnueabihf", "--enable-cryptonly",
132+
"--enable-all-crypto", "--disable-examples", "--enable-armasm",
133+
"--enable-aesgcm-siv", "--disable-aesgcm-stream", "CFLAGS=-O2"],
134+
"check": false,
135+
"run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "QEMU_CPU=max",
136+
"./wolfcrypt/test/testwolfcrypt"]]},
137+
{"name": "armhf-base", "minutes": 6,
138+
"cc": "ccache arm-linux-gnueabihf-gcc",
139+
"comment": "WOLFSSL_ARMASM_NO_HW_CRYPTO selects the AArch32 software-table POLYVAL/CTR (AES_GCMSIV_polyval_base/ctr_base). Run under the DEFAULT qemu CPU (no QEMU_CPU=max) so the crypto path is not taken - this is the only job exercising the base variant at runtime.",
140+
"configure": ["--host=arm-linux-gnueabihf", "--enable-cryptonly",
141+
"--enable-all-crypto", "--disable-examples", "--enable-armasm",
142+
"--enable-aesgcm-siv", "--disable-aesgcm-stream",
143+
"CPPFLAGS=-DWOLFSSL_ARMASM_NO_HW_CRYPTO", "CFLAGS=-O2"],
144+
"check": false,
145+
"run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf",
146+
"./wolfcrypt/test/testwolfcrypt"]]}
147+
]
148+
EOF
149+
.github/scripts/parallel-make-check.py \
150+
${{ github.event_name == 'schedule' && '--build-only' || '' }} \
151+
"$RUNNER_TEMP/aesgcm-siv-configs.json"
152+
153+
- name: ccache stats
154+
if: always()
155+
run: ccache -s || true
156+
157+
- name: Upload logs on failure
158+
if: failure()
159+
uses: actions/upload-artifact@v6
160+
with:
161+
retention-days: 7
162+
name: aesgcm-siv-cross-logs
163+
path: |
164+
build-*/make-check.log
165+
build-*/test-suite.log
166+
build-*/config.log
167+
if-no-files-found: ignore
168+
169+
# Windows MSVC/MASM: build wolfssl64.sln (AES-NI on by default => the MASM
170+
# aes_gcm_asm.asm POLYVAL/CTR is assembled with ml64) with WOLFSSL_AESGCM_SIV
171+
# enabled, and run testsuite.exe - which calls wolfcrypt_test() -> the RFC 8452
172+
# KATs incl. the 128-byte multi-block vector. This is the ONLY job that
173+
# exercises the Windows MASM SIV path; its absence let a High-severity
174+
# AES_GCMSIV_ctr register-clobber (wrong ciphertext + a 16-byte wild write)
175+
# ship undetected. x64 only: the AES-NI .asm is x86_64.
176+
windows_masm:
177+
name: Windows MASM AES-GCM-SIV (x64)
178+
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
179+
runs-on: windows-latest
180+
timeout-minutes: 12
181+
env:
182+
SOLUTION_FILE_PATH: wolfssl64.sln
183+
BUILD_CONFIGURATION: Release
184+
steps:
185+
- uses: actions/checkout@v5
186+
name: Checkout wolfSSL
187+
188+
- name: Enable AES-GCM-SIV in user_settings.h
189+
shell: bash
190+
run: |
191+
# Add the define once, right after the first HAVE_AESGCM (AES-NI is
192+
# already enabled for x64 in this header).
193+
sed -i '0,/#define HAVE_AESGCM/s//#define HAVE_AESGCM\n#define WOLFSSL_AESGCM_SIV/' \
194+
IDE/WIN/user_settings.h
195+
grep -n 'WOLFSSL_AESGCM_SIV' IDE/WIN/user_settings.h
196+
197+
- name: Add MSBuild to PATH
198+
uses: microsoft/setup-msbuild@v3
199+
200+
- name: Restore NuGet packages
201+
run: nuget restore ${{ env.SOLUTION_FILE_PATH }}
202+
203+
- name: Build (x64, MASM)
204+
run: msbuild /m /p:PlatformToolset=v142 /p:Platform=x64 /p:Configuration=${{ env.BUILD_CONFIGURATION }} ${{ env.SOLUTION_FILE_PATH }}
205+
206+
- name: Run wolfCrypt KATs (incl. AES-GCM-SIV)
207+
run: Release/x64/testsuite.exe

.wolfssl_known_macro_extras

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,7 @@ WOLFSSL_SE050_NO_TRNG
927927
WOLFSSL_SECURE_RENEGOTIATION_ON_BY_DEFAULT
928928
WOLFSSL_SERVER_EXAMPLE
929929
WOLFSSL_SETTINGS_FILE
930+
WOLFSSL_SGX_CPUID_AVX512_VAES
930931
WOLFSSL_SHA256_ALT_CH_MAJ
931932
WOLFSSL_SHA3_PPC64_BLOCKS_N
932933
WOLFSSL_SHA512_HASHTYPE

CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,18 @@ if(WOLFSSL_AESSIV)
930930
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AES_SIV")
931931
endif()
932932

933+
# AES-GCM-SIV
934+
add_option("WOLFSSL_AESGCMSIV"
935+
"Enable AES-GCM-SIV (RFC 8452) support (default: disabled)"
936+
"no" "yes;no")
937+
938+
if(WOLFSSL_AESGCMSIV)
939+
if(NOT WOLFSSL_AESGCM)
940+
message(FATAL_ERROR "AES-GCM-SIV requires AES-GCM. Please enable WOLFSSL_AESGCM.")
941+
endif()
942+
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AESGCM_SIV")
943+
endif()
944+
933945
# AES-CTR
934946
add_option("WOLFSSL_AESCTR"
935947
"Enable wolfSSL AES-CTR support (default: disabled)"

configure.ac

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3536,6 +3536,25 @@ then
35363536
ENABLED_AESSIV=yes
35373537
fi
35383538

3539+
# AES-GCM-SIV (RFC 8452)
3540+
AC_ARG_ENABLE([aesgcm-siv],
3541+
[AS_HELP_STRING([--enable-aesgcm-siv],[Enable AES-GCM-SIV (RFC 8452) (default: disabled)])],
3542+
[ ENABLED_AESGCMSIV=$enableval ],
3543+
[ ENABLED_AESGCMSIV=no ]
3544+
)
3545+
3546+
if test "$ENABLED_AESGCMSIV" = "yes"
3547+
then
3548+
if test "$ENABLED_AESGCM" = "no"
3549+
then
3550+
AC_MSG_ERROR([AES-GCM-SIV requires AES-GCM. Please enable it (--enable-aesgcm).])
3551+
fi
3552+
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AESGCM_SIV"
3553+
# The generated AES-GCM-SIV assembly (aes_gcm_asm.S) is guarded by
3554+
# WOLFSSL_AESGCM_SIV, so the assembler needs the define too.
3555+
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AESGCM_SIV"
3556+
fi
3557+
35393558
# AES-CTR
35403559
AC_ARG_ENABLE([aesctr],
35413560
[AS_HELP_STRING([--enable-aesctr],[Enable wolfSSL AES-CTR support (default: disabled)])],
@@ -12981,6 +13000,7 @@ echo " * AES-OFB: $ENABLED_AESOFB"
1298113000
echo " * AES-XTS: $ENABLED_AESXTS"
1298213001
echo " * AES-XTS streaming: $ENABLED_AESXTS_STREAM"
1298313002
echo " * AES-SIV: $ENABLED_AESSIV"
13003+
echo " * AES-GCM-SIV: $ENABLED_AESGCMSIV"
1298413004
echo " * AES-EAX: $ENABLED_AESEAX"
1298513005
echo " * AES Bitspliced: $ENABLED_AESBS"
1298613006
echo " * AES Key Wrap: $ENABLED_AESKEYWRAP"

0 commit comments

Comments
 (0)