Skip to content

20260807-linuxkm-ed-pqc-glue - #11180

Open
douzzer wants to merge 11 commits into
wolfSSL:masterfrom
douzzer:20260807-linuxkm-ed-pqc-glue
Open

20260807-linuxkm-ed-pqc-glue#11180
douzzer wants to merge 11 commits into
wolfSSL:masterfrom
douzzer:20260807-linuxkm-ed-pqc-glue

Conversation

@douzzer

@douzzer douzzer commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

src/pk_ec.c: fix identicalInnerCondition in wolfSSL_ECDH_compute_key().

wolfcrypt/src/ecc.c: fix identicalInnerCondition in _ecc_import_x963_ex2().

wolfcrypt/src/md5.c: fix MSAN-detected unaligned access in Transform().

wolfcrypt/benchmark/benchmark.c: smallstack refactor of bench_chacha20_poly1305_aead().

wolfssl/openssl/hmac.h: add missing !OPENSSL_COEXIST gate around #define HMAC_MAX_MD_CBLOCK.

wolfssl/wolfcrypt/memory.h: add configuration consistency asserts around DEBUG_VECTOR_REGISTER_ACCESS*.

wolfcrypt/src/error.c, wolfssl/wolfcrypt/error-crypt.h:

  • add NO_DEFAULT_FOUND_E "No default object registered for request type".
  • add missing #include <wolfssl/wolfcrypt/logging.h> in WOLFSSL_DEBUG_TRACE_ERROR_CODES path.
  • add func to GNUC WC_ERR_TRACE().

wolfcrypt/src/rng_bank.c, wolfssl/wolfcrypt/rng_bank.h, wolfcrypt/test/test.c:

  • add wc_rng_bank_inst.bank for parent access from the children.
  • add wc_rng_bank_inst_checkin().
  • improve thread safety, error checking, and default bank support in wc_rng_bank_checkout(), wc_local_rng_bank_checkout_for_bankref(), wc_rng_bank_inst_reinit(), wc_rng_bank_seed(), wc_rng_bank_reseed(), and wc_InitRng_BankRef_local().
  • orthogonalize common code in wc_InitRng_BankRef() and wc_rng_new_bankref() into wc_InitRng_BankRef_local().

wolfcrypt/test/test.c:

  • fix typo in PRINT_HEAP_CHECKPOINT().
  • refactor bare XMALLOC in aeskeywrap_test() using WC__VAR(), and implement associated error handling and propagation.
  • add wc_rng_bank_inst_checkin() tests to random_bank_test(), update expected failure codes, and remove obsolete test clauses.
  • add missing !HAVE_FIPS gates in cryptocb_test().

wolfcrypt/src/random.c:

  • in WC_RNG_BANK_SUPPORT variant of wc_RNG_GenerateBlock(), use the new wc_rng_bank_inst_checkin(), not wc_rng_bank_checkin().
  • tweaks to WOLFSSL_DEBUG_TRACE_ERROR_CODES code wrappers to mollify clang-tidy and -Wconversion.
  • fix a spelling error in _InitRng().

linuxkm/lkcapi_sha_glue.c:

  • in wc_linuxkm_drbg_generate(), opportunistically reseed once half way to WC_RESEED_INTERVAL and wc_linuxkm_can_block(). Also properly inhibit the recovery call to wc_rng_bank_inst_reinit() if ! wc_linuxkm_can_block().
  • refactor wc_mix_pool_bytes() to use wc_RNG_DRBG_Reseed(), and only on the CPU-local RNG.

wolfcrypt/src/asn.c, wolfcrypt/src/curve25519.c, wolfcrypt/src/evp.c, wolfcrypt/src/pkcs7.c, wolfcrypt/src/pkcs12.c, wolfcrypt/src/srp.c: at each existing wc_InitRng(), attempt wc_InitRng_BankRef() if WC_RNG_BANK_DEFAULT_SUPPORT && WC_HAVE_RNG_BANKREF.

.wolfssl_known_macro_extras
linuxkm/include.am

linuxkm/lkcapi_ecdh_glue.c: implement ecdh-nist-p521 driver.

linuxkm/lkcapi_ecdsa_glue.c:

  • hoist LINUXKM_ECC192 setup into lkcapi_glue.c (used by both lkcapi_ecdh_glue.c and lkcapi_ecdsa_glue.c).
  • use LINUXKM_ECC521, not HAVE_ECC521, as the pivot for gating in P521.

