gmac: clear the cached message on init - #474
Conversation
- wp_gmac_init() releases macCtx->data with OPENSSL_clear_free() and resets data and dataLen once the running check passes, before the parameters and key are applied. - test_gmac_reinit drives one EVP_MAC_CTX through init/update/final rounds plus an init mid-stream, re-supplying the IV on each init, and compares every MAC against OpenSSL. - test/unit.c and test/unit.h register the new test case. Issue: F-11551
There was a problem hiding this comment.
Pull request overview
This pull request fixes a correctness bug in the GMAC implementation where re-initializing an EVP_MAC_CTX could unintentionally authenticate previous_message || new_message due to a stale cached message buffer. It aligns wolfProvider behavior with OpenSSL’s expected “init resets state” semantics and adds a regression test to cover both post-final and mid-stream re-init cases.
Changes:
- Clear and free the cached GMAC message buffer during
wp_gmac_init()so each init starts a fresh message. - Add a new unit test (
test_gmac_reinit) that exercises re-init afterEVP_MAC_final()and re-init mid-stream while reusing the cached key, comparing results against OpenSSL. - Register the new GMAC re-init test in the unit test harness.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/wp_gmac.c |
Clears cached message data in wp_gmac_init() to prevent stale-data MAC concatenation across re-inits. |
test/test_gmac.c |
Adds test_gmac_reinit to validate correct behavior across GMAC context resets vs OpenSSL. |
test/unit.h |
Declares the new GMAC re-init unit test. |
test/unit.c |
Registers the new GMAC re-init unit test in the test case list. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #474
Scan targets checked: wolfprovider-bugs, wolfprovider-src
Fenrir result: Approved ✅
No new issues found in the changed files.
Advisory only — this automated result does not count as a GitHub approval.
Problem
wp_gmac_init()never cleared the cached message buffer. wolfSSL has nostreaming GMAC API, so
wp_gmac_update()accumulates the whole message inmacCtx->data/macCtx->dataLenandwp_gmac_final()feeds it to theone-shot
wc_GmacUpdate(); onlywp_gmac_free()andwp_gmac_dup()evertouched that buffer. Re-initializing a used
EVP_MAC_CTX— the documented wayto reuse one, and the natural GMAC pattern since every message needs a fresh IV
— therefore authenticated
previous_message || new_message, reporting successat every call. A wrong tag with no error.
OpenSSL's default provider resets on every init path (
gmac_init()alwayscalls
EVP_EncryptInit_ex()), and OpenSSL'sevp_testre-inits and re-runsevery MAC KAT, so
scripts/test-openssl.shreproduces this today: all nineGMAC entries in
scripts/evp_test/evpmac_common.txtfail withTEST_MAC_ERR.Same defect class as f_11550 (CMAC, PR #473); this is its GMAC sibling.
Fix (
src/wp_gmac.c)wp_gmac_init()discards the cached message once the running check passes andbefore the parameters and key are applied, so every init starts a new message:
OPENSSL_clear_free()cleanses the plaintext and releases theallocation, keeping
dataLenequal to the allocated size — the invariantwp_gmac_free()andwp_gmac_dup()both rely on for a correct cleanse andmemdup.
data = NULL; dataLen = 0sowp_gmac_update()'s nextOPENSSL_realloc()starts clean.Clearing in init covers both a reset after
finaland a reset mid-stream, sowp_gmac_final()is unchanged. No re-keying is needed —wc_GmacUpdate()is aone-shot over an already-keyed
Gmac.Closes f_11551.
Tests
test_gmac_reinitdrives oneEVP_MAC_CTXthrough init/update/final roundsand an init mid-stream, re-supplying the IV on each init as
evp_testdoes,and compares every MAC against OpenSSL.
Verification
-Werror.GMAC after reset doesn't match the first MAC— while the OpenSSL half of the same test passes.evp_testonevpmac_common.txt: 11 errors → 2. All nine GMAC failuresclear; the two remaining CMAC failures are PR cmac: take a NULL key in init as a restart with the cached key #473.