Skip to content

Add curve448 crypto callback support - #11209

Open
night1rider wants to merge 2 commits into
wolfSSL:masterfrom
night1rider:curve448-callbacks
Open

Add curve448 crypto callback support#11209
night1rider wants to merge 2 commits into
wolfSSL:masterfrom
night1rider:curve448-callbacks

Conversation

@night1rider

Copy link
Copy Markdown
Contributor

Mirror curve25519 CB's -

keygen, shared secret, make pub and generic callbacks.

wc_curve448_init_ex/new/delete, new wc_curve448_generic API, WOLF_CRYPTO_CB_ONLY_CURVE448 mode.

TLS devId plumbing, tests (test.c, api unit tests, swdev), benchmark devId, CI entries.

@night1rider night1rider self-assigned this Aug 19, 2026
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

@night1rider
night1rider requested review from wolfSSL-Fenrir-bot and removed request for wolfSSL-Fenrir-bot August 20, 2026 02:36

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

Scan targets checked: wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src

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

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

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

Scan targets checked: wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src

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

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

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

Scan targets checked: wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src

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

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

Mirror curve25519: keygen, shared secret, make pub and generic
callbacks, wc_curve448_init_ex/new/delete, new wc_curve448_generic
API with scalar clamp checks, WOLF_CRYPTO_CB_ONLY_CURVE448 mode,
TLS devId plumbing, tests (test.c, api unit tests, swdev),
benchmark devId, CI entries.

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

Scan targets checked: wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src
Failed targets: wolfcrypt-bugs

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

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

Assert cryptocb output in curve448_onlycb_test, reject an all-zero
wc_curve448_generic result, guard the new API test for CB-only builds.

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

Scan targets checked: wolfcrypt-bugs, wolfcrypt-port-bugs, wolfcrypt-rs-bugs, wolfcrypt-src, wolfssl-bugs, wolfssl-src

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

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

Comment thread wolfcrypt/test/test.c
/* the dispatcher must hand over a usable payload */
if ((info->pk.curve448kg.rng == NULL) ||
(info->pk.curve448kg.size != CURVE448_KEY_SIZE)) {
return BAD_FUNC_ARG;

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] Curve448 keygen stub leaves key-devId at INVALID_DEVID on the BAD_FUNC_ARG path · Incorrect error handling

The payload-validation early return in the WC_PK_TYPE_CURVE448_KEYGEN branch returns before restoring info->pk.curve448kg.key->devId, which was set to INVALID_DEVID at line 80921. Every other early return in this callback restores devIdArg first, so the caller's key is left unbound from the device.

Fix: Restore info->pk.curve448kg.key->devId = devIdArg; before returning BAD_FUNC_ARG.

Comment thread wolfcrypt/src/curve448.c
wc_MemZero_Add("wc_curve448_shared_secret_ex o", o, CURVE448_PUB_KEY_SIZE);
#endif

if (ret == 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.

⚪ [Info] Always-true ret == 0 guard left behind by the shared-secret restructure · Dead error handling

The argument checks now return early (lines 299 and 303) and the crypto-callback block either returns or resets ret = 0 (line 330), so ret is unconditionally 0 when this guard is evaluated. The check can never be false and no longer protects anything.

Related known finding #7089 (similar but distinct): Both findings concern an always-decided error-handling guard caused by prior control flow, but this is the Curve448 shared-secret operation in wc_curve448_shared_secret_ex, whereas issue 7089 covers separate CMAC operations. The functions and required patches differ.

Fix: Drop the guard and call curve448() directly, keeping the subsequent if (ret == 0) checks that test its result.

Comment thread wolfcrypt/test/test.c
/* the dispatcher must hand over a usable payload */
if ((info->pk.curve448kg.rng == NULL) ||
(info->pk.curve448kg.size != CURVE448_KEY_SIZE)) {
return BAD_FUNC_ARG;

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] Curve448 keygen callback leaves key-devId cleared when returning BAD_FUNC_ARG · Incorrect error handling

This early return fires after info->pk.curve448kg.key->devId was overwritten with INVALID_DEVID at line 80921 and skips the /* reset devId */ restore that every sibling branch in this callback performs, leaving the caller's key unbound from the device.

Fix: Restore info->pk.curve448kg.key->devId = devIdArg; before returning BAD_FUNC_ARG.

Comment thread wolfcrypt/test/test.c
ret = wc_curve448_shared_secret(&key, &pubKey, out, &outLen);
if (ret != 0)
ret = WC_TEST_RET_ENC_EC(ret);
else if ((outLen != CURVE448_KEY_SIZE) || (out[0] != 0xA5))

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] curve448_onlycb_test verifies only the first byte of callback-supplied output · Weak or missing assertions

The shared-secret assertion inspects out[0] only, and the keygen assertion at line 80188 inspects key.p[0] only, while curve448_buf_is() — added in the same hunk — full-buffer-checks the make_pub/generic markers. A device that fills only part of the 56-byte output still passes.

Fix: Assert with curve448_buf_is(out, 0xA5, CURVE448_PUB_KEY_SIZE) and curve448_buf_is(key.p, 0xC3, CURVE448_PUB_KEY_SIZE).

Comment thread wolfcrypt/src/cryptocb.c
/* try the find callback first, else grab the first registered device */
dev = wc_CryptoCb_FindDevice(INVALID_DEVID, WC_ALGO_TYPE_PK);
if (dev == NULL || dev->cb == NULL)
dev = wc_CryptoCb_FindDeviceByIndex(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.

🟠 [Medium] X448 private scalar dispatched to an arbitrary registered crypto-callback device, ignoring the key's devId · Cryptographic correctness

wc_CryptoCb_FindDeviceByIndex(0) returns the first registered device regardless of algorithm, and wc_curve448_make_pub (curve448.c:90) and wc_curve448_generic call it with no devId gating. Every software X448 keygen and lazy wc_curve448_export_public derivation hands the raw 56-byte private scalar to that device's callback, even for keys created with INVALID_DEVID or bound to a different device. wc_curve448_make_key and wc_curve448_shared_secret_ex do respect key->devId. wc_CryptoCb_Curve448Generic (cryptocb.c:1539) shares the defect.

Fix: Plumb the owning key's devId into the make-pub/generic dispatch and drop the FindDeviceByIndex(0) fallback so unbound keys stay in software.

Comment thread tests/api/test_curve448.c
ExpectIntEQ(wc_InitRng(&rng), 0);
#ifndef WC_NO_CONSTRUCTORS
/* exercise the new constructor path */
ExpectNotNull(keyA = wc_curve448_new(HEAP_HINT, devId, &ret));

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 constructor/destructor NULL-tolerant parameters left untested · Missing edge-case coverage on a function the PR also changed

The PR documents result_code in wc_curve448_new and key_p in wc_curve448_delete as optional, but the only new tests always pass non-NULL for both; wc_curve448_delete(NULL, NULL) returns before reaching the key_p store, so the NULL-tolerant branches are never executed.

Fix: Add a wc_curve448_new(HEAP_HINT, devId, NULL) call and a successful wc_curve448_delete(key, NULL) call to the test.

curve448_key* key);
WOLFSSL_LOCAL int wc_CryptoCb_Curve448(curve448_key* private_key,
curve448_key* public_key, byte* out, word32* outlen, int endian);
WOLFSSL_LOCAL int wc_CryptoCb_Curve448MakePub(int public_size, byte* pub,

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] X448 make-pub/generic dispatch hands the raw private scalar to an arbitrary registered crypto device · Cryptographic correctness

wc_CryptoCb_Curve448MakePub/wc_CryptoCb_Curve448Generic take no devId and fall back to wc_CryptoCb_FindDeviceByIndex(0), so wc_curve448_make_pub() and wc_curve448_generic() now forward the raw X448 private scalar to whatever callback is registered first — including keys explicitly created with INVALID_DEVID. Mirrors the existing curve25519 helpers, but is a new information flow for X448.

Fix: Add devId-carrying variants (or a key-aware wrapper) so the scalar is only offloaded to the device the caller selected.

Comment thread tests/api/test_curve448.c
ExpectIntEQ(wc_InitRng(&rng), 0);
#ifndef WC_NO_CONSTRUCTORS
/* exercise the new constructor path */
ExpectNotNull(keyA = wc_curve448_new(HEAP_HINT, devId, &ret));

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_curve448_new/wc_curve448_delete NULL guards are uncovered by the added tests · Missing edge-case coverage on a function the PR also changed

The only constructor/destructor coverage is the success path plus wc_curve448_delete(NULL, NULL). The result_code != NULL guard in wc_curve448_new and the key_p != NULL guard in wc_curve448_delete are never exercised, so a regression that dereferences either NULL out-param passes CI.

Fix: Add cases calling wc_curve448_new(HEAP_HINT, devId, NULL) and wc_curve448_delete(key, NULL).

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