linuxkm/lkcapi_ed_glue.c: implement LKCAPI glue logic for EdDSA-25519 and -448.

linuxkm/lkcapi_lms_glue.c: implement LKCAPI glue logic for LMS/HSS (RFC 8554, SP 800-208).

linuxkm/lkcapi_xmss_glue.c: implement LKCAPI glue logic for XMSS/XMSS^MT (RFC 8391, SP 800-208).

linuxkm/lkcapi_mlkem_glue.c: implement LKCAPI glue logic for FIPS 203 ML-KEM, supporting both roles (encapsulation/initiator, decapsulation/responder).

linuxkm/lkcapi_mldsa_glue.c: implement LKCAPI glue logic for FIPS 204 mldsa44, mldsa65, and mldsa87, with both sign and verify operations.

linuxkm/lkcapi_slhdsa_glue.c: implement LKCAPI glue logic for FIPS 205 SLH-DSA (all parameter sets).

linuxkm/lkcapi_glue.c:

  • add setup for LINUXKM_ECC192, adopted from lkcapi_ecdsa_glue.c, and add setup for LINUXKM_ECC521.
  • add inclusion, registration, and deregistration, for EdDSA, ML-DSA, ML-KEM, SLH-DSA, LMS, and XMSS.

configure.ac: add LKCAPI handling for EdDSA, ML-DSA, ML-KEM, SLH-DSA, LMS, and XMSS.

linuxkm/x86_vector_register_glue.c, wolfcrypt/src/wc_port.c, linuxkm/linuxkm_wc_port.h:

  • allow vector registers in softirq contexts on the idle process.
  • rename {allocate,free}wolfcrypt_linuxkm_fpu_states() to wc_linuxkm{allocate,free}_svr_states().
  • rename wc_linuxkm_fpu_() to wc_linuxkm_svr_().
  • rename struct wc_thread_fpu_count_ent to wc_thread_svr_count_ent.
  • add wc_thread_svr_count_ent.reserved_at and WC_SVR_SLOT_AGE_MS(), and set .reserved_at on each outermost save, and leverage them for more informative log output.
  • rename WC_FPU_COUNT_MASK and WC_FPU_INHIBITED_FLAG to WC_SVR_COUNT_MASK and WC_SVR_INHIBITED_FLAG.
  • in wc_linuxkm_free_svr_states(), inhibit deallocation entirely if any slots are still occupied (a small one-time leak is much better than a near-certain crash).
  • add WC_SVR_FREE_SLOT_PID, WC_SVR_IDLE_PID, and WC_SVR_PID_SLOT_ID(), allowing representation of the idle process (one per CPU, all PID 0 in current kernels) in the .pid member.
  • in wc_linuxkm_svr_state_assoc*(), wc_can_save_vector_registers_x86(), and wc_save_vector_registers_x86(), accommodate WC_SVR_IDLE_PID, allowing calls from softirq contexts on the idle process.
  • add wc_svr_disallowed_count_reset(), wc_svr_disallowed_count_current(), and wc_svr_disallowed_count_increment(), for auditing of refused vector saves.
  • add WC_SVR_BH_HELD_FLAG, use it to track and restore local_bh_disable(), inhibit local_bh_disable() when irqs_disabled(), and use softirq_count(), not preempt_count(), to confirm that local_bh_disable() was called successfully and appropriately.

linuxkm/linuxkm_wc_port.h:

  • reduce WC_LINUXKM_MAX_NS_WITHOUT_YIELD from 1 second to 25 ms for better kernel citizenship.
  • add WC_DEBUG_FORCE_KERNEL_SETTINGS for inhibiting #errors on unsupported configurations.
  • add extension annotation to macros that need it.
  • add wc_svr_disallowed_count_reset() and wc_svr_disallowed_count_current().
  • fix CAN_SAVE_VECTOR_REGISTERS() to honor DEBUG_VECTOR_REGISTER_ACCESS_ALWAYS_{ON,OFF}.
  • add WC_RELAX_LONG_LOOP() to DEBUG_VECTOR_REGISTER_ACCESS_ALWAYS_OFF variant of SAVE_VECTOR_REGISTERS2().
  • allow for fully user-supplied SAVE_VECTOR_REGISTERS() and friends.

