Skip to content

linuxkm: register a wolfCrypt single-block "aes" crypto_cipher - #11612

Open
MarkAtwood wants to merge 1 commit into
wolfSSL:masterfrom
MarkAtwood:linuxkm-aes-single-block-cipher
Open

MarkAtwood wants to merge 1 commit into
wolfSSL:masterfrom
MarkAtwood:linuxkm-aes-single-block-cipher

Conversation

@MarkAtwood

@MarkAtwood MarkAtwood commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Description

dm-crypt essiv (aes-cbc-essiv:sha256, the LUKS1 default) and xcbc get the bare aes cipher via crypto_alloc_cipher("aes"), linuxkm didn't register one so those stayed on the kernel's aes-lib. this adds a single-block aes crypto_cipher on wc_AesEncryptDirect/wc_AesDecryptDirect.

cia_encrypt/cia_decrypt are void and can't refuse service, so it's not an approved FIPS service. if a Direct call fails (v7 with a fatal signal pending, or an unaligned src on aesni) it falls through to the kernel aes-lib with a ratelimited log, same as wc__get_random_bytes. gated on WOLFSSL_AES_DIRECT, HAVE_AES_DECRYPT, 5.4+ and CONFIG_CRYPTO_LIB_AES, and aes/-aes work in --enable-linuxkm-lkcapi-register.

Testing

ubuntu 26.04, 7.0.0-1016-aws, =aes, =all and =all --enable-aesni. fips-197 c.1-c.3, rfc 3566 xcbc cases 1-7, and dm-crypt essiv at 2048/2048 sectors vs pyca all pass, also with -DTEST_WC_LINUXKM_AESDIRECT_FALLTHROUGH forcing the aes-lib path.

Checklist

  • added tests (load-time self-test with FIPS-197 KATs)
  • updated/added doxygen
  • updated appropriate READMEs
  • Updated manual and documentation

Copilot AI balanced review requested due to automatic review settings September 30, 2026 18:01

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.

Copilot review overview

🟡 Changes recommended

Decryption-disabled and restricted-key-size configurations are not handled correctly.

Review effort: Balanced
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

Registers a bare single-block AES implementation with the Linux Kernel Crypto API for ESSIV and similar consumers.

Changes:

  • Adds AES cipher registration, encryption/decryption, and KATs.
  • Adds feature gates and configure options.
  • Imports the required kernel cipher API.
File Description
linuxkm/​lkcapi_glue.c Registers and unregisters the cipher.
linuxkm/​lkcapi_aes_glue.c Implements and tests single-block AES.
linuxkm/​linuxkm_wc_port.h Includes the internal cipher API.
configure.ac Adds aes registration controls.

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

Comment thread linuxkm/lkcapi_aes_glue.c Outdated
* essiv(cbc(aes),sha256), which encrypts each sector IV with it. Without it,
* dm-crypt aes-cbc-essiv volumes run IV generation outside wolfCrypt.
*/
#ifdef HAVE_AES_ECB

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

Comment thread linuxkm/lkcapi_aes_glue.c Outdated
static const struct {
unsigned int key_len;
const u8 *ct;
} kat[] = { { 16, ct128 }, { 32, ct256 } };

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

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

MemBrowse Memory Report · Explore what changed →

zephyr-frdm_rw612

  • FLASH: datas +16 B, log_const_area -8 B, rodata +36 B, text +10,544 B (+3.7%, 293,052 B / 67,108,864 B, total: 0% used)
  • RAM: bss +49 B, datas +16 B (+0.1%, 58,423 B / 983,040 B, total: 6% used)

No memory changes detected for:


Catch memory regressions in CI with MemBrowse. Free for open source.

@MarkAtwood
MarkAtwood force-pushed the linuxkm-aes-single-block-cipher branch 2 times, most recently from 88baecd to f42f110 Compare October 7, 2026 18:59
@MarkAtwood
MarkAtwood requested a review from douzzer October 7, 2026 18:59
@MarkAtwood
MarkAtwood force-pushed the linuxkm-aes-single-block-cipher branch from f42f110 to 1131e01 Compare October 13, 2026 21:44
@MarkAtwood
MarkAtwood force-pushed the linuxkm-aes-single-block-cipher branch from 1131e01 to dd4723c Compare October 20, 2026 22:48
@MarkAtwood

Copy link
Copy Markdown
Contributor Author

retest this please

@MarkAtwood
MarkAtwood force-pushed the linuxkm-aes-single-block-cipher branch from dd4723c to 959405b Compare October 21, 2026 14:51
@MarkAtwood
MarkAtwood force-pushed the linuxkm-aes-single-block-cipher branch from 959405b to 0efc335 Compare November 4, 2026 14:39

@douzzer douzzer 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.

Alas the problem this PR is trying to solve is harder than it looks.

struct cipher_alg can't be used in a FIPS call stack because it has void slots
for .cia_encrypt and .cia_decrypt -- must-succeed APIs -- which are incompatible
with FIPS-required refusal of service in the degraded state.

What this means in practice: wolfCrypt can supply the implementation for the
cipher_alg block cipher, but only by using direct function calls that are not
wrapped by FIPS shims, and never with strict FIPS compliance.

The PR's call to km_AesSetKeyCommon() from km_AesDirectSetKey() is correct as-is,
because cipher_alg.cia_setkey does return an integer error code as needed.

However, the PR's implementation of km_AesDirectCrypt() zeroes the output buffer
on any failure from wc_AesEcbEncrypt() or wc_AesEcbDecrypt() (FIPS-wrapped
service functions). This converts degraded state into a vulnerability: a
legitimate consumer composed over the bare cipher (e.g. the xcbc template under
IPsec) computes its result from zeroed blocks and returns success, so the result
becomes a key-independent function of the message -- computable offline by an
adversary able to force or detect degraded state, whose forgeries then verify.

To avoid introducing this serious and otherwise irremediable vulnerability,
km_AesDirectCrypt() must call the non-FIPS wc_AesEncryptDirect() and
wc_AesDecryptDirect(), which succeed unconditionally in practice (there are no
NMI block cipher consumers in the kernel, and all other contexts are fulfilled
unconditionally). Even then, the impossibility of propagating an error to the
caller by itself precludes FIPS compliance, hence the need (which remains) for
fallthrough failure handling with rate-limited system logging. And note that
the new glue needs to be gated on defined(WOLFSSL_AES_DIRECT), which is defined
in all current and historical FIPS profiles.

Ultimately, this PR does not change the FIPS status of dm-crypt aes-cbc-essiv
volumes. The approved service is the cbc(aes) data path, which accepts
caller-supplied IVs as FIPS permits for CBC; the essiv IV derivation was never
an approved service, whether computed by the kernel's aes-lib (status quo) or by
wolfCrypt (this PR). No call stack that reaches cryptography through a void
interface can be claimed as an approved service.

@douzzer douzzer assigned MarkAtwood and unassigned douzzer and wolfSSL-Bot Nov 5, 2026
@MarkAtwood
MarkAtwood force-pushed the linuxkm-aes-single-block-cipher branch from 0efc335 to e4db874 Compare November 11, 2026 18:54
@MarkAtwood

Copy link
Copy Markdown
Contributor Author

switched to wc_AesEncryptDirect/wc_AesDecryptDirect, falls through to aes-lib on failure, no more zeroing, gated on WOLFSSL_AES_DIRECT. tested on 7.0 with and without a forced failure, essiv and xcbc match reference vectors. details in the description.

@MarkAtwood
MarkAtwood requested a review from douzzer November 11, 2026 19:26
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.

4 participants