Skip to content

cmac: take a NULL key in init as a restart with the cached key - #473

Open
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_11550
Open

yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_11550

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Problem

wp_cmac_init() only restarted the wolfSSL CMAC object when a key was supplied, so EVP_MAC_init(ctx, NULL, 0, NULL), the documented way to reset a MAC context while keeping the installed key, did nothing:

Reset point Result
After EVP_MAC_final() wc_CmacFinal() zeroes the Cmac, so the next EVP_MAC_update() returns 0
Mid-stream, before final the MAC silently covers msgA‖msgB instead of msgB, reporting success at every call

Separately, wp_cmac_update() and wp_cmac_final() accepted a context whose key install had failed. The FIPS bundles' wc_CmacUpdate()/wc_CmacFinal() validate only pointers, with no cmac->type check, so a context that never received a usable key returned a MAC computed with an all-zero AES key. Current non-FIPS wolfSSL rejects that via default: BAD_FUNC_ARG, which is why it reproduces only under FIPS.

Fix (src/wp_cmac.c)

  • wp_cmac_set_key() takes key == NULL as "keep the cached key, just restart": keyLen resolves from macCtx->keyLen, and a zero resolved length fails. A non-NULL key first wipes the whole cached key buffer and zeroes macCtx->keyLen, then runs the length and expKeySize checks, so a rejected key never leaves the previous key usable. A rejected key is wiped again, and macCtx->keyLen is assigned only after wc_InitCmac_ex() succeeds.
  • wp_cmac_init() calls it on every init, so the AES key schedule and the k1/k2 subkeys are re-derived.
  • wp_cmac_update() and wp_cmac_final() fail when macCtx->keyLen is 0, rather than relying on wolfSSL to reject an uninitialized Cmac.

A keyless restart after a rejected key now fails, matching OpenSSL's default provider.

Closes f_11550.

Tests

test_cmac_reinit, run against both OpenSSL and wolfProvider:

  • drives one EVP_MAC_CTX through keyless init after final and mid-stream, comparing every MAC against OpenSSL;
  • checks that a context whose key was never installed cannot produce a MAC through EVP_MAC_update()/EVP_MAC_final(), and that EVP_MAC_final() alone fails;
  • checks that a valid key replaced by a wrong-length key, through OSSL_MAC_PARAM_KEY and through EVP_MAC_init(), leaves a keyless EVP_MAC_init() failing.

Verification

  • Full unit suite green on non-FIPS (234/234) and against the v5.2.4 FIPS bundle (192/192); clean under -Werror; ASan + UBSan clean.
  • Negative controls: reverting wp_cmac.c fails the reinit and replaced-key legs; removing only the final guard fails the never-installed key case under FIPS.
  • Before the guards, a local FIPS build reproduced the PRB-fips-scripts-test failure exactly (test 22, CMAC produced a MAC from a key that was never set); it passes after.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Aug 26, 2026
Copilot AI lite review requested due to automatic review settings August 26, 2026 04:20

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes CMAC context reinitialization semantics so EVP_MAC_init(ctx, NULL, 0, NULL) correctly resets the CMAC state while retaining the cached key, aligning wolfProvider behavior with the documented EVP MAC contract and OpenSSL’s default provider behavior.

Changes:

  • Update wp_cmac_set_key() / wp_cmac_init() so a NULL key triggers a restart using the cached key (when present).
  • Add a unit test (test_cmac_reinit) that exercises reinit-after-final and mid-stream reset behavior and compares outputs against OpenSSL.
  • Wire the new CMAC reinit test into the unit test harness.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
test/unit.h Declares the new test_cmac_reinit unit test.
test/unit.c Registers test_cmac_reinit in the unit test list.
test/test_cmac.c Adds coverage for CMAC reset behavior (post-final and mid-stream) and OpenSSL equivalence checks.
src/wp_cmac.c Implements CMAC restart-on-init with cached key when key == NULL.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/wp_cmac.c

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #473

Scan targets checked: wolfprovider-bugs, wolfprovider-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Comment thread src/wp_cmac.c
Comment thread src/wp_cmac.c

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #473

Scan targets checked: wolfprovider-bugs, wolfprovider-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Comment thread test/test_cmac.c
Comment thread test/test_cmac.c

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #473

Scan targets checked: wolfprovider-bugs, wolfprovider-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Reported findings require changes before merge.

Comment thread src/wp_cmac.c
Comment thread src/wp_cmac.c

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #473

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.

@wolfSSL-Fenrir-bot
wolfSSL-Fenrir-bot dismissed stale reviews from themself August 27, 2026 00:16

Fenrir's latest completed scan found no issues; clearing the prior automated change request.

@yosuke-wolfssl

Copy link
Copy Markdown
Contributor Author

Jenkins retest please

@ColtonWilley ColtonWilley added the ci:all PR OSP toggle: run all label Sep 29, 2026
- wp_cmac_set_key() resolves a NULL key to the cached length in
  macCtx->keyLen and fails when that length is zero. A non-NULL key
  first wipes the whole cached key buffer and zeroes macCtx->keyLen,
  then runs the length, expKeySize and copy steps; a rejected key
  wipes the buffer again.
- The wc_InitCmac_ex()/wc_InitCmac() restart runs for any key,
  cached or supplied, and takes the resolved length; macCtx->keyLen
  is assigned after it succeeds.
- wp_cmac_init() calls wp_cmac_set_key() for every init.
- wp_cmac_update() and wp_cmac_final() fail when macCtx->keyLen is
  zero.
- The key parameter notes on wp_cmac_set_key() and wp_cmac_init()
  record that NULL restarts with the cached key.
- test_cmac_reinit drives one EVP_MAC_CTX through keyless init after
  final and mid-stream, comparing each MAC against OpenSSL, and
  checks that a keyless restart after a rejected key refuses both
  EVP_MAC_update() and EVP_MAC_final().
- test_cmac_reinit_stale_key checks that a valid key replaced by a
  wrong-length key, through OSSL_MAC_PARAM_KEY and through
  EVP_MAC_init(), leaves a keyless EVP_MAC_init() failing.
- test/unit.c and test/unit.h register test_cmac_reinit.

Issue: F-11550
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:all PR OSP toggle: run all

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants