Skip to content

wolfcrypt: add Caliptra Root of Trust CryptoCb port#10579

Open
MarkAtwood wants to merge 2 commits into
masterfrom
feature/caliptra
Open

wolfcrypt: add Caliptra Root of Trust CryptoCb port#10579
MarkAtwood wants to merge 2 commits into
masterfrom
feature/caliptra

Conversation

@MarkAtwood
Copy link
Copy Markdown
Contributor

wolfcrypt: add Caliptra Root of Trust CryptoCb port

Adds a CryptoCb backend that offloads RNG, SHA-384/512, AES-256-GCM,
HMAC-SHA-384/512, and ECDSA P-384 (sign + verify) to a Caliptra security
processor via an integrator-supplied mailbox transport.

Caliptra is an
open-standard hardware Root of Trust developed under CHIPS Alliance.
Offloading these primitives keeps key material inside the Caliptra
security boundary and enables hardware attestation for constrained
and secure-boot environments. OCP / Open Compute is on track to
mandate a hardware RoT on mainboards within ~18 months, and Caliptra
is one of the leading reference designs.

What's in this PR

Configure flag Default Effect
--enable-caliptra off Compiles the port (wolfcrypt/src/port/caliptra/caliptra_port.c) and implies --enable-cryptocb
--enable-caliptra-sim / --disable-caliptra-sim on when --enable-caliptra is on Links the bundled software simulator (sim/caliptra_sim.c) into libwolfssl, providing a caliptra_mailbox_exec() implementation for host-side testing

Production builds that supply their own caliptra_mailbox_exec()
implementation (real hardware mailbox, FPGA bench, etc.) pass
--enable-caliptra --disable-caliptra-sim. The library then builds
with caliptra_mailbox_exec as an undefined symbol that the
integrator resolves at final link time.

How the offload works

wc_AesGcmEncrypt, wc_Sha384Update, wc_HmacFinal, etc. dispatch
through the existing WOLF_CRYPTO_CB framework when aes->devId == WOLF_CALIPTRA_DEVID. The port translates each call into the
appropriate Caliptra Cryptographic Mailbox command
(CM_AES_GCM_ENCRYPT_INIT, CM_SHA_INIT/UPDATE/FINAL, CM_HMAC,
CM_ECDSA_SIGN, CM_ECDSA_VERIFY, CM_RANDOM_GENERATE) and ships
it to the integrator-supplied caliptra_mailbox_exec() function.

Key import is via wc_caliptra_import_key() which returns an opaque
CaliptraCmk handle the application stores in the wolfSSL object's
devCtx. Streaming SHA contexts (heap-allocated CaliptraShaCtx) are
released by WOLF_CRYPTO_CB_FREE.

AES-GCM IV semantics

Caliptra's CM_AES_GCM_ENCRYPT_INIT command always generates the IV in
firmware (see caliptra/runtime/README.md § CM_AES_GCM_ENCRYPT_INIT
and caliptra/api/src/mailbox.rs::CmAesGcmEncryptInitReq — the
request struct has no IV field). The port reflects this: callers pass
a 12-byte placeholder buffer (required by wc_AesGcmEncrypt's argument
validation), the port silently ignores its contents, and the
firmware-generated IV is retrieved via the helper
wc_caliptra_aesgcm_get_iv() before being passed to subsequent
decrypt operations. This is documented in caliptra_port.c:710-715.

Testing

wolfcrypt/test/test.c gains 12 caliptra subtests covering every
offloaded primitive:

caliptra_test: RNG passed
caliptra_test: SHA-384 passed
caliptra_test: SHA-512 passed
caliptra_test: SHA-384 streaming (single-update) passed
caliptra_test: SHA-512 streaming (two-update) passed
caliptra_test: SHA-384 streaming (zero-length update) passed
caliptra_test: AES-256-GCM KAT (decrypt) passed
caliptra_test: AES-256-GCM round-trip passed
caliptra_test: AES-GCM authentication failure detection passed
caliptra_test: HMAC-SHA-384 passed
caliptra_test: ECDSA P-384 sign+verify passed
caliptra_test: ECDSA P-384 negative verify passed

Verified configurations:

  • ./configure && make && make check5 PASS, 4 SKIP, 0 FAIL
    (default build, no caliptra; rebase against upstream/master is clean)
  • ./configure --enable-all && make && make check17 PASS, 5 SKIP,
    0 FAIL
    (everything-on smoke; caliptra correctly stays off)
  • ./configure --enable-caliptra && make && make check5 PASS,
    4 SKIP, 0 FAIL
    (caliptra subtests included via testsuite)
  • ./configure --enable-caliptra --disable-caliptra-sim && make src/libwolfssl.la — clean library build; subsequent example/test
    binaries fail to link with the expected undefined reference to caliptra_mailbox_exec, confirming the production path works as
    designed

Test vectors are bound by independent oracles: AES-256-GCM KAT from
NIST CAVP, ECDSA P-384 cross-validated through encrypt-then-decrypt
round-trips, HMAC-SHA-384 cross-checked against wolfSSL software HMAC,
SHA streaming variants exercise every path through the port
(Init-only, Init+Update, single Update, multi-Update,
zero-length Update).

A hardware-model test harness for real Caliptra firmware lives in
wolfcrypt/src/port/caliptra/sim/ with its own standalone Makefile.

Known scope limitations (deferred to follow-up PRs)

  1. No SetKey dispatch. A SetKey-callback path
    (WOLF_CRYPTO_CB_SETKEY) for AES, HMAC, and ECC was prototyped but
    omitted from this PR because it depends on a one-line fix to
    wolfcrypt/src/aes.c GCM key-schedule logic. The existing guard at
    aes.c:7855 checks WOLF_CRYPTO_CB_AES_SETKEY but should also
    check the newer generic WOLF_CRYPTO_CB_SETKEY to skip the
    software-side H subkey generation when the SE owns the key.
    Without that, wc_AesGcmSetKey returns KEYUSAGE_E (-226) because
    the rounds count is left at 0. A follow-up PR will propose the
    one-line core fix; a third PR will then re-introduce SetKey wiring
    to this port. Users today integrate via the explicit pattern
    (wc_caliptra_import_key() + manual aes.devCtx = &cmk).
  2. AES-GCM streaming chunked input. The port currently rejects
    single-Update payloads exceeding CMB_MAX_DATA_SIZE (4096 bytes).
    Chunked input across multiple CM_AES_GCM_ENCRYPT_UPDATE calls
    is wire-protocol-supported and can be added later without a
    public API change.

Review notes

  • All file additions are confined to:
    • wolfcrypt/src/port/caliptra/ (port + sim + hwmodel test harness)
    • wolfssl/wolfcrypt/port/caliptra/ (public header)
  • Existing files modified:
    • configure.ac — adds --enable-caliptra, --enable-caliptra-sim
    • wolfcrypt/src/include.am, wolfssl/wolfcrypt/include.am — wires
      the conditional sources
    • wolfcrypt/test/test.c — appends caliptra_test() and its dispatch
    • .gitignore — ignores sim build artifacts
  • No changes to any existing wolfSSL source under wolfcrypt/src/ or
    src/. The port is purely additive to core wolfSSL.

Branch / rebase status

This branch is rebased onto current master (tip at PR creation:
4c0c093fe) and consists of 2 commits. No fixup commits remain (an
earlier round of skoll-driven fixups was autosquashed before push).

Copilot AI review requested due to automatic review settings June 2, 2026 23:14
@MarkAtwood MarkAtwood marked this pull request as draft June 2, 2026 23:17
@MarkAtwood
Copy link
Copy Markdown
Contributor Author

Converting to draft. Please hold review on this PR — there's a small wolfSSL core fix that should land first (a one-line guard extension at wolfcrypt/src/aes.c:7855 so generic WOLF_CRYPTO_CB_SETKEY cryptocb users benefit from the same GCM H subkey skip as WOLF_CRYPTO_CB_AES_SETKEY users). I'll open that core PR separately. Once it merges, I'll mark this Caliptra port PR ready for review and follow up with the SetKey re-introduction in a third PR.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new wolfCrypt CryptoCb backend for the Caliptra Root of Trust mailbox interface, plus an optional in-tree simulator transport and corresponding wolfCrypt test coverage. This integrates Caliptra offload into the existing WOLF_CRYPTO_CB dispatch model and wires it into autoconf/automake so integrators can either link the simulator or provide their own caliptra_mailbox_exec() at final link time.

