You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
sizeof(mcrypt_sha256_t)=120, sizeof(mcrypt_hmac_sha256_t)=192, and
sizeof(mcrypt_aes128_t)=184 on the measured 64-bit ABI; HMAC context
storage changed from 320 B to 192 B.
GCC 13.3.0 -O2 -fstack-usage: SHA transform stack changed from 384 B on
the 2.1 cleanup baseline to 192 B using the cleared 16-word schedule. SHA
final remained 256 B; HMAC init/final measured 224 B/240 B.
SHA-256 and HMAC-SHA256 OpenSSL differential soaks each passed 100,000
deterministic boundary-biased cases. The GCC suite also passed the 50,000
case OpenSSL GCM soak.
The prior local GCC benchmark found SHA reductions of 13.0% to 15.5% and
HMAC reductions of 7.2% to 17.4%, depending on message size; this is the
documented RAM/stack versus throughput tradeoff.
2.1.0 release-cleanup rerun
Hash-pinned NIST GCMVS archive (f9fc479e...f26a023) rerun: 375 encrypt,
179 valid decrypt, and 196 invalid decrypt cases passed; no unexpected
accepts, crypto failures, or parser errors.
Strict GCC and Clang suites, ASan+UBSan, i386 runtime, s390x QEMU runtime,
Cortex-M4 compile, GCM-disabled build, static-only BUILD_SHARED_LIBS=ON,
and a relocatable installed-package consumer test passed.
SHA-256 / HMAC-SHA256 footprint optimization
GCC 13.3.0 -O2 -fstack-usage: SHA transform stack changed from 368 to
192 bytes after replacing the 64-word schedule with a cleared 16-word ring
buffer. SHA final remained 240 bytes. The GCC object .text size changed
from 14,581 to 14,517 bytes.
mcrypt_hmac_sha256_t changed from 320 to 192 bytes on the measured
64-bit ABI. The 128-byte reduction removes stored normalized-key and inner
pad data; only the outer pad remains until HMAC finalization. This public
layout change is ABI-breaking.
Clang ASan+UBSan full self-test passed with a 1,000-case deterministic
differential subset; the separately run full GCC/OpenSSL soak above used
the default 100,000 cases for each primitive.
The ring schedule trades throughput for stack: the local GCC benchmark saw
SHA changes of -13.0% (64 B), -14.9% (1 KiB), -15.2% (64 KiB), and -15.5%
(1 MiB); HMAC changes were -7.2%, -11.7%, -17.4%, and -16.6% respectively.
NIST AES-GCM vectors covered: empty plaintext, one zero block, and the published non-empty AAD/multi-block/partial-block vector.
The OpenSSL GCM differential oracle ran 512 deterministic random cases, including successful decrypt and corrupted-tag rejection.
AES-128-GCM destructive verification
A regression test found and fixed order-dependent AES-GCM encryption when AAD overlapped the payload output. The API now rejects metadata/payload aliasing with MCRYPT_ERR_OVERLAP; exact payload in-place operation remains supported.
WSL Ubuntu GCC 13.3.0, strict C99, -O3: OpenSSL-backed exhaustive matrix of 33,540 cases (plaintext_len=0..257, aad_len=0..129) and a 50,000-case boundary-biased deterministic soak both passed.
WSL Ubuntu Clang 18.1.3, ASan+UBSan: the exhaustive matrix and a 5,000-case deterministic soak passed without sanitizer findings.
tests/gcm_external_runner.py --parser-selftest passed before corpus execution. It checks valid encrypt/decrypt records, decrypt FAIL, missing PT/CT/tag fields, incompatible IV/tag/key sizes, and an unsupported response-file type.
Skipped 46,500: response files outside the selected known-answer response-file types or records outside AES-128/96-bit-IV/128-bit-tag API profile. Incomplete compatible records: 0.
These are official published test vectors only; using them does not constitute CAVP or FIPS validation/certification of this project.
API-compatible cases: 67; valid 40/40 passed; invalid 27/27 rejected; acceptable 0; failures 0; skipped 249 for AES key, IV, or tag length outside the supported profile.
Wycheproof vectors are test material and are not a formal security audit.
32-bit attempt, WSL Ubuntu GCC 13.3.0, gcc -m32:
A 32-bit object compiled when the -Wtype-limits diagnostic was not promoted (ELF 32-bit). No runtime was available.
The fully strict attempt stopped on gcm_lengths_valid: on a 32-bit size_t, casts of aad_len and payload_len to uint64_t can never exceed UINT64_MAX / 8. This is a redundant guard on that target, not a demonstrated arithmetic/runtime defect; production code was not changed.
BIG_ENDIAN_RUNTIME_HARNESS: PASS: AES block encrypt/decrypt KAT; empty and one-block GCM NIST vectors; NIST AAD/multi-block/partial-block vector; authentication failures for changed tag, ciphertext, AAD, nonce, and key, including out-of-place zeroisation and in-place preservation; and an OpenSSL-generated 88-case boundary corpus (11 payload lengths x 8 AAD lengths). Total checks 198, failures 0.
FULL_BIG_ENDIAN_SELF_TEST: PASS: cross-compiled tests/test_all.c ran under QEMU with 21 tests, 6,334 assertions, and 0 failures. The OpenSSL differential branch was unavailable on the target and reported NOT VERIFIED, not a passing differential test.
A first temporary harness run failed only because its manually transcribed NIST key used 8a where the project NIST vector uses 8f; after correcting the temporary test input, all checks passed. This was a harness transcription error, not a production-code defect.
AES-128-GCM 32-bit strict portability fix
gcm_lengths_valid formerly compared 32-bit size_t values, after conversion to uint64_t, with UINT64_MAX / 8. GCC correctly diagnosed both comparisons as always false on i386.
The bit-length overflow guard is now compiled only where SIZE_MAX > UINT64_MAX / 8; the 32-bit path does not compile impossible comparisons. This is a strict-warning portability fix only: no GCM algorithm, limit, or public API changed.
WSL Ubuntu GCC 13.3.0 i386: the required unsuppressed gcc -m32 strict source compile passed and produced an ELF 32-bit object. A full -m32 CMake build and ctest self-test run also passed (1/1).
The large-length validation regression covers UINT64_MAX / 8, the next value, and SIZE_MAX on platforms where those values fit in size_t; it uses small buffers and validation rejects before payload processing. On 32-bit, the corresponding fake ranges are rejected by overlap validation because their bit lengths themselves are representable.