Skip to content

Add a Linux user space backend for the CAAM port - #11197

Draft
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:caam_linux
Draft

Add a Linux user space backend for the CAAM port#11197
dgarske wants to merge 1 commit into
wolfSSL:masterfrom
dgarske:caam_linux

Conversation

@dgarske

@dgarske dgarske commented Aug 18, 2026

Copy link
Copy Markdown
Member

Description

wolfSSL's CAAM port has only ever run on i.MX, under QNX, INTEGRITY, SECO and MCUXpresso, and its driver core has never been built for Linux or for PowerPC. This adds a Linux user space backend so that same core drives NXP's SEC from a normal process, developed and tested against a QorIQ T1040. It implements the eleven-function port seam already declared in caam_driver.h (caam_linux.c) plus in-process request dispatch replacing QNX's resource-manager IPC (wolfcaam_linux.c), and is enabled with --enable-caam=linux. AES-CBC/CTR/ECB and the TRNG are accelerated; everything else returns CRYPTOCB_UNAVAILABLE and runs in software. Changes to shared code are three small guards: WOLFSSL_CAAM_NO_SM for parts without the i.MX secure memory block, a WOLFSSL_CAAM_LINUX arm in the environment selection, and an #ifndef around caam_driver.h's WOLFSSL_MSG so building the driver into the library no longer silently replaces wolfSSL's logging in every CAAM translation unit.

Two platform constraints drive the design and are documented in wolfcrypt/src/port/caam/README.md. The in-tree caam driver claims all four job rings and sets MCFGR[PS] for 64-bit descriptor pointers; MCFGR is global to the block, so a user space driver writing 32-bit pointer words has to take the whole engine rather than share it, and unbinding leaves that driver's interrupt handler registered, so the port masks the ring interrupt when it claims the ring. Separately, ordinary user pages are neither physically contiguous nor below 4 GB on a 36-bit part, so engine buffers are carved from a physical range Linux is told not to manage with mem=.

Testing

On a T1040D4RDB running its stock Linux 3.12, testwolfcrypt cross-compiled for 32-bit big-endian PowerPC passes 44/44 with 0 failures, with RANDOM and all AES tests executing on the engine. Offload was confirmed rather than assumed: forcing the AES dispatch to fail makes the AES tests fail, and a standalone probe matches the NIST SP 800-38A AES-128-CBC vector byte for byte. --enable-all on x86-64 builds and passes unchanged.

Throughput is worth stating plainly: on this part the engine is slower than software AES, 0.51x at 512 B rising to 0.60x at 16 KB (27.75 vs 46.31 MiB/s), because per-job cost dominates - two copies to stage operands through the reserved pool, a descriptor build, and a polled completion - and the e5500's software AES is quick. The reason to enable this is the TRNG as a real entropy source and moving work off the core, not throughput. The README says so and lists what would close the gap.

The existing sec_qoriq branch is untouched and remains a separate PR.

@dgarske
dgarske requested review from JacobBarthelmeh and a lite review from Copilot August 18, 2026 19:14
@dgarske dgarske self-assigned this Aug 18, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Adds a Linux user-space backend for wolfSSL’s CAAM/SEC port so the existing CAAM driver core can run in-process on Linux (e.g., QorIQ T1040), enabled via --enable-caam=linux.

Changes:

  • Introduces Linux environment/port-layer headers and implementations (caam_linux.*, wolfcaam_linux.*) plus build-system wiring.
  • Updates CAAM shared headers/driver core to support Linux selection and optionally disable secure-memory features (WOLFSSL_CAAM_NO_SM) without breaking logging.
  • Expands CAAM documentation with Linux setup/constraints and performance notes.

Reviewed changes

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

Show a summary per file
File Description
wolfssl/wolfcrypt/settings.h Enables CAAM + disables unsupported CAAM features when WOLFSSL_CAAM_LINUX is set.
wolfssl/wolfcrypt/port/caam/wolfcaam_linux.h Declares the Linux shim interface and request-dispatch entry points.
wolfssl/wolfcrypt/port/caam/wolfcaam.h Selects the Linux shim header and guards secure-memory APIs.
wolfssl/wolfcrypt/port/caam/caam_linux.h Defines Linux userspace types/macros the CAAM driver core expects.
wolfssl/wolfcrypt/port/caam/caam_driver.h Adds Linux environment selection + avoids overriding wolfSSL logging macros.
wolfssl/wolfcrypt/include.am Installs/ships new CAAM Linux headers.
wolfcrypt/src/port/caam/wolfcaam_linux.c Implements in-process “send request” + staging for AES/TRNG.
wolfcrypt/src/port/caam/caam_linux.c Implements CAAM driver-core OS seam for Linux userspace (/dev/mem + reserved DMA pool).
wolfcrypt/src/port/caam/caam_error.c Enables CAAM error support when building for Linux.
wolfcrypt/src/port/caam/caam_driver.c Adds WOLFSSL_CAAM_NO_SM guards around secure-memory code paths.
wolfcrypt/src/port/caam/README.md Documents Linux user-space backend setup and constraints.
wolfcrypt/src/include.am Builds CAAM core + Linux port pieces into the library when enabled.
configure.ac Adds --enable-caam=linux option and Automake conditional.

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

Comment on lines +86 to +90
map = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, caamMemFd,
(off_t)phys);
if (map == MAP_FAILED) {
WOLFSSL_MSG("caam: could not map physical range");
return NULL;
Comment on lines +90 to +96
if (!caamLockInit) {
if (wc_InitMutex(&caamLock) != 0) {
WOLFSSL_MSG("caam: could not create the request mutex");
return WC_HW_E;
}
caamLockInit = 1;
}
Comment on lines +115 to +120
void wc_CAAMFreeInterface(void)
{
if (caamInitDone) {
CleanupCAAM();
caamInitDone = 0;
}
Comment on lines +134 to +137
if (caamLockInit) {
wc_FreeMutex(&caamLock);
caamLockInit = 0;
}
Comment on lines +122 to +132
/* Leave nothing behind in the shared pool, then drop the pointers so a
* later init cannot reuse them. */
if (caamKeyBuf != NULL) {
ForceZero(caamKeyBuf, CAAM_LINUX_KEY_MAX + CAAM_LINUX_IV_MAX +
CAAM_LINUX_ENT_MAX + (2 * CAAM_LINUX_AES_MAX));
}
caamKeyBuf = NULL;
caamIvBuf = NULL;
caamInBuf = NULL;
caamOutBuf = NULL;
caamEntBuf = NULL;
Comment on lines +31 to +33
* what the shim layer itself refers to. */
#define DataBuffer 0
#define LastBuffer 0
(void)vaddr;
(void)sz;

__asm__ __volatile__("sync" ::: "memory");
Comment on lines +219 to +228
if (buf[0].Length <= 0 || buf[inIdx].Length <= 0 ||
buf[outIdx].Length <= 0 || (ivIdx && buf[1].Length <= 0)) {
return Failure;
}
if (buf[0].Length > CAAM_LINUX_KEY_MAX ||
buf[inIdx].Length > CAAM_LINUX_AES_MAX ||
buf[outIdx].Length > CAAM_LINUX_AES_MAX ||
(ivIdx && buf[1].Length > CAAM_LINUX_IV_MAX)) {
return CRYPTOCB_UNAVAILABLE;
}

caamDescInit(&desc, type, args, dma, outIdx + 1);
if (caamAes(&desc, dma, args) == Success) {
XMEMCPY((void*)buf[outIdx].TheAddress, caamOutBuf, buf[outIdx].Length);
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