Changes:

  • Introduces the Caliptra port implementation (caliptra_port.c) and public mailbox/ABI definitions (caliptra_port.h).
  • Adds an optional bundled mailbox simulator + hw-model harness under wolfcrypt/src/port/caliptra/sim/.
  • Extends build system + wolfCrypt tests to build/execute Caliptra subtests when enabled.

Reviewed changes

Copilot reviewed 13 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
wolfssl/wolfcrypt/port/caliptra/caliptra_port.h New public Caliptra mailbox protocol definitions + public API declarations for the port.
wolfcrypt/src/port/caliptra/caliptra_port.c New CryptoCb callback implementation routing RNG/SHA/AES-GCM/HMAC/ECDSA to Caliptra via caliptra_mailbox_exec().
wolfcrypt/src/port/caliptra/README.md Port documentation: build flags, limitations, usage patterns, and testing instructions.
wolfcrypt/src/port/caliptra/sim/caliptra_sim.c Bundled software simulator implementation of caliptra_mailbox_exec() for host-side testing.
wolfcrypt/src/port/caliptra/sim/caliptra_test.c Standalone test harness for simulator/hw-model transports (outside the normal test suite).
wolfcrypt/src/port/caliptra/sim/caliptra_hwmodel.c hw-model mailbox transport implementation (test-only) using the Caliptra hw-model C binding.
wolfcrypt/src/port/caliptra/sim/caliptra_hwmodel.h Declarations for hw-model init/cleanup (test-only).
wolfcrypt/src/port/caliptra/sim/caliptra_top_reg.h Minimal synthesized Caliptra register offsets/constants used by the hw-model transport.
wolfcrypt/src/port/caliptra/sim/Makefile Standalone Makefile to build/run the hw-model test binary against Caliptra firmware.
wolfssl/wolfcrypt/include.am Installs/exposes the new public Caliptra header under the appropriate build conditional.
wolfcrypt/src/include.am Adds the port and (optionally) simulator sources to libwolfssl build + distribution list.
configure.ac Adds --enable-caliptra and --enable/disable-caliptra-sim flags; forces CryptoCb on when Caliptra enabled.
wolfcrypt/test/test.c Adds caliptra_test() and wires it into the main wolfCrypt test runner under WOLFSSL_CALIPTRA && WOLF_CRYPTO_CB.
.gitignore Ignores Caliptra sim/hw-model build artifacts and some tool state directories.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +50 to +53
* wolfSSL device IDs are int; the only reserved value is INVALID_DEVID (-2).
* In-tree ports use small positive integers (1, 2, 3...) for named hardware;
* this port uses 0x43414C50 ("CALP" in ASCII, 1128808528 as a signed int) to
* avoid guessing a small integer that might collide with another port.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. The decimal was off; the actual value of 0x43414C50 is 1128352848, not 1128808528. Corrected in the autosquashed branch (commit 7c52321).

