From bad522f6549bd9bc16035a94016f765d4642f08c Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Tue, 15 Sep 2026 13:24:14 +0200 Subject: [PATCH] F-12942: pkcs11: wipe PIN on terminal init failure pkcs11_crypto_init() tore down the session on failure but left the pre-populated pkcs11_pin credential in retained bootloader memory after the handoff. Wipe it in the failure path, same as the deinit path (F-12114). Regression test in unit-pkcs11-pin-zeroize: login rejected -> init fails -> every pin byte is zero. --- src/libwolfboot.c | 5 ++++ tools/unit-tests/unit-pkcs11-pin-zeroize.c | 35 +++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 5569d645..932677a1 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -2369,6 +2369,8 @@ static int pkcs11_enc_initialized = 0, pkcs11_dec_initialized = 0; static CK_AES_CTR_PARAMS pkcs11_params; #endif +static void pkcs11_pin_wipe(void); + int pkcs11_crypto_init(void) { CK_RV ret = 0; @@ -2462,6 +2464,9 @@ int pkcs11_crypto_init(void) if (pkcs11_initialized) { pkcs11_function_list->C_Finalize(NULL); } + /* terminal failure: the credential must not survive in retained + * memory (same reason as the deinit wipe) */ + pkcs11_pin_wipe(); } return ret; diff --git a/tools/unit-tests/unit-pkcs11-pin-zeroize.c b/tools/unit-tests/unit-pkcs11-pin-zeroize.c index 591cbe25..8c801eb9 100644 --- a/tools/unit-tests/unit-pkcs11-pin-zeroize.c +++ b/tools/unit-tests/unit-pkcs11-pin-zeroize.c @@ -1,6 +1,7 @@ /* unit-pkcs11-pin-zeroize.c * - * Unit test for the PKCS#11 login credential lifetime (F-12114). + * Unit test for the PKCS#11 login credential lifetime (F-12114, + * F-12942). * * pkcs11_pin is a file-scope copy of the credential supplied to * C_Login() for the token holding the firmware-decryption key. @@ -58,6 +59,7 @@ static uint8_t test_encrypt_key[ENCRYPT_PKCS11_KEY_ID_SIZE + /* ---- PKCS#11 stubs ---- */ static int stub_close_session_calls; +static int stub_login_fail; static CK_RV stub_C_Initialize(CK_VOID_PTR pInitArgs) { @@ -98,6 +100,9 @@ static CK_RV stub_C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, (void)userType; (void)pPin; (void)ulPinLen; + if (stub_login_fail) { + return CKR_PIN_INCORRECT; + } return CKR_OK; } @@ -171,6 +176,7 @@ void panic(void) static void reset_stub_state(void) { stub_close_session_calls = 0; + stub_login_fail = 0; } /* F-12114: the pre-handoff deinitializer must erase the PKCS#11 @@ -223,6 +229,32 @@ START_TEST(test_pkcs11_deinit_no_session) } END_TEST +/* F-12942: a terminal initialization failure after C_Login() was + * attempted (login rejected) tears the session down and must also + * erase the credential copy: the bootloader memory is retained + * after the handoff, as on the deinit path. */ +START_TEST(test_pkcs11_pin_wiped_on_init_failure) +{ + int ret; + size_t i; + + reset_stub_state(); + encrypt_initialized = 0; + memcpy(pkcs11_pin, ENCRYPT_PKCS11_PIN, sizeof(ENCRYPT_PKCS11_PIN)); + stub_login_fail = 1; + + ret = pkcs11_crypto_init(); + stub_login_fail = 0; + + ck_assert_int_eq(ret, CKR_PIN_INCORRECT); + ck_assert_int_eq(encrypt_initialized, 0); + for (i = 0; i < sizeof(pkcs11_pin); i++) { + ck_assert_msg(pkcs11_pin[i] == 0, + "pkcs11_pin byte %zu not wiped", i); + } +} +END_TEST + Suite *wolfboot_suite(void) { Suite *s = suite_create("wolfboot-pkcs11-pin"); @@ -230,6 +262,7 @@ Suite *wolfboot_suite(void) tcase_add_test(tc, test_pkcs11_pin_wiped_on_deinit); tcase_add_test(tc, test_pkcs11_deinit_no_session); + tcase_add_test(tc, test_pkcs11_pin_wiped_on_init_failure); suite_add_tcase(s, tc); return s; }