linuxkm/module_hooks.c:

  • add WOLFSSL_DEBUG_TRACE_ERROR_CODES coverage for all system error codes used by module_hooks.c and its includes.
  • implement double-run wolfCrypt_IntegrityTest_fips() and wc_RunAllCast_fips() in WC_C_DYNAMIC_FALLBACK configurations, once with acceleration on (leveraging fallback instrumentation to fail the module if any fallbacks occur), and once with it forced off using DISABLE_VECTOR_REGISTERS().

linuxkm/lkcapi_aes_glue.c: implement WC_LINUXKM{GCM,XTS}SVR_BATCH, batching several chunks within a single SAVE_VECTOR_REGISTERS2() bracket (entails adding WALK_ATOMIC to calls that affect walk dynamics during the locked batches).

tested with

wolfssl-multi-test.sh ... pr-check

and numerous kernel-oriented scenarios.

douzzer added 11 commits August 14, 2026 16:31
* add NO_DEFAULT_FOUND_E "No default object registered for request type".
* add missing #include <wolfssl/wolfcrypt/logging.h> in WOLFSSL_DEBUG_TRACE_ERROR_CODES path.
* add __func__ to __GNUC__ WC_ERR_TRACE().

wolfcrypt/src/rng_bank.c, wolfssl/wolfcrypt/rng_bank.h, wolfcrypt/test/test.c:
* add wc_rng_bank_inst.bank for parent access from the children.
* add wc_rng_bank_inst_checkin().
* improve thread safety, error checking, and default bank support in wc_rng_bank_checkout(), wc_local_rng_bank_checkout_for_bankref(), wc_rng_bank_inst_reinit(), wc_rng_bank_seed(), wc_rng_bank_reseed(), and wc_InitRng_BankRef_local().
* orthogonalize common code in wc_InitRng_BankRef() and wc_rng_new_bankref() into wc_InitRng_BankRef_local().

wolfcrypt/test/test.c:
* fix typo in PRINT_HEAP_CHECKPOINT().
* refactor bare XMALLOC in aeskeywrap_test() using WC_*_VAR*(), and implement associated error handling and propagation.
* add wc_rng_bank_inst_checkin() tests to random_bank_test(), update expected failure codes, and remove obsolete test clauses.
* add missing !HAVE_FIPS gates in cryptocb_test().

wolfcrypt/src/random.c:
* in WC_RNG_BANK_SUPPORT variant of wc_RNG_GenerateBlock(), use the new wc_rng_bank_inst_checkin(), not wc_rng_bank_checkin().
* tweaks to WOLFSSL_DEBUG_TRACE_ERROR_CODES code wrappers to mollify clang-tidy and -Wconversion.
* fix a spelling error in _InitRng().

linuxkm/lkcapi_sha_glue.c:
* in wc_linuxkm_drbg_generate(), opportunistically reseed once half way to WC_RESEED_INTERVAL and wc_linuxkm_can_block().  Also properly inhibit the recovery call to wc_rng_bank_inst_reinit() if ! wc_linuxkm_can_block().
* refactor wc_mix_pool_bytes() to use wc_RNG_DRBG_Reseed(), and only on the CPU-local RNG.

wolfcrypt/src/asn.c, wolfcrypt/src/curve25519.c, wolfcrypt/src/evp.c, wolfcrypt/src/pkcs7.c, wolfcrypt/src/pkcs12.c, wolfcrypt/src/srp.c: at each existing wc_InitRng(), attempt wc_InitRng_BankRef() if WC_RNG_BANK_DEFAULT_SUPPORT && WC_HAVE_RNG_BANKREF.
linuxkm/lkcapi_ecdsa_glue.c:
* hoist LINUXKM_ECC192 setup into lkcapi_glue.c (used by both lkcapi_ecdh_glue.c and lkcapi_ecdsa_glue.c).
* use LINUXKM_ECC521, not HAVE_ECC521, as the pivot for gating in P521.

linuxkm/lkcapi_ed_glue.c: implement LKCAPI glue logic for EdDSA-25519 and -448.

linuxkm/lkcapi_lms_glue.c: implement LKCAPI glue logic for LMS/HSS (RFC 8554, SP 800-208).

linuxkm/lkcapi_xmss_glue.c: implement LKCAPI glue logic for XMSS/XMSS^MT (RFC 8391, SP 800-208).

linuxkm/lkcapi_mlkem_glue.c: implement LKCAPI glue logic for FIPS 203 ML-KEM, supporting both roles (encapsulation/initiator, decapsulation/responder).

linuxkm/lkcapi_mldsa_glue.c: implement LKCAPI glue logic for FIPS 204 mldsa44, mldsa65, and mldsa87, with both sign and verify operations.

linuxkm/lkcapi_slhdsa_glue.c: implement LKCAPI glue logic for FIPS 205 SLH-DSA (all parameter sets).

linuxkm/lkcapi_glue.c:
* add setup for LINUXKM_ECC192, adopted from lkcapi_ecdsa_glue.c, and add setup for LINUXKM_ECC521.
* add inclusion, registration, and deregistration, for EdDSA, ML-DSA, ML-KEM, SLH-DSA, LMS, and XMSS.

configure.ac: add LKCAPI handling for EdDSA, ML-DSA, ML-KEM, SLH-DSA, LMS, and XMSS.
…linuxkm_wc_port.h:

* allow vector registers in softirq contexts on the idle process.
* rename {allocate,free}_wolfcrypt_linuxkm_fpu_states() to wc_linuxkm_{allocate,free}_svr_states().
* rename wc_linuxkm_fpu_*() to wc_linuxkm_svr_*().
* rename struct wc_thread_fpu_count_ent to wc_thread_svr_count_ent.
* add wc_thread_svr_count_ent.reserved_at and WC_SVR_SLOT_AGE_MS(), and set .reserved_at on each outermost save, and leverage them for more informative log output.
* rename WC_FPU_COUNT_MASK and WC_FPU_INHIBITED_FLAG to WC_SVR_COUNT_MASK and WC_SVR_INHIBITED_FLAG.
* in wc_linuxkm_free_svr_states(), inhibit deallocation entirely if any slots are still occupied (a small one-time leak is much better than a near-certain crash).
* add WC_SVR_FREE_SLOT_PID, WC_SVR_IDLE_PID, and WC_SVR_PID_SLOT_ID(), allowing representation of the idle process (one per CPU, all PID 0 in current kernels) in the .pid member.
* in wc_linuxkm_svr_state_assoc*(), wc_can_save_vector_registers_x86(), and wc_save_vector_registers_x86(), accommodate WC_SVR_IDLE_PID, allowing calls from softirq contexts on the idle process.
* add wc_svr_disallowed_count_reset(), wc_svr_disallowed_count_current(), and wc_svr_disallowed_count_increment(), for auditing of refused vector saves.
* add WC_SVR_BH_HELD_FLAG, use it to track and restore local_bh_disable(), inhibit local_bh_disable() when irqs_disabled(), and use softirq_count(), not preempt_count(), to confirm that local_bh_disable() was called successfully and appropriately.

linuxkm/linuxkm_wc_port.h:

* reduce WC_LINUXKM_MAX_NS_WITHOUT_YIELD from 1 second to 25 ms for better kernel citizenship.
* add WC_DEBUG_FORCE_KERNEL_SETTINGS for inhibiting #errors on unsupported configurations.
* add __extension__ annotation to macros that need it.
* add wc_svr_disallowed_count_reset() and wc_svr_disallowed_count_current().
* fix CAN_SAVE_VECTOR_REGISTERS() to honor DEBUG_VECTOR_REGISTER_ACCESS_ALWAYS_{ON,OFF}.
* add WC_RELAX_LONG_LOOP() to DEBUG_VECTOR_REGISTER_ACCESS_ALWAYS_OFF variant of SAVE_VECTOR_REGISTERS2().
* allow for fully user-supplied SAVE_VECTOR_REGISTERS() and friends.
* add WOLFSSL_DEBUG_TRACE_ERROR_CODES coverage for all system error codes used by module_hooks.c and its includes.
* implement double-run wolfCrypt_IntegrityTest_fips() and wc_RunAllCast_fips() in WC_C_DYNAMIC_FALLBACK configurations, once with acceleration on (leveraging fallback instrumentation to fail the module if any fallbacks occur), and once with it forced off using DISABLE_VECTOR_REGISTERS().
…batching several chunks within a single SAVE_VECTOR_REGISTERS2() bracket (entails adding WALK_ATOMIC to calls that affect walk dynamics during the locked batches).
@github-actions

Copy link
Copy Markdown

MemBrowse Memory Report

gcc-arm-cortex-m4

  • FLASH: .rodata.CSWTCH.1 +4 B, .rodata.str1.1 +46 B (+0.0%, 202,017 B / 262,144 B, total: 77% used)

gcc-arm-cortex-m4-crypto-only

  • FLASH: .rodata.CSWTCH.1 +4 B, .rodata.str1.1 +46 B, .text +512 B (+0.3%, 176,668 B / 262,144 B, total: 67% used)

gcc-arm-cortex-m4-openssl-compat

  • FLASH: .rodata +40 B, .text +512 B (+0.1%, 776,356 B / 1,048,576 B, total: 74% used)

gcc-arm-cortex-m4-pkcs7

  • FLASH: .rodata.CSWTCH.1 +4 B, .rodata.str1.1 +46 B (+0.0%, 215,008 B / 262,144 B, total: 82% used)

gcc-arm-cortex-m4-pq

  • FLASH: .rodata +44 B (+0.0%, 297,800 B / 1,048,576 B, total: 28% used)

gcc-arm-cortex-m4-rsa-only

  • FLASH: .rodata +48 B, .text +512 B (+0.2%, 328,800 B / 1,048,576 B, total: 31% used)

gcc-arm-cortex-m4-tls13

  • FLASH: .rodata.CSWTCH.1 +4 B, .rodata.str1.1 +46 B (+0.0%, 238,547 B / 262,144 B, total: 91% used)

gcc-arm-cortex-m7

  • FLASH: .rodata.CSWTCH.1 +4 B, .rodata.str1.1 +46 B (+0.0%, 202,017 B / 262,144 B, total: 77% used)

gcc-arm-cortex-m7-pq

  • FLASH: .rodata +44 B (+0.0%, 298,696 B / 1,048,576 B, total: 28% used)

gcc-arm-cortex-m7-tls13

  • FLASH: .rodata.CSWTCH.1 +4 B, .rodata.str1.1 +46 B (+0.0%, 238,611 B / 262,144 B, total: 91% used)

linuxkm-pie

  • Data: __patchable_function_entries +560 B (+2.1%, 27,144 B)

linuxkm-standard

  • Data: __patchable_function_entries +544 B (+1.1%, 49,936 B)

stm32-sim-stm32h753

@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 #11180

Scan targets checked: linuxkm-bugs, linuxkm-src, wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src
Findings: 19
18 finding(s) posted as inline comments (see file-level comments below)

Low (1)

wc_rng_bank_seed() accepts instance-selection flags that break its per-index seeding loop

File: wolfcrypt/src/rng_bank.c:934
Function: wc_rng_bank_seed
Category: Cryptographic correctness

The loop passes index n to wc_rng_bank_checkout() but forwards caller flags verbatim. With WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST or WC_RNG_BANK_FLAG_CAN_FAIL_OVER_INST the checkout overrides n, so the same instance is reseeded repeatedly while others never receive the supplied entropy, and the function still returns 0. wc_rng_bank_reseed() rejects both flags at line 985.

Recommendation: Reject WC_RNG_BANK_FLAG_PREFER_AFFINITY_INST and WC_RNG_BANK_FLAG_CAN_FAIL_OVER_INST on entry, as wc_rng_bank_reseed() does.

Referenced code: wolfcrypt/src/rng_bank.c:934-936 (3 lines)


This review was generated automatically by Fenrir. Findings are non-blocking.


msg_len = req->src_len;

msg = malloc(msg_len + req->dst_len);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟠 [Medium] km_slhdsa_sign() akcipher path allocates msg_len + dst_len without the overflow guard used everywhere else · Incorrect sizeof/type usage

The sum of the two caller-supplied unsigned int lengths can wrap, yielding an undersized buffer while km_slhdsa_sign_common() still accepts sig_space and writes a full signature past its end. Every sibling verify path in this PR guards the same expression with a word64 comparison.

Fix: Add the same (msg_len + req->dst_len) != ((word64)msg_len + (word64)req->dst_len) rejection used in km_slhdsa_verify(), and size the signature area from the parameter set rather than dst_len.

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.

This looks valid. malloc(msg_len + req->dst_len); needs overflow checks.

!defined(LINUXKM_LKCAPI_REGISTER_XMSS)
#define LINUXKM_LKCAPI_REGISTER_XMSS
#ifndef HAVE_FIPS
#define LINUXKM_LKCAPI_REGISTER_XMSS_MT

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] LINUXKM_LKCAPI_REGISTER_XMSS_MT is unreachable when XMSS is requested explicitly · Logic errors

LINUXKM_LKCAPI_REGISTER_XMSS_MT is defined only inside a block guarded by !defined(LINUXKM_LKCAPI_REGISTER_XMSS), so --enable-linuxkm-lkcapi-register=xmss (which defines that macro via configure.ac) registers only single-tree "xmss" and silently drops "xmssmt".

Fix: Derive LINUXKM_LKCAPI_REGISTER_XMSS_MT in a separate #if defined(LINUXKM_LKCAPI_REGISTER_XMSS) && !defined(HAVE_FIPS) && !defined(LINUXKM_LKCAPI_DONT_REGISTER_XMSS_MT) block after the gate above.

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.

This seems valid too.


err = km_slhdsa_sign_common(ctx, sig, (word32)req->dst_len,
msg, msg_len);
if (err >= 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] km_slhdsa_sign() does not update req-dst_len before returning -EOVERFLOW · API contract violations

On the short-dst path km_slhdsa_sign_common() returns -EOVERFLOW and req->dst_len is left at the caller's value, so callers cannot learn the required signature size. The ML-DSA and EdDSA akcipher sign paths added in this PR both set req->dst_len first, as include/crypto/akcipher.h requires. Adjacent to known finding #434 (km_pkcs1pad_dec dst_len), but a different function and a different path.

Fix: Check the parameter set's signature size up front and set req->dst_len to it before returning -EOVERFLOW.

Comment thread linuxkm/module_hooks.c
REENABLE_VECTOR_REGISTERS();

svr_disallowed_count = wc_svr_disallowed_count_current();
if (svr_disallowed_count == 0) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] svr_disallowed_count post-condition check in wolfssl_init() can never fail · Dead/unreachable code

DISABLE_VECTOR_REGISTERS() itself calls wc_svr_disallowed_count_increment() on every success path in wc_save_vector_registers_x86(), so the counter is already >= 1 before the self-test runs; the svr_disallowed_count == 0 guard is vacuously satisfied and never detects a test run that made no inhibited save attempts. Same defect repeats after wc_RunAllCast_fips() at line 1057.

Fix: Snapshot the counter immediately after DISABLE_VECTOR_REGISTERS() and require the post-test value to exceed that snapshot.

free(ct);
}
km_mlkem_del_wc_key(wc_key);
return (err > 0) ? -EINVAL : err;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] km_mlkem_generate_ct() returns raw wolfCrypt error codes to the kernel crypto API · Incorrect error handling

Negative wolfCrypt codes from wc_MlKemKey_DecodePublicKey(), wc_MlKemKey_Encapsulate() and wc_Sha256Hash() (e.g. BAD_FUNC_ARG = -173) are returned unchanged as the kpp callback's errno, unlike the sibling km_mlkem_generate_ek() which normalizes with err ? -EINVAL : 0.

Related known finding #7896 (similar but distinct): Both leak raw wolfCrypt errors through Linux kernel KPP callbacks because error domains are not normalized, but km_mlkem_generate_ct's decode/encapsulate/hash exits are distinct from km_ecdh_gen_pub's wc_ecc_make_pub exit and require a separate patch.

Fix: Normalize wolfCrypt failures to -EINVAL while preserving the kernel errnos this function sets itself (-ENOMEM, -ENODEV).

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.

This looks valid too.

Comment thread wolfcrypt/test/test.c

if (aes_inited)
wc_AesFree(aes);
WC_FREE_VAR(aes, HEAP_HINT);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚪ [Info] aeskeywrap_test() frees the Aes buffer with a different memory-type tag than it allocated · Resource leaks

aes is allocated via WC_ALLOC_VAR_EX(..., DYNAMIC_TYPE_TMP_BUFFER, ...) at line 23585 but released with WC_FREE_VAR(), which hardcodes DYNAMIC_TYPE_WOLF_BIGINT. The tag mismatch corrupts memory-tracking accounting under WOLFSSL_TRACK_MEMORY/WOLFSSL_DEBUG_MEMORY.

Related known finding #7252 (similar but distinct): Both findings release memory with allocation metadata that differs from the allocation, risking allocator/accounting corruption in configured memory modes. #7252 mismatches the heap hint for an SRP allocation, while this finding mismatches the dynamic type tag in aeskeywrap_test(); the allocations, free operations, root details, and fixes are separate.

Fix: Use WC_FREE_VAR_EX(aes, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER).

Comment thread wolfcrypt/test/test.c

if (aes_inited)
wc_AesFree(aes);
WC_FREE_VAR(aes, HEAP_HINT);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] aeskeywrap_test allocates with DYNAMIC_TYPE_TMP_BUFFER but frees with DYNAMIC_TYPE_WOLF_BIGINT · Incorrect sizeof/type usage

The new aes buffer is allocated via WC_ALLOC_VAR_EX(..., DYNAMIC_TYPE_TMP_BUFFER, ...) but released via WC_FREE_VAR(), which hardcodes DYNAMIC_TYPE_WOLF_BIGINT. The alloc/free type tags disagree, misreporting the type to WOLFSSL_STATIC_MEMORY_DEBUG_CALLBACK and WOLFSSL_DEBUG_MEMORY output.

Related known finding #7339 (similar but distinct): Both findings are allocator type-tag mismatches, but they affect different functions and allocation/free operations: aeskeywrap_test's temporary Aes buffer versus GENERAL_NAME objects/stacks. Their root cause is analogous, yet each needs a separate source patch.

Fix: Use WC_FREE_VAR_EX(aes, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER), matching the pattern already used at test.c:9745 and 27063.

Comment thread wolfcrypt/test/test.c
if (rng_inst != bank->rngs + 3)
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
ret = wc_rng_bank_checkin(bank, &rng_inst);
ret = wc_rng_bank_inst_checkin(&rng_inst);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] New wc_rng_bank_inst_checkin() error returns are never exercised · Missing edge-case coverage on a function the PR also changed

wc_rng_bank_inst_checkin() is added by this PR and guards both rng_inst == NULL and *rng_inst == NULL with BAD_FUNC_ARG, plus the rng_inst_matches_bank() range check. All four new call sites pass a valid checked-out instance, so neither guard nor the bogus-pointer path is covered, unlike wc_rng_bank_checkin() which is negative-tested at test.c:26618.

Fix: Add negative cases asserting BAD_FUNC_ARG for wc_rng_bank_inst_checkin(NULL), for a NULL *rng_inst, and for a bogus instance pointer.

Comment thread wolfcrypt/test/test.c

if (aes_inited)
wc_AesFree(aes);
WC_FREE_VAR(aes, HEAP_HINT);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 [Low] aeskeywrap_test frees Aes buffer with a different DYNAMIC_TYPE than it allocated · Resource leaks

The new WC_ALLOC_VAR_EX allocates aes with DYNAMIC_TYPE_TMP_BUFFER, but WC_FREE_VAR releases it with DYNAMIC_TYPE_WOLF_BIGINT. The alloc/free type accounting disagrees in WOLFSSL_TRACK_MEMORY and WOLFSSL_STATIC_MEMORY builds, unlike every other allocation the PR converted in this file.

Related known finding #7252 (similar but distinct): Both involve allocator metadata mismatching at free time and affect specialized memory-accounting builds. However, this is aeskeywrap_test's DYNAMIC_TYPE mismatch, while issue 7252 is wolfSSL_CTX_set_srp_password's heap-hint mismatch; the faulting operations and required patches are separate.

Fix: Use WC_FREE_VAR_EX(aes, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER) to match the allocation type.

Comment thread wolfcrypt/test/test.c
if (rng_inst != bank->rngs + 3)
ERROR_OUT(WC_TEST_RET_ENC_NC, out);
ret = wc_rng_bank_checkin(bank, &rng_inst);
ret = wc_rng_bank_inst_checkin(&rng_inst);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚪ [Info] New wc_rng_bank_inst_checkin() guards are never exercised by random_bank_test · Missing edge-case coverage on a function the PR also changed

wc_rng_bank_inst_checkin() is introduced by this PR with two BAD_FUNC_ARG guards (rng_inst == NULL and *rng_inst == NULL) plus the rng_inst_matches_bank() rejection path, but the test only calls it on the success path. The sibling wc_rng_bank_checkin() does get a bogus-inst negative test at line 26618.

Fix: Add negative cases calling wc_rng_bank_inst_checkin(NULL), an already-NULL *rng_inst, and a bogus inst pointer, asserting BAD_FUNC_ARG.

@douzzer
douzzer requested a review from SparkiDev August 15, 2026 00:02

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

Fenrir found some issues. Please review them and fix as needed

@philljj philljj assigned douzzer and unassigned philljj Aug 16, 2026
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.

3 participants