Comment thread wolfcrypt/test/test.c
Comment on lines +75566 to +75572
ret = (wc_test_ret_t)wc_CryptoCb_RegisterDevice(WOLF_CALIPTRA_DEVID,
wc_caliptra_cb, NULL);
if (ret != 0) {
printf("caliptra_test: wc_CryptoCb_RegisterDevice failed %d\n",
(int)ret);
return WC_TEST_RET_ENC_EC(ret);
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed. wc_CryptoCb_RegisterDevice failure path now calls wc_caliptra_cleanup() before returning. Fixed in the autosquashed branch (commit 7c52321).

Comment on lines +442 to +449
if (status == MBOX_STATUS_CMD_FAILURE) {
mbox_write(MBOX_CSR_MBOX_EXECUTE, 0u);
caliptra_model_step(g_model);
fprintf(stderr,
"caliptra_mailbox_exec: CMD_FAILURE for cmd 0x%08X\n",
(unsigned)cmd_id);
return -EIO;
}
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already fixed in the autosquashed branch (commit ab44f06). The hwmodel transport now returns SIG_VERIFY_E specifically for CM_ECDSA_VERIFY CMD_FAILURE, while keeping the generic -EIO for all other commands. Includes the two header includes (error-crypt.h for SIG_VERIFY_E, caliptra_port.h for CM_ECDSA_VERIFY).

@MarkAtwood
Copy link
Copy Markdown
Contributor Author

The core fix is now open as #10580. Once that lands, I'll mark this PR ready for review.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

MemBrowse Memory Report

No memory changes detected for:

Adds a CryptoCb backend that offloads SHA-384/512, AES-256-GCM,
HMAC-SHA-384/512, ECDSA P-384 sign+verify, and RNG to a Caliptra
security processor via a user-supplied mailbox hook.

Caliptra is an open-standard hardware Root of Trust; offloading to it
keeps key material inside the security boundary and enables hardware
attestation for constrained and secure-boot environments.

Includes a standalone simulator and test harness in audit/ for
development without hardware, and KATs in wolfcrypt/test/test.c.
Add caliptra_hwmodel.c/h, caliptra_top_reg.h, and Makefile to build
and run caliptra_test.c against real Caliptra firmware via the
chipsalliance/caliptra-sw hw-model C binding. All 9 tests pass.

Fix ECDSA test: use the same 48-byte random seed for both sign_cmk and
verify_cmk. Caliptra derives the key pair from the seed, so both sides
must share it for hardware-to-hardware round-trip to work.

Fix HMAC test: compute and fill hdr.chksum before the direct
caliptra_mailbox_exec call; firmware rejects requests with chksum=0.

Update README: add step-by-step hw-model test instructions and correct
the ECDSA verify section (seed-based derivation, not 96-byte import).
@MarkAtwood
Copy link
Copy Markdown
Contributor Author

Force-pushed updates: all 3 Copilot findings addressed (replies in-thread above), plus a self-review pass via our internal review tool surfaced 47 additional findings (3 HIGH, 18 MEDIUM, 20 LOW, 6 INFO). 34 of those have code fixes in this push; the remaining 13 are tagged WONTFIX-DEFENSIBLE or PARTIAL with rationale tracked internally.

Summary of substantive changes since the initial draft:

  • HIGH: AES-GCM decrypt sim restructured to use wc_AesGcmEncrypt for CTR-mode symmetry (avoids depending on undocumented "output-before-auth" wolfSSL behavior); AAD overflow rejected in sim instead of silently truncated; sim now serialized via a single mailbox mutex (defense for multi-threaded callers when sim is linked into libwolfssl).
  • MEDIUM: ConstantCompare for GCM tag comparison in sim; CALIPTRA_FREE_SENSITIVE applied to all secret-bearing buffers; req/resp bounds checks at sim handlers; WOLF_CRYPTO_CB_FREE requirement promoted from #warning to #error; AES-256-only enforcement in sim init; sim default-on signposting via configure warning + compile #pragma + README; libc → X-wrappers throughout sim; HMAC streaming WC_HW_E test coverage; ECDSA test refactored to standard key-import idiom; NULL-tag defense in encrypt; aes->reg cleared on encrypt error; plaintext zeroed on any decrypt error (not just auth-fail).
  • LOW + INFO: zeroization sweep on cleanup paths; input-validation tightening; tag_verified != 1 (fail-safe) instead of == 0 (fail-open); empty-message and SHA-512 abort tests; documentation fixes including the DEVID decimal noted by Copilot.

caliptra subtest count: 12 → 18 (added empty-message GCM round-trip, SHA-512 abort-cleanup, HMAC streaming rejection, wc_caliptra_req_chksum KAT against the upstream Caliptra test vector).

Still draft until the prerequisite core fix in #10580 (one-line aes.c:7855 guard extension) lands.

@MarkAtwood MarkAtwood marked this pull request as ready for review June 3, 2026 02:45
@MarkAtwood
Copy link
Copy Markdown
Contributor Author

Marking ready for review. On reflection the prior draft hold was incorrect — this PR is self-contained and has no dependency on #10580. The WOLF_CRYPTO_CB_SETKEY code path that needs #10580's core fix is on a separate branch and will land as a third followup PR after both this one and #10580 merge.

The two PRs (this and #10580) can be reviewed and merged independently in either order.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 3, 2026

retest this please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants