mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-09 10:30:50 +02:00
AES-GCM-SIV: Add implementation in C and assembly
Added assembly for Intel x64, ARM64, ARM32, Thumb2.
This commit is contained in:
@@ -0,0 +1,207 @@
|
||||
name: AES-GCM-SIV (RFC 8452) tests
|
||||
|
||||
# START OF COMMON SECTION
|
||||
on:
|
||||
push:
|
||||
branches: [ 'release/**' ]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
branches: [ '*' ]
|
||||
# Weekday-morning cron (10:00 UTC) seeds the master-scoped ccache that PR runs
|
||||
# restore (cross job only); re-runs --build-only on the default branch.
|
||||
schedule:
|
||||
- cron: '40 10 * * 1-5'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
# END OF COMMON SECTION
|
||||
|
||||
jobs:
|
||||
# Native x86_64 'make check'. These are --enable-cryptonly (WOLFCRYPT_ONLY)
|
||||
# builds, so check runs testwolfcrypt - which includes aesgcm_siv_test (the
|
||||
# RFC 8452 KATs) - but not the TLS-only tests/unit.test (the tests/api group,
|
||||
# test_wc_AesGcmSivEncryptDecrypt, needs a non-cryptonly build). One runner
|
||||
# per config:
|
||||
# - siv-c-only : no asm, software word64-table POLYVAL + C CTR.
|
||||
# - siv-word32 : GCM_WORD32 forces the word32-table software POLYVAL multiply.
|
||||
# - siv-small : GCM_SMALL forces the table-free software POLYVAL multiply.
|
||||
# - siv-intelasm : PCLMUL/AVX/VAES/AVX512 POLYVAL + pipelined CTR, whichever
|
||||
# the runner CPU selects at runtime.
|
||||
# - siv-all : SIV alongside --enable-all to catch integration regressions.
|
||||
# - siv-smallstack : SIV's key schedules / derived keys live on the stack.
|
||||
make_check:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- '--enable-cryptonly --enable-aesgcm-siv'
|
||||
- '--enable-cryptonly --enable-aesgcm-siv CPPFLAGS=-DGCM_WORD32'
|
||||
- '--enable-cryptonly --enable-aesgcm-siv CPPFLAGS=-DGCM_SMALL'
|
||||
- '--enable-cryptonly --enable-intelasm --enable-sp-asm --enable-aesgcm-siv'
|
||||
- '--enable-cryptonly --enable-all-crypto --enable-intelasm --enable-sp-asm --enable-aesgcm-siv'
|
||||
- '--enable-cryptonly --enable-aesgcm-siv --enable-smallstack'
|
||||
name: make check (${{ matrix.config }})
|
||||
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 12
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
name: Checkout wolfSSL
|
||||
|
||||
- name: Build and test AES-GCM-SIV
|
||||
run: |
|
||||
./autogen.sh
|
||||
./configure ${{ matrix.config }}
|
||||
make -j 4
|
||||
make check
|
||||
|
||||
- name: Print errors
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
for file in scripts/*.log test-suite.log
|
||||
do
|
||||
if [ -f "$file" ]; then
|
||||
echo "${file}:"
|
||||
cat "$file"
|
||||
echo "========================================================================"
|
||||
fi
|
||||
done
|
||||
|
||||
# Cross-compiled AES-GCM-SIV asm paths, built out-of-tree in parallel and run
|
||||
# under qemu-user (binfmt). Covers:
|
||||
# - arm64-pmull : AArch64 PMULL POLYVAL (gcm_siv_arm64_crypto).
|
||||
# - arm64-no-hw-crypto : AArch64 NEON 8-bit-pmul + table POLYVAL
|
||||
# (gcm_siv_arm64_neon / _base) via WOLFSSL_ARMASM_NO_HW_CRYPTO.
|
||||
# - armhf-crypto : ARMv8-A 32-bit vmull.p64 POLYVAL (gcm_siv_arm32_crypto);
|
||||
# QEMU_CPU=max enables the crypto extensions.
|
||||
# - armhf-base : AArch32 software-table POLYVAL/CTR (gcm_siv_arm32_base)
|
||||
# via NO_HW_CRYPTO, run under the default (non-crypto) CPU.
|
||||
# Known gaps (a defect here would not be caught): the AArch64 base variant
|
||||
# (AES_GCMSIV_polyval_base) is compiled in every aarch64 armasm build but only
|
||||
# selected at runtime with NEON+HW-crypto both disabled, a config unsupported
|
||||
# upstream on aarch64 (no base SHA/ChaCha armasm); and Thumb-2 (gcm_siv_thumb2,
|
||||
# armv7-m) which qemu-user cannot run. Both are noted for release notes.
|
||||
cross_check:
|
||||
name: Cross-arch test
|
||||
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
|
||||
runs-on: ubuntu-22.04
|
||||
timeout-minutes: 25
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
name: Checkout wolfSSL
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/actions/install-apt-deps
|
||||
with:
|
||||
packages: autoconf automake libtool build-essential crossbuild-essential-arm64 crossbuild-essential-armhf qemu-user
|
||||
ghcr-debs-tag: ubuntu-22.04-minimal
|
||||
|
||||
- name: Set up ccache
|
||||
uses: ./.github/actions/ccache-setup
|
||||
with:
|
||||
workflow-id: aesgcm-siv
|
||||
read-only: ${{ github.event_name == 'pull_request' }}
|
||||
max-size: 300M
|
||||
|
||||
- name: Build all configs (parallel, out-of-tree)
|
||||
run: |
|
||||
cat > "$RUNNER_TEMP/aesgcm-siv-configs.json" <<'EOF'
|
||||
[
|
||||
{"name": "arm64-pmull", "minutes": 6,
|
||||
"cc": "ccache aarch64-linux-gnu-gcc",
|
||||
"configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly",
|
||||
"--enable-all-crypto", "--disable-examples", "--enable-armasm",
|
||||
"--enable-aesgcm-siv", "CFLAGS=-O2"],
|
||||
"check": false,
|
||||
"run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "QEMU_CPU=max",
|
||||
"./wolfcrypt/test/testwolfcrypt"]]},
|
||||
{"name": "arm64-no-hw-crypto", "minutes": 6,
|
||||
"cc": "ccache aarch64-linux-gnu-gcc",
|
||||
"configure": ["--host=aarch64-linux-gnu", "--enable-cryptonly",
|
||||
"--enable-all-crypto", "--disable-examples", "--enable-armasm",
|
||||
"--enable-aesgcm-siv", "CPPFLAGS=-DWOLFSSL_ARMASM_NO_HW_CRYPTO",
|
||||
"CFLAGS=-O2"],
|
||||
"check": false,
|
||||
"run": [["env", "QEMU_LD_PREFIX=/usr/aarch64-linux-gnu", "QEMU_CPU=max",
|
||||
"./wolfcrypt/test/testwolfcrypt"]]},
|
||||
{"name": "armhf-crypto", "minutes": 6,
|
||||
"cc": "ccache arm-linux-gnueabihf-gcc",
|
||||
"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).",
|
||||
"configure": ["--host=arm-linux-gnueabihf", "--enable-cryptonly",
|
||||
"--enable-all-crypto", "--disable-examples", "--enable-armasm",
|
||||
"--enable-aesgcm-siv", "--disable-aesgcm-stream", "CFLAGS=-O2"],
|
||||
"check": false,
|
||||
"run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf", "QEMU_CPU=max",
|
||||
"./wolfcrypt/test/testwolfcrypt"]]},
|
||||
{"name": "armhf-base", "minutes": 6,
|
||||
"cc": "ccache arm-linux-gnueabihf-gcc",
|
||||
"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.",
|
||||
"configure": ["--host=arm-linux-gnueabihf", "--enable-cryptonly",
|
||||
"--enable-all-crypto", "--disable-examples", "--enable-armasm",
|
||||
"--enable-aesgcm-siv", "--disable-aesgcm-stream",
|
||||
"CPPFLAGS=-DWOLFSSL_ARMASM_NO_HW_CRYPTO", "CFLAGS=-O2"],
|
||||
"check": false,
|
||||
"run": [["env", "QEMU_LD_PREFIX=/usr/arm-linux-gnueabihf",
|
||||
"./wolfcrypt/test/testwolfcrypt"]]}
|
||||
]
|
||||
EOF
|
||||
.github/scripts/parallel-make-check.py \
|
||||
${{ github.event_name == 'schedule' && '--build-only' || '' }} \
|
||||
"$RUNNER_TEMP/aesgcm-siv-configs.json"
|
||||
|
||||
- name: ccache stats
|
||||
if: always()
|
||||
run: ccache -s || true
|
||||
|
||||
- name: Upload logs on failure
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
retention-days: 7
|
||||
name: aesgcm-siv-cross-logs
|
||||
path: |
|
||||
build-*/make-check.log
|
||||
build-*/test-suite.log
|
||||
build-*/config.log
|
||||
if-no-files-found: ignore
|
||||
|
||||
# Windows MSVC/MASM: build wolfssl64.sln (AES-NI on by default => the MASM
|
||||
# aes_gcm_asm.asm POLYVAL/CTR is assembled with ml64) with WOLFSSL_AESGCM_SIV
|
||||
# enabled, and run testsuite.exe - which calls wolfcrypt_test() -> the RFC 8452
|
||||
# KATs incl. the 128-byte multi-block vector. This is the ONLY job that
|
||||
# exercises the Windows MASM SIV path; its absence let a High-severity
|
||||
# AES_GCMSIV_ctr register-clobber (wrong ciphertext + a 16-byte wild write)
|
||||
# ship undetected. x64 only: the AES-NI .asm is x86_64.
|
||||
windows_masm:
|
||||
name: Windows MASM AES-GCM-SIV (x64)
|
||||
if: ${{ (github.repository_owner == 'wolfssl') && (github.event_name != 'pull_request' || github.event.pull_request.draft == false) }}
|
||||
runs-on: windows-latest
|
||||
timeout-minutes: 12
|
||||
env:
|
||||
SOLUTION_FILE_PATH: wolfssl64.sln
|
||||
BUILD_CONFIGURATION: Release
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
name: Checkout wolfSSL
|
||||
|
||||
- name: Enable AES-GCM-SIV in user_settings.h
|
||||
shell: bash
|
||||
run: |
|
||||
# Add the define once, right after the first HAVE_AESGCM (AES-NI is
|
||||
# already enabled for x64 in this header).
|
||||
sed -i '0,/#define HAVE_AESGCM/s//#define HAVE_AESGCM\n#define WOLFSSL_AESGCM_SIV/' \
|
||||
IDE/WIN/user_settings.h
|
||||
grep -n 'WOLFSSL_AESGCM_SIV' IDE/WIN/user_settings.h
|
||||
|
||||
- name: Add MSBuild to PATH
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
|
||||
- name: Restore NuGet packages
|
||||
run: nuget restore ${{ env.SOLUTION_FILE_PATH }}
|
||||
|
||||
- name: Build (x64, MASM)
|
||||
run: msbuild /m /p:PlatformToolset=v142 /p:Platform=x64 /p:Configuration=${{ env.BUILD_CONFIGURATION }} ${{ env.SOLUTION_FILE_PATH }}
|
||||
|
||||
- name: Run wolfCrypt KATs (incl. AES-GCM-SIV)
|
||||
run: Release/x64/testsuite.exe
|
||||
@@ -927,6 +927,7 @@ WOLFSSL_SE050_NO_TRNG
|
||||
WOLFSSL_SECURE_RENEGOTIATION_ON_BY_DEFAULT
|
||||
WOLFSSL_SERVER_EXAMPLE
|
||||
WOLFSSL_SETTINGS_FILE
|
||||
WOLFSSL_SGX_CPUID_AVX512_VAES
|
||||
WOLFSSL_SHA256_ALT_CH_MAJ
|
||||
WOLFSSL_SHA3_PPC64_BLOCKS_N
|
||||
WOLFSSL_SHA512_HASHTYPE
|
||||
|
||||
@@ -930,6 +930,18 @@ if(WOLFSSL_AESSIV)
|
||||
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AES_SIV")
|
||||
endif()
|
||||
|
||||
# AES-GCM-SIV
|
||||
add_option("WOLFSSL_AESGCMSIV"
|
||||
"Enable AES-GCM-SIV (RFC 8452) support (default: disabled)"
|
||||
"no" "yes;no")
|
||||
|
||||
if(WOLFSSL_AESGCMSIV)
|
||||
if(NOT WOLFSSL_AESGCM)
|
||||
message(FATAL_ERROR "AES-GCM-SIV requires AES-GCM. Please enable WOLFSSL_AESGCM.")
|
||||
endif()
|
||||
list(APPEND WOLFSSL_DEFINITIONS "-DWOLFSSL_AESGCM_SIV")
|
||||
endif()
|
||||
|
||||
# AES-CTR
|
||||
add_option("WOLFSSL_AESCTR"
|
||||
"Enable wolfSSL AES-CTR support (default: disabled)"
|
||||
|
||||
@@ -3536,6 +3536,25 @@ then
|
||||
ENABLED_AESSIV=yes
|
||||
fi
|
||||
|
||||
# AES-GCM-SIV (RFC 8452)
|
||||
AC_ARG_ENABLE([aesgcm-siv],
|
||||
[AS_HELP_STRING([--enable-aesgcm-siv],[Enable AES-GCM-SIV (RFC 8452) (default: disabled)])],
|
||||
[ ENABLED_AESGCMSIV=$enableval ],
|
||||
[ ENABLED_AESGCMSIV=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLED_AESGCMSIV" = "yes"
|
||||
then
|
||||
if test "$ENABLED_AESGCM" = "no"
|
||||
then
|
||||
AC_MSG_ERROR([AES-GCM-SIV requires AES-GCM. Please enable it (--enable-aesgcm).])
|
||||
fi
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AESGCM_SIV"
|
||||
# The generated AES-GCM-SIV assembly (aes_gcm_asm.S) is guarded by
|
||||
# WOLFSSL_AESGCM_SIV, so the assembler needs the define too.
|
||||
AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_AESGCM_SIV"
|
||||
fi
|
||||
|
||||
# AES-CTR
|
||||
AC_ARG_ENABLE([aesctr],
|
||||
[AS_HELP_STRING([--enable-aesctr],[Enable wolfSSL AES-CTR support (default: disabled)])],
|
||||
@@ -12981,6 +13000,7 @@ echo " * AES-OFB: $ENABLED_AESOFB"
|
||||
echo " * AES-XTS: $ENABLED_AESXTS"
|
||||
echo " * AES-XTS streaming: $ENABLED_AESXTS_STREAM"
|
||||
echo " * AES-SIV: $ENABLED_AESSIV"
|
||||
echo " * AES-GCM-SIV: $ENABLED_AESGCMSIV"
|
||||
echo " * AES-EAX: $ENABLED_AESEAX"
|
||||
echo " * AES Bitspliced: $ENABLED_AESBS"
|
||||
echo " * AES Key Wrap: $ENABLED_AESKEYWRAP"
|
||||
|
||||
@@ -3705,6 +3705,243 @@ int test_wc_AesGcmMixedEncDecLongIV(void)
|
||||
* AES-GCM non-standard nonce lengths
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(WOLFSSL_AESGCM_SIV) && !defined(NO_AES) && defined(HAVE_AESGCM) && \
|
||||
defined(WOLFSSL_AES_128)
|
||||
/* Decode a hex string into 'out' (spaces ignored, NULL -> length 0).
|
||||
* Returns the byte length, or -1 on a malformed string / overflow. */
|
||||
static int gcmsiv_hex(const char* hex, byte* out, word32 max)
|
||||
{
|
||||
word32 n = 0;
|
||||
int hi, lo;
|
||||
|
||||
if (hex == NULL)
|
||||
return 0;
|
||||
while (*hex != '\0') {
|
||||
if (*hex == ' ') { hex++; continue; }
|
||||
if (hex[1] == '\0') return -1;
|
||||
hi = (*hex >= '0' && *hex <= '9') ? *hex - '0' :
|
||||
(*hex >= 'a' && *hex <= 'f') ? *hex - 'a' + 10 :
|
||||
(*hex >= 'A' && *hex <= 'F') ? *hex - 'A' + 10 : -1;
|
||||
hex++;
|
||||
lo = (*hex >= '0' && *hex <= '9') ? *hex - '0' :
|
||||
(*hex >= 'a' && *hex <= 'f') ? *hex - 'a' + 10 :
|
||||
(*hex >= 'A' && *hex <= 'F') ? *hex - 'A' + 10 : -1;
|
||||
hex++;
|
||||
if (hi < 0 || lo < 0 || n >= max) return -1;
|
||||
out[n++] = (byte)((hi << 4) | lo);
|
||||
}
|
||||
return (int)n;
|
||||
}
|
||||
|
||||
/* Run one RFC 8452 known-answer vector (expH = ciphertext || 16-byte tag):
|
||||
* encrypt and check ciphertext+tag, then decrypt and check the recovered
|
||||
* plaintext and that authentication succeeds. Returns 0 on a full match,
|
||||
* or a negative step code on the first failure. */
|
||||
static int gcmsiv_kat(const char* keyH, const char* nonceH, const char* aadH,
|
||||
const char* ptH, const char* expH)
|
||||
{
|
||||
byte key[32], nonce[12], aad[64], pt[64], exp[96], ct[80], tag[16], dec[64];
|
||||
int keySz, nonceSz, aadSz, ptSz, expSz;
|
||||
|
||||
keySz = gcmsiv_hex(keyH, key, (word32)sizeof(key));
|
||||
nonceSz = gcmsiv_hex(nonceH, nonce, (word32)sizeof(nonce));
|
||||
aadSz = gcmsiv_hex(aadH, aad, (word32)sizeof(aad));
|
||||
ptSz = gcmsiv_hex(ptH, pt, (word32)sizeof(pt));
|
||||
expSz = gcmsiv_hex(expH, exp, (word32)sizeof(exp));
|
||||
if (keySz < 0 || nonceSz < 0 || aadSz < 0 || ptSz < 0 || expSz < 0)
|
||||
return -1;
|
||||
if (expSz != ptSz + 16)
|
||||
return -2;
|
||||
|
||||
if (wc_AesGcmSivEncrypt(key, (word32)keySz, nonce, (word32)nonceSz,
|
||||
aad, (word32)aadSz, pt, (word32)ptSz, ct, tag, 16) != 0)
|
||||
return -3;
|
||||
if (ptSz > 0 && XMEMCMP(ct, exp, (size_t)ptSz) != 0)
|
||||
return -4;
|
||||
if (XMEMCMP(tag, exp + ptSz, 16) != 0)
|
||||
return -5;
|
||||
|
||||
if (wc_AesGcmSivDecrypt(key, (word32)keySz, nonce, (word32)nonceSz,
|
||||
aad, (word32)aadSz, ct, (word32)ptSz, dec, tag, 16) != 0)
|
||||
return -6;
|
||||
if (ptSz > 0 && XMEMCMP(dec, pt, (size_t)ptSz) != 0)
|
||||
return -7;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* WOLFSSL_AESGCM_SIV ... */
|
||||
|
||||
/*
|
||||
* AES-GCM-SIV (RFC 8452): RFC 8452 Appendix C known-answer vectors (encrypt and
|
||||
* decrypt), a full encrypt/decrypt round trip, authentication-failure handling
|
||||
* (corrupted tag / AAD / ciphertext), edge cases (empty plaintext, empty AAD,
|
||||
* AES-128 and AES-256), and an exhaustive invalid-parameter matrix.
|
||||
*/
|
||||
int test_wc_AesGcmSivEncryptDecrypt(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(WOLFSSL_AESGCM_SIV) && !defined(NO_AES) && defined(HAVE_AESGCM) && \
|
||||
defined(WOLFSSL_AES_128)
|
||||
byte key[32];
|
||||
byte nonce[12];
|
||||
byte aad[20];
|
||||
byte pt[32];
|
||||
byte ct[32];
|
||||
byte tag[16];
|
||||
byte dec[32];
|
||||
word32 i;
|
||||
|
||||
/* --- RFC 8452 Appendix C.1 known-answer vectors (AES-128) --- */
|
||||
ExpectIntEQ(gcmsiv_kat("01000000000000000000000000000000",
|
||||
"030000000000000000000000", NULL, NULL,
|
||||
"dc20e2d83f25705bb49e439eca56de25"), 0);
|
||||
ExpectIntEQ(gcmsiv_kat("01000000000000000000000000000000",
|
||||
"030000000000000000000000", NULL, "0100000000000000",
|
||||
"b5d839330ac7b786578782fff6013b815b287c22493a364c"), 0);
|
||||
ExpectIntEQ(gcmsiv_kat("01000000000000000000000000000000",
|
||||
"030000000000000000000000", NULL, "010000000000000000000000",
|
||||
"7323ea61d05932260047d942a4978db357391a0bc4fdec8b0d106639"), 0);
|
||||
ExpectIntEQ(gcmsiv_kat("01000000000000000000000000000000",
|
||||
"030000000000000000000000", "01", "0200000000000000",
|
||||
"1e6daba35669f4273b0a1a2560969cdf790d99759abd1508"), 0);
|
||||
ExpectIntEQ(gcmsiv_kat("01000000000000000000000000000000",
|
||||
"030000000000000000000000", "01",
|
||||
"02000000000000000000000000000000",
|
||||
"e2b0c5da79a901c1745f700525cb335b8f8936ec039e4e4bb97ebd8c4457441f"), 0);
|
||||
/* Non-block-aligned AAD (18 B) and plaintext (20 B). */
|
||||
ExpectIntEQ(gcmsiv_kat("01000000000000000000000000000000",
|
||||
"030000000000000000000000",
|
||||
"010000000000000000000000000000000200",
|
||||
"030000000000000000000000000000000400 0000",
|
||||
"6bb0fecf5ded9b77f902c7d5da236a4391dd029724afc9805e976f451e6d87f6"
|
||||
"fe106514"), 0);
|
||||
/* Non-block-aligned AAD (20 B) and plaintext (18 B). */
|
||||
ExpectIntEQ(gcmsiv_kat("01000000000000000000000000000000",
|
||||
"030000000000000000000000",
|
||||
"0100000000000000000000000000000002000000",
|
||||
"030000000000000000000000000000000400",
|
||||
"44d0aaf6fb2f1f34add5e8064e83e12a2adabff9b2ef00fb47920cc72a0c0f13"
|
||||
"b9fd"), 0);
|
||||
|
||||
#ifdef WOLFSSL_AES_256
|
||||
/* --- RFC 8452 Appendix C.2 known-answer vectors (AES-256) --- */
|
||||
ExpectIntEQ(gcmsiv_kat(
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"030000000000000000000000", NULL, NULL,
|
||||
"07f5f4169bbf55a8400cd47ea6fd400f"), 0);
|
||||
ExpectIntEQ(gcmsiv_kat(
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"030000000000000000000000", NULL, "0100000000000000",
|
||||
"c2ef328e5c71c83b843122130f7364b761e0b97427e3df28"), 0);
|
||||
ExpectIntEQ(gcmsiv_kat(
|
||||
"0100000000000000000000000000000000000000000000000000000000000000",
|
||||
"030000000000000000000000", NULL, "010000000000000000000000",
|
||||
"9aab2aeb3faa0a34aea8e2b18ca50da9ae6559e48fd10f6e5c9ca17e"), 0);
|
||||
#endif /* WOLFSSL_AES_256 */
|
||||
|
||||
/* --- Round trip + authentication-failure handling (AES-128) --- */
|
||||
for (i = 0; i < (word32)sizeof(key); i++) key[i] = (byte)i;
|
||||
for (i = 0; i < (word32)sizeof(nonce); i++) nonce[i] = (byte)(i + 1);
|
||||
for (i = 0; i < (word32)sizeof(aad); i++) aad[i] = (byte)(i + 2);
|
||||
for (i = 0; i < (word32)sizeof(pt); i++) pt[i] = (byte)(i + 3);
|
||||
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), 0);
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), 0);
|
||||
ExpectIntEQ(XMEMCMP(pt, dec, sizeof(pt)), 0);
|
||||
|
||||
/* Corrupted tag -> authentication failure. */
|
||||
tag[0] ^= 0xff;
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
|
||||
tag[0] ^= 0xff;
|
||||
/* Corrupted AAD -> authentication failure. */
|
||||
aad[0] ^= 0xff;
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
|
||||
aad[0] ^= 0xff;
|
||||
/* Corrupted ciphertext -> authentication failure. */
|
||||
ct[0] ^= 0xff;
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), WC_NO_ERR_TRACE(AES_GCM_AUTH_E));
|
||||
ct[0] ^= 0xff;
|
||||
|
||||
/* Edge cases: empty plaintext (tag only) and empty AAD. */
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 12, NULL, 0, NULL, 0,
|
||||
NULL, tag, 16), 0);
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 12, NULL, 0, NULL, 0,
|
||||
NULL, tag, 16), 0);
|
||||
|
||||
#ifdef WOLFSSL_AES_256
|
||||
/* AES-256 round trip. */
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 32, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), 0);
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 32, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), 0);
|
||||
ExpectIntEQ(XMEMCMP(pt, dec, sizeof(pt)), 0);
|
||||
#endif
|
||||
|
||||
/* --- Invalid parameters: encrypt --- */
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(NULL, 16, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, NULL, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, NULL, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
/* in/out NULL while inSz != 0 */
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
NULL, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), NULL, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
/* aad NULL while aadSz != 0 */
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 12, NULL, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
/* invalid key sizes (only 16 and 32 allowed; 24/AES-192 is rejected) */
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 0, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 15, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 24, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 33, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
/* invalid nonce sizes (must be exactly 12) */
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 0, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 11, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 13, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
/* invalid tag sizes (must be exactly 16) */
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 15), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivEncrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
pt, sizeof(pt), ct, tag, 17), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
|
||||
/* --- Invalid parameters: decrypt --- */
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(NULL, 16, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, NULL, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, NULL, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
NULL, sizeof(pt), dec, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), NULL, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, NULL, 12, NULL, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 24, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 13, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 16), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
ExpectIntEQ(wc_AesGcmSivDecrypt(key, 16, nonce, 12, aad, sizeof(aad),
|
||||
ct, sizeof(pt), dec, tag, 17), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
#endif /* WOLFSSL_AESGCM_SIV && !NO_AES && HAVE_AESGCM && WOLFSSL_AES_128 */
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-standard (non-96-bit) nonce tests for AES-GCM.
|
||||
*
|
||||
|
||||
@@ -51,6 +51,7 @@ int test_wc_AesGcmEncryptDecrypt_UnalignedBuffers(void);
|
||||
int test_wc_AesGcm_CrossCipher(void);
|
||||
int test_wc_AesGcmMixedEncDecLongIV(void);
|
||||
int test_wc_AesGcmNonStdNonce(void);
|
||||
int test_wc_AesGcmSivEncryptDecrypt(void);
|
||||
int test_wc_AesGcmStream(void);
|
||||
int test_wc_AesGcmStream_MidStreamState(void);
|
||||
int test_wc_AesGcmStream_ReinitAfterFinal(void);
|
||||
@@ -149,6 +150,7 @@ int test_wc_CryptoCb_Tls13_Key_No_Zero_Without_Offload(void);
|
||||
TEST_DECL_GROUP("aes", test_wc_AesGcm_CrossCipher), \
|
||||
TEST_DECL_GROUP("aes", test_wc_AesGcmMixedEncDecLongIV), \
|
||||
TEST_DECL_GROUP("aes", test_wc_AesGcmNonStdNonce), \
|
||||
TEST_DECL_GROUP("aes", test_wc_AesGcmSivEncryptDecrypt), \
|
||||
TEST_DECL_GROUP("aes", test_wc_AesGcmStream), \
|
||||
TEST_DECL_GROUP("aes", test_wc_AesGcmStream_MidStreamState), \
|
||||
TEST_DECL_GROUP("aes", test_wc_AesGcmStream_ReinitAfterFinal), \
|
||||
|
||||
@@ -829,6 +829,7 @@ static WC_INLINE void bench_append_memory_info(char* buffer, size_t size,
|
||||
#define BENCH_SM4_GCM 0x00100000
|
||||
#define BENCH_SM4_CCM 0x00200000
|
||||
#define BENCH_SM4 (BENCH_SM4_CBC | BENCH_SM4_GCM | BENCH_SM4_CCM)
|
||||
#define BENCH_AESGCM_SIV 0x00800000
|
||||
/* Digest algorithms. */
|
||||
#define BENCH_MD5 0x00000001
|
||||
#define BENCH_POLY1305 0x00000002
|
||||
@@ -1066,6 +1067,9 @@ static const bench_alg bench_cipher_opt[] = {
|
||||
#ifdef WOLFSSL_AES_SIV
|
||||
{ "-aes-siv", BENCH_AES_SIV },
|
||||
#endif
|
||||
#ifdef WOLFSSL_AESGCM_SIV
|
||||
{ "-aesgcm-siv", BENCH_AESGCM_SIV },
|
||||
#endif
|
||||
#ifdef HAVE_CAMELLIA
|
||||
{ "-camellia", BENCH_CAMELLIA },
|
||||
#endif
|
||||
@@ -4033,6 +4037,10 @@ static void* benchmarks_do(void* args)
|
||||
if (bench_all || (bench_cipher_algs & BENCH_AES_SIV))
|
||||
bench_aessiv();
|
||||
#endif
|
||||
#ifdef WOLFSSL_AESGCM_SIV
|
||||
if (bench_all || (bench_cipher_algs & BENCH_AESGCM_SIV))
|
||||
bench_aesgcmsiv();
|
||||
#endif
|
||||
#endif /* !NO_AES */
|
||||
|
||||
#ifdef HAVE_CAMELLIA
|
||||
@@ -6913,6 +6921,86 @@ void bench_aessiv(void)
|
||||
bench_aessiv_internal(bench_key, 64, "AES-512-SIV-enc", "AES-512-SIV-dec");
|
||||
}
|
||||
#endif /* WOLFSSL_AES_SIV */
|
||||
|
||||
#ifdef WOLFSSL_AESGCM_SIV
|
||||
static void bench_aesgcmsiv_internal(const byte* key, word32 keySz, const char*
|
||||
encLabel, const char* decLabel)
|
||||
{
|
||||
int i;
|
||||
int ret = 0;
|
||||
byte nonce[12];
|
||||
byte additional[AES_AUTH_ADD_SZ];
|
||||
byte tag[WC_AES_BLOCK_SIZE];
|
||||
int count = 0;
|
||||
double start;
|
||||
DECLARE_MULTI_VALUE_STATS_VARS()
|
||||
|
||||
XMEMSET(nonce, 0, sizeof(nonce));
|
||||
XMEMSET(additional, 0, sizeof(additional));
|
||||
|
||||
bench_stats_prepare();
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (i = 0; i < numBlocks; i++) {
|
||||
ret = wc_AesGcmSivEncrypt(key, keySz, nonce, sizeof(nonce),
|
||||
additional, aesAuthAddSz,
|
||||
bench_plain, bench_size, bench_cipher,
|
||||
tag, sizeof(tag));
|
||||
if (ret != 0) {
|
||||
printf("wc_AesGcmSivEncrypt failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
RECORD_MULTI_VALUE_STATS();
|
||||
}
|
||||
count += i;
|
||||
} while (bench_stats_check(start)
|
||||
#ifdef MULTI_VALUE_STATISTICS
|
||||
|| runs < minimum_runs
|
||||
#endif
|
||||
);
|
||||
|
||||
bench_stats_sym_finish(encLabel, 0, count, bench_size, start, ret);
|
||||
#ifdef MULTI_VALUE_STATISTICS
|
||||
bench_multi_value_stats(max, min, sum, squareSum, runs);
|
||||
#endif
|
||||
|
||||
RESET_MULTI_VALUE_STATS_VARS();
|
||||
|
||||
bench_stats_start(&count, &start);
|
||||
do {
|
||||
for (i = 0; i < numBlocks; i++) {
|
||||
ret = wc_AesGcmSivDecrypt(key, keySz, nonce, sizeof(nonce),
|
||||
additional, aesAuthAddSz,
|
||||
bench_cipher, bench_size, bench_plain,
|
||||
tag, sizeof(tag));
|
||||
if (ret != 0) {
|
||||
printf("wc_AesGcmSivDecrypt failed (%d)\n", ret);
|
||||
return;
|
||||
}
|
||||
RECORD_MULTI_VALUE_STATS();
|
||||
}
|
||||
count += i;
|
||||
} while (bench_stats_check(start)
|
||||
#ifdef MULTI_VALUE_STATISTICS
|
||||
|| runs < minimum_runs
|
||||
#endif
|
||||
);
|
||||
|
||||
bench_stats_sym_finish(decLabel, 0, count, bench_size, start, ret);
|
||||
#ifdef MULTI_VALUE_STATISTICS
|
||||
bench_multi_value_stats(max, min, sum, squareSum, runs);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bench_aesgcmsiv(void)
|
||||
{
|
||||
bench_aesgcmsiv_internal(bench_key, 16, "AES-128-GCM-SIV-enc",
|
||||
"AES-128-GCM-SIV-dec");
|
||||
bench_aesgcmsiv_internal(bench_key, 32, "AES-256-GCM-SIV-enc",
|
||||
"AES-256-GCM-SIV-dec");
|
||||
}
|
||||
#endif /* WOLFSSL_AESGCM_SIV */
|
||||
#endif /* !NO_AES */
|
||||
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ void bench_aesctr(int useDeviceID);
|
||||
void bench_aescfb(void);
|
||||
void bench_aesofb(void);
|
||||
void bench_aessiv(void);
|
||||
void bench_aesgcmsiv(void);
|
||||
void bench_poly1305(void);
|
||||
void bench_camellia(void);
|
||||
void bench_sm4_cbc(void);
|
||||
|
||||
+1143
-6
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -53,6 +53,14 @@
|
||||
new_cpuid_flags |= CPUID_ADX;
|
||||
new_cpuid_flags |= CPUID_MOVBE;
|
||||
new_cpuid_flags |= CPUID_BMI1;
|
||||
#ifdef WOLFSSL_SGX_CPUID_AVX512_VAES
|
||||
/* CPUID is unavailable inside an SGX enclave, so the integrator
|
||||
* defines this macro to assert the target CPU implements VAES and
|
||||
* AVX512. This enables ALL VAES/AVX512-gated code (AES-GCM and the
|
||||
* rest), not just AES-GCM-SIV - only set it when that is true. */
|
||||
new_cpuid_flags |= CPUID_VAES;
|
||||
new_cpuid_flags |= CPUID_AVX512;
|
||||
#endif
|
||||
|
||||
(void)wolfSSL_Atomic_Uint_CompareExchange
|
||||
(&cpuid_flags, &old_cpuid_flags, new_cpuid_flags);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -59,9 +59,9 @@
|
||||
#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL)
|
||||
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_init()
|
||||
WC_OMIT_FRAME_POINTER void fe_init(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_init()
|
||||
WC_OMIT_FRAME_POINTER void fe_init(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -81,9 +81,9 @@ WC_OMIT_FRAME_POINTER void fe_init()
|
||||
|
||||
void fe_add_sub_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_add_sub_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_add_sub_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_add_sub_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_add_sub_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -296,9 +296,9 @@ WC_OMIT_FRAME_POINTER void fe_add_sub_op()
|
||||
|
||||
void fe_sub_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_sub_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sub_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_sub_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sub_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -372,9 +372,9 @@ WC_OMIT_FRAME_POINTER void fe_sub(fe r, const fe a, const fe b)
|
||||
|
||||
void fe_add_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_add_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_add_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_add_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_add_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -2498,9 +2498,9 @@ WC_OMIT_FRAME_POINTER void fe_cmov_table(fe* r, const fe* base, signed char b)
|
||||
#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 6)
|
||||
void fe_mul_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -2893,9 +2893,9 @@ WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
#else
|
||||
void fe_mul_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -3074,9 +3074,9 @@ WC_OMIT_FRAME_POINTER void fe_mul(fe r, const fe a, const fe b)
|
||||
#if defined(WOLFSSL_ARM_ARCH) && (WOLFSSL_ARM_ARCH < 6)
|
||||
void fe_sq_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -3362,9 +3362,9 @@ WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
#else
|
||||
void fe_sq_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,7 @@
|
||||
#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL)
|
||||
#include <wolfssl/wolfcrypt/fe_operations.h>
|
||||
|
||||
void fe_init()
|
||||
void fe_init(void)
|
||||
{
|
||||
__asm__ __volatile__ (
|
||||
"\n\t"
|
||||
@@ -229,8 +229,8 @@ int fe_isnonzero(const fe a)
|
||||
"orr %x[a], x1, x2\n\t"
|
||||
"orr x3, x3, x4\n\t"
|
||||
"orr %x[a], %x[a], x3\n\t"
|
||||
: [a] "+r" (a)
|
||||
:
|
||||
: [a] "r" (a)
|
||||
: "memory", "cc", "x1", "x2", "x3", "x4", "x5", "x6"
|
||||
);
|
||||
return (word32)(size_t)a;
|
||||
@@ -248,8 +248,8 @@ int fe_isnegative(const fe a)
|
||||
"adc x5, x4, xzr\n\t"
|
||||
"and %x[a], x1, #1\n\t"
|
||||
"eor %x[a], %x[a], x5, lsr 63\n\t"
|
||||
: [a] "+r" (a)
|
||||
:
|
||||
: [a] "r" (a)
|
||||
: "memory", "cc", "x1", "x2", "x3", "x4", "x5", "x6"
|
||||
);
|
||||
return (word32)(size_t)a;
|
||||
@@ -4362,7 +4362,7 @@ int curve25519_base(byte* r, const byte* n)
|
||||
/* Store */
|
||||
"stp x14, x15, [%x[r]]\n\t"
|
||||
"stp x16, x17, [%x[r], #16]\n\t"
|
||||
"mov x0, xzr\n\t"
|
||||
"mov %x[r], xzr\n\t"
|
||||
"ldp x29, x30, [sp], #0xb0\n\t"
|
||||
: [r] "+r" (r)
|
||||
: [n] "r" (n), [x2] "r" (x2)
|
||||
@@ -6969,7 +6969,7 @@ int curve25519(byte* r, const byte* n, const byte* a)
|
||||
/* Store */
|
||||
"stp x14, x15, [%x[r]]\n\t"
|
||||
"stp x16, x17, [%x[r], #16]\n\t"
|
||||
"mov x0, xzr\n\t"
|
||||
"mov %x[r], xzr\n\t"
|
||||
"ldp x29, x30, [sp], #0xc0\n\t"
|
||||
: [r] "+r" (r)
|
||||
: [n] "r" (n), [a] "r" (a)
|
||||
|
||||
@@ -8406,11 +8406,11 @@ int mlkem_cmp_neon(const byte* a, const byte* b, int sz)
|
||||
"orr v8.16b, v8.16b, v10.16b\n\t"
|
||||
"ext v9.16b, v8.16b, v8.16b, #8\n\t"
|
||||
"orr v8.16b, v8.16b, v9.16b\n\t"
|
||||
"mov x0, v8.d[0]\n\t"
|
||||
"subs x0, x0, xzr\n\t"
|
||||
"csetm w0, ne\n\t"
|
||||
: [sz] "+r" (sz)
|
||||
: [a] "r" (a), [b] "r" (b)
|
||||
"mov %x[a], v8.d[0]\n\t"
|
||||
"subs %x[a], %x[a], xzr\n\t"
|
||||
"csetm %w[a], ne\n\t"
|
||||
: [a] "+r" (a), [sz] "+r" (sz)
|
||||
: [b] "r" (b)
|
||||
: "memory", "cc", "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8",
|
||||
"v9", "v10", "v11"
|
||||
);
|
||||
@@ -9089,7 +9089,7 @@ unsigned int mlkem_rej_uniform_neon(sword16* p, unsigned int len, const byte* r,
|
||||
"b L_mlkem_rej_uniform_loop_lt_4_%=\n\t"
|
||||
"\n"
|
||||
"L_mlkem_rej_uniform_done_%=:\n\t"
|
||||
"mov x0, x12\n\t"
|
||||
"mov %x[p], x12\n\t"
|
||||
: [p] "+r" (p), [len] "+r" (len), [rLen] "+r" (rLen)
|
||||
: [r] "r" (r), [mask] "r" (mask), [q] "r" (q), [bits] "r" (bits),
|
||||
[indices] "r" (indices)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -59,9 +59,9 @@
|
||||
#if !defined(CURVE25519_SMALL) || !defined(ED25519_SMALL)
|
||||
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_init()
|
||||
WC_OMIT_FRAME_POINTER void fe_init(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_init()
|
||||
WC_OMIT_FRAME_POINTER void fe_init(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -81,9 +81,9 @@ WC_OMIT_FRAME_POINTER void fe_init()
|
||||
|
||||
void fe_add_sub_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_add_sub_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_add_sub_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_add_sub_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_add_sub_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -189,9 +189,9 @@ WC_OMIT_FRAME_POINTER void fe_add_sub_op()
|
||||
|
||||
void fe_sub_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_sub_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sub_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_sub_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sub_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -261,9 +261,9 @@ WC_OMIT_FRAME_POINTER void fe_sub(fe r, const fe a, const fe b)
|
||||
|
||||
void fe_add_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_add_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_add_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_add_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_add_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -1763,9 +1763,9 @@ WC_OMIT_FRAME_POINTER void fe_cmov_table(fe* r, const fe* base, signed char b)
|
||||
#ifdef WOLFSSL_ARM_ARCH_7M
|
||||
void fe_mul_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -2154,9 +2154,9 @@ WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
#else
|
||||
void fe_mul_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_mul_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -2326,9 +2326,9 @@ WC_OMIT_FRAME_POINTER void fe_mul(fe r, const fe a, const fe b)
|
||||
#ifdef WOLFSSL_ARM_ARCH_7M
|
||||
void fe_sq_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
@@ -2610,9 +2610,9 @@ WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
#else
|
||||
void fe_sq_op(void);
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op(void)
|
||||
#else
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op()
|
||||
WC_OMIT_FRAME_POINTER void fe_sq_op(void)
|
||||
#endif /* !WOLFSSL_NO_VAR_ASSIGN_REG */
|
||||
{
|
||||
#ifndef WOLFSSL_NO_VAR_ASSIGN_REG
|
||||
|
||||
@@ -877,6 +877,9 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t siphash_test(void);
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t poly1305_test(void);
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesgcm_test(void);
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesgcm_default_test(void);
|
||||
#ifdef WOLFSSL_AESGCM_SIV
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesgcm_siv_test(void);
|
||||
#endif
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t gmac_test(void);
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesccm_test(void);
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aeskeywrap_test(void);
|
||||
@@ -2857,6 +2860,12 @@ options: [-s max_relative_stack_bytes] [-m max_relative_heap_memory_bytes]\n\
|
||||
if (ret == 0) {
|
||||
TEST_PASS("AES-GCM test passed!\n");
|
||||
}
|
||||
#ifdef WOLFSSL_AESGCM_SIV
|
||||
if ((ret = aesgcm_siv_test()) != 0)
|
||||
TEST_FAIL("AES-GCM-SIV test failed!\n", ret);
|
||||
else
|
||||
TEST_PASS("AES-GCM-SIV test passed!\n");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_AESCCM) && defined(WOLFSSL_AES_128)
|
||||
@@ -20298,6 +20307,251 @@ static wc_test_ret_t aesgcm_aes256_large_test(Aes* enc, Aes* dec)
|
||||
}
|
||||
#endif /* WOLFSSL_AES_256 */
|
||||
|
||||
#ifdef WOLFSSL_AESGCM_SIV
|
||||
/* AES-GCM-SIV (RFC 8452) self test: known-answer vectors from RFC 8452
|
||||
* Appendix C (AES-128 C.1-2 and AES-256 C.2-2), an encrypt/decrypt round trip,
|
||||
* authentication-failure handling and invalid-parameter spot checks. The
|
||||
* exhaustive coverage lives in tests/api/test_aes.c. */
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesgcm_siv_test(void)
|
||||
{
|
||||
wc_test_ret_t ret = 0;
|
||||
#ifdef WOLFSSL_AES_128
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key128[16] = {
|
||||
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
#endif
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte nonce[12] = {
|
||||
0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte pt8[8] = {
|
||||
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
#ifdef WOLFSSL_AES_128
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte exp128[8] = {
|
||||
0xb5,0xd8,0x39,0x33,0x0a,0xc7,0xb7,0x86
|
||||
};
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte tag128[16] = {
|
||||
0x57,0x87,0x82,0xff,0xf6,0x01,0x3b,0x81,
|
||||
0x5b,0x28,0x7c,0x22,0x49,0x3a,0x36,0x4c
|
||||
};
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_256
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte key256[32] = {
|
||||
0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte exp256[8] = {
|
||||
0xc2,0xef,0x32,0x8e,0x5c,0x71,0xc8,0x3b
|
||||
};
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte tag256[16] = {
|
||||
0x84,0x31,0x22,0x13,0x0f,0x73,0x64,0xb7,
|
||||
0x61,0xe0,0xb9,0x74,0x27,0xe3,0xdf,0x28
|
||||
};
|
||||
#endif
|
||||
/* Multi-block (128-byte) known-answer vectors: exercise the 64-byte CTR
|
||||
* loop and its tail past the first block. Self-generated with the
|
||||
* software reference (which passes the Wycheproof suite) and independent
|
||||
* of any one asm backend; <=1-block vectors cannot catch CTR round-count
|
||||
* or counter-pointer bugs (e.g. the Windows MASM AES_GCMSIV_ctr defect). */
|
||||
#ifdef WOLFSSL_AES_128
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte keyBig128[16] = {
|
||||
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||
0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10
|
||||
};
|
||||
#endif
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte nonceBig[12] = {
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||
0x18,0x19,0x1a,0x1b
|
||||
};
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte aadBig[20] = {
|
||||
0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,
|
||||
0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
|
||||
0xb0,0xb1,0xb2,0xb3
|
||||
};
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte ptBig[128] = {
|
||||
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
|
||||
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
|
||||
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
|
||||
0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
|
||||
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
|
||||
0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
|
||||
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
|
||||
0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
|
||||
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
|
||||
0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
|
||||
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,
|
||||
0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
|
||||
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
|
||||
0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
|
||||
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
|
||||
0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
|
||||
};
|
||||
#ifdef WOLFSSL_AES_128
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte ctBig128Exp[128] = {
|
||||
0x4f,0x98,0x96,0x18,0x0d,0xc1,0x37,0x1f,
|
||||
0xf4,0xf1,0x7b,0x4b,0xff,0x28,0xd4,0x29,
|
||||
0x54,0x80,0x33,0xd0,0x7f,0xed,0xe0,0x23,
|
||||
0xd8,0x76,0x5d,0x28,0xad,0x2a,0x5e,0x37,
|
||||
0xeb,0xb7,0x64,0x87,0xb7,0x03,0x37,0xdd,
|
||||
0x72,0x5f,0xd1,0x1f,0xba,0xc2,0xdb,0x53,
|
||||
0x46,0x38,0xb9,0x30,0x5f,0x67,0x22,0x6b,
|
||||
0x96,0x10,0x06,0x36,0xe7,0xf5,0x88,0x53,
|
||||
0x5c,0x88,0x80,0xaf,0x83,0xc3,0x73,0x78,
|
||||
0xc4,0x59,0xb0,0x52,0x79,0x77,0xd3,0xdd,
|
||||
0x3f,0xfd,0x1f,0xed,0x34,0xaf,0xd2,0x53,
|
||||
0x4e,0xc2,0xb5,0x94,0x96,0xcd,0x03,0x11,
|
||||
0x52,0xcb,0x31,0x09,0x84,0x0f,0x8d,0xa4,
|
||||
0x4a,0x82,0x66,0xd9,0xb3,0xfe,0x22,0xa1,
|
||||
0xbc,0x04,0xb5,0x43,0x50,0x83,0xb9,0xd6,
|
||||
0x42,0xea,0xc5,0x75,0xe1,0x7f,0x42,0x04
|
||||
};
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte tagBig128Exp[16] = {
|
||||
0x6c,0x53,0xec,0xcc,0xd2,0x1b,0xdc,0x5a,
|
||||
0x45,0x7f,0x97,0xa4,0x79,0xb1,0x0c,0x52
|
||||
};
|
||||
#endif
|
||||
#ifdef WOLFSSL_AES_256
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte keyBig256[32] = {
|
||||
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,
|
||||
0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,
|
||||
0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,
|
||||
0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20
|
||||
};
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte ctBig256Exp[128] = {
|
||||
0x1a,0x16,0xea,0x46,0x31,0x0f,0x8e,0xe6,
|
||||
0x51,0x3a,0x56,0x0b,0x90,0xf6,0x3a,0x4e,
|
||||
0x09,0x25,0xf0,0x0a,0xfb,0xa5,0x58,0x36,
|
||||
0x9e,0xd7,0x96,0x59,0x24,0x8f,0xb6,0xdd,
|
||||
0xf1,0xc6,0xb6,0x75,0xf9,0x11,0x39,0x04,
|
||||
0x8d,0xa2,0xcb,0x0d,0x17,0x52,0x81,0x1b,
|
||||
0xf8,0x94,0xc4,0xd0,0x04,0xcc,0xcc,0xda,
|
||||
0xb6,0x85,0x26,0x66,0x40,0xaa,0xef,0x40,
|
||||
0xdb,0xbb,0xe1,0xbb,0x5e,0x57,0x0b,0x65,
|
||||
0x26,0x1c,0xde,0x3b,0x61,0xcd,0x96,0xb1,
|
||||
0xd9,0xe4,0x0b,0x13,0x2f,0xd3,0x48,0x41,
|
||||
0x58,0xa5,0xc7,0x33,0x45,0x03,0x3c,0xbf,
|
||||
0xe9,0x23,0x5e,0x6b,0x01,0xd0,0xe0,0x3a,
|
||||
0x90,0x81,0xd2,0x95,0x84,0x12,0x70,0x8e,
|
||||
0x79,0xdf,0xf4,0x95,0xbf,0x30,0x0c,0xad,
|
||||
0xe0,0x9a,0xa1,0x56,0xcd,0x70,0xd6,0x3b
|
||||
};
|
||||
WOLFSSL_SMALL_STACK_STATIC const byte tagBig256Exp[16] = {
|
||||
0xeb,0x69,0x16,0x9f,0x11,0xd4,0x59,0x7c,
|
||||
0xc0,0x81,0xe7,0xf6,0x79,0x5c,0x7c,0xbb
|
||||
};
|
||||
#endif
|
||||
byte ctBig[128];
|
||||
byte tagBig[16];
|
||||
byte decBig[128];
|
||||
|
||||
byte ct[8];
|
||||
byte tag[16];
|
||||
byte dec[8];
|
||||
|
||||
#ifdef WOLFSSL_AES_128
|
||||
/* AES-128 known-answer (encrypt). */
|
||||
ret = wc_AesGcmSivEncrypt(key128, sizeof(key128), nonce, sizeof(nonce),
|
||||
NULL, 0, pt8, sizeof(pt8), ct, tag, sizeof(tag));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (XMEMCMP(ct, exp128, sizeof(exp128)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
if (XMEMCMP(tag, tag128, sizeof(tag128)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
/* Decrypt round trip. */
|
||||
ret = wc_AesGcmSivDecrypt(key128, sizeof(key128), nonce, sizeof(nonce),
|
||||
NULL, 0, ct, sizeof(ct), dec, tag, sizeof(tag));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (XMEMCMP(dec, pt8, sizeof(pt8)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
/* Tampered tag must fail authentication. */
|
||||
tag[0] ^= 0xff;
|
||||
if (wc_AesGcmSivDecrypt(key128, sizeof(key128), nonce, sizeof(nonce),
|
||||
NULL, 0, ct, sizeof(ct), dec, tag, sizeof(tag)) !=
|
||||
WC_NO_ERR_TRACE(AES_GCM_AUTH_E))
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
tag[0] ^= 0xff;
|
||||
#endif /* WOLFSSL_AES_128 */
|
||||
|
||||
#ifdef WOLFSSL_AES_256
|
||||
/* AES-256 known-answer + round trip. */
|
||||
ret = wc_AesGcmSivEncrypt(key256, sizeof(key256), nonce, sizeof(nonce),
|
||||
NULL, 0, pt8, sizeof(pt8), ct, tag, sizeof(tag));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (XMEMCMP(ct, exp256, sizeof(exp256)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
if (XMEMCMP(tag, tag256, sizeof(tag256)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
ret = wc_AesGcmSivDecrypt(key256, sizeof(key256), nonce, sizeof(nonce),
|
||||
NULL, 0, ct, sizeof(ct), dec, tag, sizeof(tag));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (XMEMCMP(dec, pt8, sizeof(pt8)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
#endif /* WOLFSSL_AES_256 */
|
||||
|
||||
#ifdef WOLFSSL_AES_128
|
||||
/* AES-128 multi-block known-answer + round trip (128-byte plaintext). */
|
||||
ret = wc_AesGcmSivEncrypt(keyBig128, sizeof(keyBig128), nonceBig,
|
||||
sizeof(nonceBig), aadBig, sizeof(aadBig), ptBig, sizeof(ptBig),
|
||||
ctBig, tagBig, sizeof(tagBig));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (XMEMCMP(ctBig, ctBig128Exp, sizeof(ctBig128Exp)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
if (XMEMCMP(tagBig, tagBig128Exp, sizeof(tagBig128Exp)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
ret = wc_AesGcmSivDecrypt(keyBig128, sizeof(keyBig128), nonceBig,
|
||||
sizeof(nonceBig), aadBig, sizeof(aadBig), ctBig, sizeof(ptBig),
|
||||
decBig, tagBig, sizeof(tagBig));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (XMEMCMP(decBig, ptBig, sizeof(ptBig)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
#endif /* WOLFSSL_AES_128 */
|
||||
#ifdef WOLFSSL_AES_256
|
||||
ret = wc_AesGcmSivEncrypt(keyBig256, sizeof(keyBig256), nonceBig,
|
||||
sizeof(nonceBig), aadBig, sizeof(aadBig), ptBig, sizeof(ptBig),
|
||||
ctBig, tagBig, sizeof(tagBig));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (XMEMCMP(ctBig, ctBig256Exp, sizeof(ctBig256Exp)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
if (XMEMCMP(tagBig, tagBig256Exp, sizeof(tagBig256Exp)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
ret = wc_AesGcmSivDecrypt(keyBig256, sizeof(keyBig256), nonceBig,
|
||||
sizeof(nonceBig), aadBig, sizeof(aadBig), ctBig, sizeof(ptBig),
|
||||
decBig, tagBig, sizeof(tagBig));
|
||||
if (ret != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_EC(ret), out);
|
||||
if (XMEMCMP(decBig, ptBig, sizeof(ptBig)) != 0)
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
#endif /* WOLFSSL_AES_256 */
|
||||
|
||||
/* Invalid-parameter spot checks (NULL key; AES-192 key size rejected).
|
||||
* Key-size-agnostic (no key128) so these run in AES-256-only builds too;
|
||||
* both are rejected before the key bytes are read, so ptBig is just a
|
||||
* non-NULL pointer. */
|
||||
if (wc_AesGcmSivEncrypt(NULL, 16, nonce, sizeof(nonce),
|
||||
NULL, 0, pt8, sizeof(pt8), ct, tag, sizeof(tag)) !=
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG))
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
if (wc_AesGcmSivEncrypt(ptBig, 24, nonce, sizeof(nonce),
|
||||
NULL, 0, pt8, sizeof(pt8), ct, tag, sizeof(tag)) !=
|
||||
WC_NO_ERR_TRACE(BAD_FUNC_ARG))
|
||||
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
#endif /* WOLFSSL_AESGCM_SIV */
|
||||
|
||||
WOLFSSL_TEST_SUBROUTINE wc_test_ret_t aesgcm_test(void)
|
||||
{
|
||||
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
|
||||
|
||||
@@ -824,6 +824,30 @@ int wc_AesSivDecrypt_ex(const byte* key, word32 keySz, const AesSivAssoc* assoc,
|
||||
const byte* in, word32 inSz, byte* siv, byte* out);
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_AESGCM_SIV
|
||||
/* AES-GCM-SIV (RFC 8452): nonce-misuse resistant AEAD.
|
||||
* key : key-generating-key, 16 (AES-128) or 32 (AES-256) bytes.
|
||||
* nonce : 12 bytes.
|
||||
* tag : 16 bytes (the RFC 8452 authentication tag).
|
||||
* The encrypted output is the same length as the plaintext; the tag is
|
||||
* returned separately.
|
||||
*
|
||||
* The POLYVAL hash is constant-time wherever the CPU provides carry-less
|
||||
* multiply (x86 PCLMUL, Arm PMULL/VMULL) - the runtime default on such CPUs.
|
||||
* Software-only builds fall back to a key-dependent 4-bit table (a cache-timing
|
||||
* trade-off matching GCM_TABLE GHASH); GCM_SMALL avoids the table entirely. */
|
||||
WOLFSSL_API WARN_UNUSED_RESULT
|
||||
int wc_AesGcmSivEncrypt(const byte* key, word32 keySz, const byte* nonce,
|
||||
word32 nonceSz, const byte* aad, word32 aadSz,
|
||||
const byte* in, word32 inSz, byte* out,
|
||||
byte* tag, word32 tagSz);
|
||||
WOLFSSL_API WARN_UNUSED_RESULT
|
||||
int wc_AesGcmSivDecrypt(const byte* key, word32 keySz, const byte* nonce,
|
||||
word32 nonceSz, const byte* aad, word32 aadSz,
|
||||
const byte* in, word32 inSz, byte* out,
|
||||
const byte* tag, word32 tagSz);
|
||||
#endif /* WOLFSSL_AESGCM_SIV */
|
||||
|
||||
#ifdef WOLFSSL_CMAC
|
||||
/* forward declaration, in case aes.h is being included by cmac.h */
|
||||
struct Cmac;
|
||||
|
||||
Reference in New Issue
Block a user