diff --git a/.gitignore b/.gitignore index afd172af..6942eb1f 100644 --- a/.gitignore +++ b/.gitignore @@ -35,14 +35,12 @@ coverage.info cmake/wolfpkcs11Config.cmake cmake/wolfpkcs11Targets.cmake cmake/wolfpkcs11ConfigVersion.cmake -tests/pkcs11test -tests/pkcs11mtt -tests/pkcs11str -tests/object_id_uniqueness_test -tests/rsa_session_persistence_test -tests/debug_test -tests/token_path_test -tests/pkcs11v3test +# Test binaries and build artifacts +tests/* +!tests/*.c +!tests/*.h +!tests/*.am +!tests/README.md examples/add_aes_key examples/add_hmac_key examples/add_rsa_key @@ -53,16 +51,7 @@ examples/mech_info examples/obj_list examples/slot_info examples/token_info -store/wp11* -store/debug -store/empty_pin_test -store/object -store/pkcs11mtt -store/pkcs11test -store/pkcs11v3test -store/rsa -store/str -store/debug +store/* test/* *.gcda *.gcno @@ -73,18 +62,13 @@ add_cert_file .cache compile_commands.json -tests/wp11_rsakey_* -tests/wp11_dhkey_* -tests/wp11_ecckey_* -tests/wp11_symmkey_* -tests/wp11_token_* -tests/wp11_obj_* -tests/token_path_test -tests/rsa_session_persistence_test -tests/empty_pin_store_test IDE/VisualStudio/.vs doc/doxygen_warnings doc/html/ doc/refman.pdf + +AGENTS.md +CLAUDE.md +.clangd diff --git a/src/crypto.c b/src/crypto.c index 0326e02c..f80e16ee 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -1794,7 +1794,6 @@ static CK_RV EncryptInit(CK_SESSION_HANDLE hSession, WOLFPKCS11_LEAVE("C_EncryptInit", rv); return rv; } - ret = WP11_Object_Find(session, hKey, &obj); if (ret != 0) { rv = CKR_OBJECT_HANDLE_INVALID; @@ -2023,6 +2022,11 @@ static CK_RV EncryptInit(CK_SESSION_HANDLE hSession, return CKR_MECHANISM_INVALID; } + if (WP11_Session_IsOpInitializedExact(session, init)) { + rv = CKR_OPERATION_ACTIVE; + WOLFPKCS11_LEAVE("C_EncryptInit", rv); + return rv; + } WP11_Session_SetMechanism(session, pMechanism->mechanism); WP11_Session_SetObject(session, obj); WP11_Session_SetOpInitialized(session, init); @@ -2136,7 +2140,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, &encDataLen, obj, WP11_Session_GetSlot(session)); if (ret < 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; case CKM_RSA_PKCS: @@ -2155,7 +2159,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, pEncryptedData, &encDataLen, obj, WP11_Session_GetSlot(session)); if (ret < 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; #ifndef WC_NO_RSA_OAEP @@ -2177,7 +2181,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, pEncryptedData, &encDataLen, obj, session); if (ret < 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; #endif @@ -2199,7 +2203,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ret = WP11_AesCbc_Encrypt(pData, (int)ulDataLen, pEncryptedData, &encDataLen, session); if (ret < 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; case CKM_AES_CBC_PAD: @@ -2221,7 +2225,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ret = WP11_AesCbcPad_Encrypt(pData, (int)ulDataLen, pEncryptedData, &encDataLen, session); if (ret < 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; #endif @@ -2241,7 +2245,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ret = WP11_AesCtr_Do(pData, (word32)ulDataLen, pEncryptedData, &encDataLen, session); if (ret != 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; #endif @@ -2262,7 +2266,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ret = WP11_AesGcm_Encrypt(pData, (int)ulDataLen, pEncryptedData, &encDataLen, obj, session); if (ret < 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; #endif @@ -2283,7 +2287,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ret = WP11_AesCcm_Encrypt(pData, (int)ulDataLen, pEncryptedData, &encDataLen, obj, session); if (ret < 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; #endif @@ -2303,7 +2307,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ret = WP11_AesEcb_Encrypt(pData, (int)ulDataLen, pEncryptedData, &encDataLen, obj, session); if (ret < 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; #endif @@ -2323,7 +2327,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ret = WP11_AesCts_Encrypt(pData, (int)ulDataLen, pEncryptedData, &encDataLen, session); if (ret < 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; #endif @@ -2344,7 +2348,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, ret = WP11_AesKeyWrap_Encrypt(pData, (word32)ulDataLen, pEncryptedData, &encDataLen, session); if (ret != 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; case CKM_AES_KEY_WRAP_PAD: { @@ -2365,8 +2369,10 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, return CKR_BUFFER_TOO_SMALL; paddedData = (byte*)XMALLOC(ulDataLen + padding, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (paddedData == NULL) + if (paddedData == NULL) { + WP11_Session_SetOpInitialized(session, 0); return CKR_DEVICE_MEMORY; + } XMEMCPY(paddedData, pData, ulDataLen); XMEMSET(paddedData + ulDataLen, padding, padding); @@ -2375,7 +2381,7 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, wc_ForceZero(paddedData, ulDataLen + padding); XFREE(paddedData, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (ret != 0) - return CKR_FUNCTION_FAILED; + break; *pulEncryptedDataLen = encDataLen; break; } @@ -2386,9 +2392,13 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, (void)encDataLen; (void)ulDataLen; (void)pEncryptedData; + WP11_Session_SetOpInitialized(session, 0); return CKR_MECHANISM_INVALID; } + WP11_Session_SetOpInitialized(session, 0); + if (ret < 0) + return CKR_FUNCTION_FAILED; return CKR_OK; } @@ -2771,7 +2781,6 @@ static CK_RV DecryptInit(CK_SESSION_HANDLE hSession, return CKR_SESSION_HANDLE_INVALID; if (pMechanism == NULL) return CKR_ARGUMENTS_BAD; - ret = WP11_Object_Find(session, hKey, &obj); if (ret != 0) return CKR_OBJECT_HANDLE_INVALID; @@ -2990,6 +2999,11 @@ static CK_RV DecryptInit(CK_SESSION_HANDLE hSession, return CKR_MECHANISM_INVALID; } + if (WP11_Session_IsOpInitializedExact(session, init)) { + rv = CKR_OPERATION_ACTIVE; + WOLFPKCS11_LEAVE("C_DecryptInit", rv); + return rv; + } WP11_Session_SetMechanism(session, pMechanism->mechanism); WP11_Session_SetObject(session, obj); WP11_Session_SetOpInitialized(session, init); @@ -3097,7 +3111,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, &decDataLen, obj, WP11_Session_GetSlot(session)); if (ret < 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; case CKM_RSA_PKCS: @@ -3117,7 +3131,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, &decDataLen, obj, WP11_Session_GetSlot(session)); if (ret < 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; #ifndef WC_NO_RSA_OAEP @@ -3139,7 +3153,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, (int)ulEncryptedDataLen, pData, &decDataLen, obj, session); if (ret < 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; #endif @@ -3161,7 +3175,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, ret = WP11_AesCbc_Decrypt(pEncryptedData, (int)ulEncryptedDataLen, pData, &decDataLen, session); if (ret < 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; case CKM_AES_CBC_PAD: @@ -3180,7 +3194,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, (int)ulEncryptedDataLen, pData, &decDataLen, session); if (ret < 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; #endif @@ -3200,7 +3214,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, ret = WP11_AesCtr_Do(pEncryptedData, (word32)ulEncryptedDataLen, pData, &decDataLen, session); if (ret != 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; #endif @@ -3223,7 +3237,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, ret = WP11_AesGcm_Decrypt(pEncryptedData, (int)ulEncryptedDataLen, pData, &decDataLen, obj, session); if (ret < 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; #endif @@ -3246,7 +3260,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, ret = WP11_AesCcm_Decrypt(pEncryptedData, (int)ulEncryptedDataLen, pData, &decDataLen, obj, session); if (ret < 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; #endif @@ -3266,7 +3280,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, ret = WP11_AesEcb_Decrypt(pEncryptedData, (int)ulEncryptedDataLen, pData, &decDataLen, obj, session); if (ret < 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; #endif @@ -3288,7 +3302,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, if (ret == BUFFER_E) return CKR_BUFFER_TOO_SMALL; if (ret < 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; *pulDataLen = decDataLen; break; #endif @@ -3313,7 +3327,7 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, ret = WP11_AesKeyWrap_Decrypt(pEncryptedData, (word32)ulEncryptedDataLen, pData, &decDataLen, session); if (ret != 0) - return CKR_ENCRYPTED_DATA_INVALID; + break; if (mechanism == CKM_AES_KEY_WRAP_PAD) { int i; byte padValue = pData[decDataLen - 1]; @@ -3340,8 +3354,10 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, (unsigned int)padValue); } - if (badPad != 0) - return CKR_ENCRYPTED_DATA_INVALID; + if (badPad != 0) { + ret = -1; + break; + } decDataLen -= padValue; } *pulDataLen = decDataLen; @@ -3353,9 +3369,13 @@ CK_RV C_Decrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, (void)ret; (void)ulEncryptedDataLen; (void)pData; + WP11_Session_SetOpInitialized(session, 0); return CKR_MECHANISM_INVALID; } + WP11_Session_SetOpInitialized(session, 0); + if (ret < 0) + return CKR_ENCRYPTED_DATA_INVALID; return CKR_OK; } @@ -3746,6 +3766,11 @@ CK_RV C_DigestInit(CK_SESSION_HANDLE hSession, return rv; } init = WP11_INIT_DIGEST; + if (WP11_Session_IsOpInitializedExact(session, init)) { + rv = CKR_OPERATION_ACTIVE; + WOLFPKCS11_LEAVE("C_DigestInit", rv); + return rv; + } ret = WP11_Digest_Init(pMechanism->mechanism, session); if (ret == 0) { @@ -3806,6 +3831,8 @@ CK_RV C_Digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, session); *pulDigestLen = hashLen; + if (pDigest != NULL && ret == CKR_OK) + WP11_Session_SetOpInitialized(session, 0); return ret; } @@ -3941,6 +3968,8 @@ CK_RV C_DigestFinal(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, ret = WP11_Digest_Final(pDigest, &hashLen, session); *pulDigestLen = hashLen; + if (pDigest != NULL && ret == 0) + WP11_Session_SetOpInitialized(session, 0); return ret; } @@ -4120,7 +4149,6 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, return CKR_SESSION_HANDLE_INVALID; if (pMechanism == NULL) return CKR_ARGUMENTS_BAD; - ret = WP11_Object_Find(session, hKey, &obj); #ifdef WOLFSSL_MAXQ10XX_CRYPTO if ((ret != 0) && (hKey == 0) && (pMechanism->mechanism == CKM_ECDSA)) { @@ -4130,6 +4158,11 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, /* The private key is pre-provisioned so no object to set. */ init = WP11_INIT_ECDSA_SIGN; + if (WP11_Session_IsOpInitializedExact(session, init)) { + rv = CKR_OPERATION_ACTIVE; + WOLFPKCS11_LEAVE("C_SignInit", rv); + return rv; + } WP11_Session_SetMechanism(session, pMechanism->mechanism); WP11_Session_SetOpInitialized(session, init); @@ -4396,6 +4429,11 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, return CKR_MECHANISM_INVALID; } + if (WP11_Session_IsOpInitializedExact(session, init)) { + rv = CKR_OPERATION_ACTIVE; + WOLFPKCS11_LEAVE("C_SignInit", rv); + return rv; + } WP11_Session_SetMechanism(session, pMechanism->mechanism); WP11_Session_SetObject(session, obj); WP11_Session_SetOpInitialized(session, init); @@ -4520,11 +4558,14 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, if (wc_Hash(hash_type, pData, (word32)ulDataLen, digest, sizeof(digest)) != 0 || (dataSz = wc_HashGetDigestSize(hash_type)) < 0) { - return CKR_FUNCTION_FAILED; + ret = -1; + break; } oid = wc_HashGetOID(hash_type); - if (oid < 0) - return CKR_FUNCTION_FAILED; + if (oid < 0) { + ret = -1; + break; + } ret = wc_EncodeSignature(digest, digest, dataSz, oid); @@ -4533,7 +4574,8 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, dataSz = ret; } else { - return CKR_FUNCTION_FAILED; + ret = -1; + break; } } @@ -4585,7 +4627,8 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, if (wc_Hash(hash_type, pData, (word32)ulDataLen, digest, sizeof(digest)) != 0 || (dataSz = wc_HashGetDigestSize(hash_type)) < 0) { - return CKR_FUNCTION_FAILED; + ret = -1; + break; } data = digest; } @@ -4636,7 +4679,8 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, if (wc_Hash(hash_type, pData, (word32)ulDataLen, digest, sizeof(digest)) != 0 || (dataSz = wc_HashGetDigestSize(hash_type)) < 0) { - return CKR_FUNCTION_FAILED; + ret = -1; + break; } data = digest; } @@ -4761,11 +4805,15 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, (void)sigLen; (void)ulDataLen; (void)pSignature; + WP11_Session_SetOpInitialized(session, 0); return CKR_MECHANISM_INVALID; } - if (ret < 0) + if (ret < 0) { + WP11_Session_SetOpInitialized(session, 0); return CKR_FUNCTION_FAILED; + } + WP11_Session_SetOpInitialized(session, 0); return CKR_OK; } @@ -5207,7 +5255,6 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, WOLFPKCS11_LEAVE("C_VerifyInit", rv); return rv; } - ret = WP11_Object_Find(session, hKey, &obj); if (ret != 0) { rv = CKR_OBJECT_HANDLE_INVALID; @@ -5458,6 +5505,11 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession, return CKR_MECHANISM_INVALID; } + if (WP11_Session_IsOpInitializedExact(session, init)) { + rv = CKR_OPERATION_ACTIVE; + WOLFPKCS11_LEAVE("C_VerifyInit", rv); + return rv; + } WP11_Session_SetMechanism(session, pMechanism->mechanism); WP11_Session_SetObject(session, obj); WP11_Session_SetOpInitialized(session, init); @@ -5570,11 +5622,14 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, if (wc_Hash(hash_type, pData, (word32)ulDataLen, digest, sizeof(digest)) != 0 || (dataSz = wc_HashGetDigestSize(hash_type)) < 0) { - return CKR_FUNCTION_FAILED; + ret = -1; + break; } oid = wc_HashGetOID(hash_type); - if (oid < 0) - return CKR_FUNCTION_FAILED; + if (oid < 0) { + ret = -1; + break; + } ret = wc_EncodeSignature(digest, digest, dataSz, oid); @@ -5583,7 +5638,8 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, dataSz = ret; } else { - return CKR_FUNCTION_FAILED; + ret = -1; + break; } } @@ -5624,7 +5680,8 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, if (wc_Hash(hash_type, pData, (word32)ulDataLen, digest, sizeof(digest)) != 0 || (dataSz = wc_HashGetDigestSize(hash_type)) < 0) { - return CKR_FUNCTION_FAILED; + ret = -1; + break; } data = digest; } @@ -5666,7 +5723,8 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, if (wc_Hash(hash_type, pData, (word32)ulDataLen, digest, sizeof(digest)) != 0 || (dataSz = wc_HashGetDigestSize(hash_type)) < 0) { - return CKR_FUNCTION_FAILED; + ret = -1; + break; } data = digest; } @@ -5758,8 +5816,10 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, default: (void)ulDataLen; (void)ulSignatureLen; + WP11_Session_SetOpInitialized(session, 0); return CKR_MECHANISM_INVALID; } + WP11_Session_SetOpInitialized(session, 0); if (ret < 0) return CKR_FUNCTION_FAILED; if (!stat) @@ -5998,6 +6058,7 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession, (void)ulSignatureLen; return CKR_MECHANISM_INVALID; } + WP11_Session_SetOpInitialized(session, 0); if (ret < 0) return CKR_FUNCTION_FAILED; if (!stat) @@ -6088,6 +6149,11 @@ CK_RV C_VerifyRecoverInit(CK_SESSION_HANDLE hSession, if (ret != CKR_OK) return ret; + if (WP11_Session_IsOpInitializedExact(session, init)) { + rv = CKR_OPERATION_ACTIVE; + WOLFPKCS11_LEAVE("C_VerifyRecoverInit", rv); + return rv; + } WP11_Session_SetMechanism(session, pMechanism->mechanism); WP11_Session_SetObject(session, obj); WP11_Session_SetOpInitialized(session, init); diff --git a/src/internal.c b/src/internal.c index 883796c0..b35f35a1 100644 --- a/src/internal.c +++ b/src/internal.c @@ -954,6 +954,8 @@ static void wp11_Session_Final(WP11_Session* session) } #endif #endif + /* Clear any remaining active operation state not handled above. */ + session->init = 0; } #ifndef WOLFPKCS11_NO_STORE @@ -7122,6 +7124,21 @@ int WP11_Session_IsOpInitialized(WP11_Session* session, int init) return (session->init & ~WP11_INIT_DIGEST_MASK) == init; } +/** + * Check whether the session is initialized for an exact operation value. + * Unlike WP11_Session_IsOpInitialized, this compares the full init value + * including digest hash bits. + * + * @param session [in] Session object. + * @param init [in] Expected full init value (including digest bits). + * @return 1 when session init matches exactly. + * 0 otherwise. + */ +int WP11_Session_IsOpInitializedExact(WP11_Session* session, int init) +{ + return session->init == init; +} + int WP11_Session_UpdateData(WP11_Session *session, byte *data, word32 dataLen) { int ret = 0; @@ -14727,6 +14744,8 @@ int WP11_SetOperationState(WP11_Session* session, unsigned char* stateData, hashAlg = &session->params.digest.hash.alg; #endif + session->init = WP11_INIT_DIGEST; + switch (session->mechanism) { #ifndef NO_MD5 case CKM_MD5: diff --git a/tests/include.am b/tests/include.am index 725c474c..6cf5eb1f 100644 --- a/tests/include.am +++ b/tests/include.am @@ -56,6 +56,11 @@ noinst_PROGRAMS += tests/ecb_check_value_error_test tests_ecb_check_value_error_test_SOURCES = tests/ecb_check_value_error_test.c tests_ecb_check_value_error_test_LDADD = +check_PROGRAMS += tests/operation_active_test +noinst_PROGRAMS += tests/operation_active_test +tests_operation_active_test_SOURCES = tests/operation_active_test.c +tests_operation_active_test_LDADD = + check_PROGRAMS += tests/pkcs11v3test noinst_PROGRAMS += tests/pkcs11v3test tests_pkcs11v3test_SOURCES = tests/pkcs11v3test.c @@ -73,6 +78,7 @@ tests_empty_pin_store_test_LDADD += src/libwolfpkcs11.la tests_find_objects_null_template_test_LDADD += src/libwolfpkcs11.la tests_aes_cbc_pad_padding_test_LDADD += src/libwolfpkcs11.la tests_ecb_check_value_error_test_LDADD += src/libwolfpkcs11.la +tests_operation_active_test_LDADD += src/libwolfpkcs11.la tests_pkcs11v3test_LDADD += src/libwolfpkcs11.la else tests_object_id_uniqueness_test_LDADD += src/libwolfpkcs11.la @@ -80,6 +86,7 @@ tests_empty_pin_store_test_LDADD += src/libwolfpkcs11.la tests_find_objects_null_template_test_LDADD += src/libwolfpkcs11.la tests_aes_cbc_pad_padding_test_LDADD += src/libwolfpkcs11.la tests_ecb_check_value_error_test_LDADD += src/libwolfpkcs11.la +tests_operation_active_test_LDADD += src/libwolfpkcs11.la endif EXTRA_DIST += tests/unit.h \ diff --git a/tests/operation_active_test.c b/tests/operation_active_test.c new file mode 100644 index 00000000..16300957 --- /dev/null +++ b/tests/operation_active_test.c @@ -0,0 +1,587 @@ +/* operation_active_test.c + * + * Copyright (C) 2026 wolfSSL Inc. + * + * This file is part of wolfPKCS11. + * + * wolfPKCS11 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfPKCS11 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + * + * Test for bug #1616: C_EncryptInit, C_DecryptInit, C_DigestInit, C_SignInit, + * and C_VerifyInit must return CKR_OPERATION_ACTIVE when an operation of the + * same type is already active on the session. + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include + +#ifndef WOLFPKCS11_USER_SETTINGS + #include +#endif +#include + +#ifndef HAVE_PKCS11_STATIC +#include +#endif + +#include "testdata.h" + +#if !defined(NO_AES) && !defined(NO_AES_CBC) + +#define OP_ACTIVE_TEST_DIR "./store/operation_active_test" +#define WOLFPKCS11_TOKEN_FILENAME "wp11_token_0000000000000001" + +static int test_passed = 0; +static int test_failed = 0; + +#define CHECK_CKR(rv, op, expected) do { \ + if (rv != expected) { \ + fprintf(stderr, "FAIL: %s: expected %ld, got %ld\n", op, (long)expected, (long)rv); \ + test_failed++; \ + result = -1; \ + goto cleanup; \ + } else { \ + printf("PASS: %s\n", op); \ + test_passed++; \ + } \ +} while(0) + +#ifndef HAVE_PKCS11_STATIC +static void* dlib; +#endif +static CK_FUNCTION_LIST* funcList; +static CK_SLOT_ID slot = 0; +static const char* tokenName = "wolfpkcs11"; +static byte* soPin = (byte*)"password123456"; +static int soPinLen = 14; +static byte* userPin = (byte*)"someUserPin"; +static int userPinLen = 11; + +static CK_OBJECT_CLASS secretKeyClass = CKO_SECRET_KEY; +static CK_BBOOL ckTrue = CK_TRUE; +static CK_KEY_TYPE aesKeyType = CKK_AES; +#ifndef NO_HMAC +static CK_KEY_TYPE genericKeyType = CKK_GENERIC_SECRET; +#endif + +static CK_RV pkcs11_init(void) +{ + CK_RV ret; + CK_C_INITIALIZE_ARGS args; + CK_INFO info; + CK_SLOT_ID slotList[16]; + CK_ULONG slotCount = sizeof(slotList) / sizeof(slotList[0]); + +#ifndef HAVE_PKCS11_STATIC + CK_C_GetFunctionList func; + + dlib = dlopen(WOLFPKCS11_DLL_FILENAME, RTLD_NOW | RTLD_LOCAL); + if (dlib == NULL) { + fprintf(stderr, "dlopen error: %s\n", dlerror()); + return -1; + } + + func = (CK_C_GetFunctionList)dlsym(dlib, "C_GetFunctionList"); + if (func == NULL) { + fprintf(stderr, "Failed to get function list function\n"); + dlclose(dlib); + return -1; + } + + ret = func(&funcList); + if (ret != CKR_OK) { + fprintf(stderr, "Failed to get function list: 0x%lx\n", + (unsigned long)ret); + dlclose(dlib); + return ret; + } +#else + ret = C_GetFunctionList(&funcList); + if (ret != CKR_OK) { + fprintf(stderr, "Failed to get function list: 0x%lx\n", + (unsigned long)ret); + return ret; + } +#endif + + XMEMSET(&args, 0, sizeof(args)); + args.flags = CKF_OS_LOCKING_OK; + ret = funcList->C_Initialize(&args); + if (ret != CKR_OK) + return ret; + + ret = funcList->C_GetInfo(&info); + if (ret != CKR_OK) + return ret; + + ret = funcList->C_GetSlotList(CK_TRUE, slotList, &slotCount); + if (ret != CKR_OK) + return ret; + + if (slotCount > 0) { + slot = slotList[0]; + } else { + fprintf(stderr, "No slots available\n"); + return CKR_GENERAL_ERROR; + } + + return ret; +} + +static CK_RV pkcs11_final(void) +{ + if (funcList != NULL) { + funcList->C_Finalize(NULL); + funcList = NULL; + } +#ifndef HAVE_PKCS11_STATIC + if (dlib) { + dlclose(dlib); + dlib = NULL; + } +#endif + return CKR_OK; +} + +static CK_RV pkcs11_init_token(void) +{ + unsigned char label[32]; + + XMEMSET(label, ' ', sizeof(label)); + XMEMCPY(label, tokenName, XSTRLEN(tokenName)); + + return funcList->C_InitToken(slot, soPin, soPinLen, label); +} + +static CK_RV pkcs11_open_session(CK_SESSION_HANDLE* session) +{ + CK_RV ret; + int sessFlags = CKF_SERIAL_SESSION | CKF_RW_SESSION; + + ret = funcList->C_OpenSession(slot, sessFlags, NULL, NULL, session); + if (ret != CKR_OK) + return ret; + + ret = funcList->C_Login(*session, CKU_USER, userPin, userPinLen); + if (ret != CKR_OK) { + funcList->C_CloseSession(*session); + return ret; + } + + return CKR_OK; +} + +static CK_RV pkcs11_close_session(CK_SESSION_HANDLE session) +{ + funcList->C_Logout(session); + return funcList->C_CloseSession(session); +} + +static void cleanup_test_files(const char* dir) +{ + char filepath[512]; + + snprintf(filepath, sizeof(filepath), "%s" PATH_SEP "%s", dir, + WOLFPKCS11_TOKEN_FILENAME); + (void)remove(filepath); +} + +static CK_RV create_aes_128_key(CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE* key) +{ + CK_ATTRIBUTE tmpl[] = { + { CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass) }, + { CKA_KEY_TYPE, &aesKeyType, sizeof(aesKeyType) }, + { CKA_ENCRYPT, &ckTrue, sizeof(ckTrue) }, + { CKA_DECRYPT, &ckTrue, sizeof(ckTrue) }, + { CKA_VALUE, aes_128_key, sizeof(aes_128_key) }, + { CKA_TOKEN, &ckTrue, sizeof(ckTrue) }, + }; + CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl); + + return funcList->C_CreateObject(session, tmpl, tmplCnt, key); +} + +#ifndef NO_HMAC +static CK_RV create_hmac_key(CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE* key) +{ + CK_ATTRIBUTE tmpl[] = { + { CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass) }, + { CKA_KEY_TYPE, &genericKeyType, sizeof(genericKeyType) }, + { CKA_SIGN, &ckTrue, sizeof(ckTrue) }, + { CKA_VERIFY, &ckTrue, sizeof(ckTrue) }, + { CKA_VALUE, (void*)hmac_key, sizeof(hmac_key) }, + { CKA_TOKEN, &ckTrue, sizeof(ckTrue) }, + }; + CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl); + + return funcList->C_CreateObject(session, tmpl, tmplCnt, key); +} +#endif /* !NO_HMAC */ + +/* + * Test 1: C_EncryptInit called twice without completing the operation. + * Second call must return CKR_OPERATION_ACTIVE. + */ +static int test_encrypt_init_double(CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE aesKey) +{ + CK_RV ret; + CK_MECHANISM mech; + byte iv[16]; + byte buf[16]; + CK_ULONG bufSz; + int result = 0; + + XMEMSET(iv, 0, sizeof(iv)); + + mech.mechanism = CKM_AES_CBC; + mech.pParameter = iv; + mech.ulParameterLen = sizeof(iv); + + /* First init should succeed */ + ret = funcList->C_EncryptInit(session, &mech, aesKey); + CHECK_CKR(ret, "EncryptInit double: first C_EncryptInit", CKR_OK); + + /* Second init should return CKR_OPERATION_ACTIVE */ + ret = funcList->C_EncryptInit(session, &mech, aesKey); + CHECK_CKR(ret, "EncryptInit double: second C_EncryptInit", + CKR_OPERATION_ACTIVE); + +cleanup: + /* Clean up active operation */ + bufSz = sizeof(buf); + XMEMSET(buf, 0, sizeof(buf)); + (void)funcList->C_Encrypt(session, buf, sizeof(buf), buf, &bufSz); + return result; +} + +/* + * Test 2: C_DecryptInit called twice without completing the operation. + * Second call must return CKR_OPERATION_ACTIVE. + */ +static int test_decrypt_init_double(CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE aesKey) +{ + CK_RV ret; + CK_MECHANISM mech; + byte iv[16]; + byte buf[16]; + CK_ULONG bufSz; + int result = 0; + + XMEMSET(iv, 0, sizeof(iv)); + + mech.mechanism = CKM_AES_CBC; + mech.pParameter = iv; + mech.ulParameterLen = sizeof(iv); + + ret = funcList->C_DecryptInit(session, &mech, aesKey); + CHECK_CKR(ret, "DecryptInit double: first C_DecryptInit", CKR_OK); + + ret = funcList->C_DecryptInit(session, &mech, aesKey); + CHECK_CKR(ret, "DecryptInit double: second C_DecryptInit", + CKR_OPERATION_ACTIVE); + +cleanup: + bufSz = sizeof(buf); + XMEMSET(buf, 0, sizeof(buf)); + (void)funcList->C_Decrypt(session, buf, sizeof(buf), buf, &bufSz); + return result; +} + +/* + * Test 3: C_DigestInit called twice without completing the operation. + * Second call must return CKR_OPERATION_ACTIVE. + */ +static int test_digest_init_double(CK_SESSION_HANDLE session) +{ + CK_RV ret; + CK_MECHANISM mech; + byte buf[32]; + CK_ULONG bufSz; + int result = 0; + + mech.mechanism = CKM_SHA256; + mech.pParameter = NULL; + mech.ulParameterLen = 0; + + ret = funcList->C_DigestInit(session, &mech); + CHECK_CKR(ret, "DigestInit double: first C_DigestInit", CKR_OK); + + ret = funcList->C_DigestInit(session, &mech); + CHECK_CKR(ret, "DigestInit double: second C_DigestInit", + CKR_OPERATION_ACTIVE); + +cleanup: + bufSz = sizeof(buf); + (void)funcList->C_Digest(session, (CK_BYTE_PTR)"abc", 3, buf, &bufSz); + return result; +} + +#ifndef NO_HMAC +/* + * Test 4: C_SignInit called twice without completing the operation. + * Second call must return CKR_OPERATION_ACTIVE. + */ +static int test_sign_init_double(CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE hmacKey) +{ + CK_RV ret; + CK_MECHANISM mech; + byte buf[32]; + CK_ULONG bufSz; + int result = 0; + + mech.mechanism = CKM_SHA256_HMAC; + mech.pParameter = NULL; + mech.ulParameterLen = 0; + + ret = funcList->C_SignInit(session, &mech, hmacKey); + CHECK_CKR(ret, "SignInit double: first C_SignInit", CKR_OK); + + ret = funcList->C_SignInit(session, &mech, hmacKey); + CHECK_CKR(ret, "SignInit double: second C_SignInit", + CKR_OPERATION_ACTIVE); + +cleanup: + bufSz = sizeof(buf); + (void)funcList->C_Sign(session, (CK_BYTE_PTR)"abc", 3, buf, &bufSz); + return result; +} + +/* + * Test 5: C_VerifyInit called twice without completing the operation. + * Second call must return CKR_OPERATION_ACTIVE. + */ +static int test_verify_init_double(CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE hmacKey) +{ + CK_RV ret; + CK_MECHANISM mech; + byte buf[32]; + int result = 0; + + mech.mechanism = CKM_SHA256_HMAC; + mech.pParameter = NULL; + mech.ulParameterLen = 0; + + ret = funcList->C_VerifyInit(session, &mech, hmacKey); + CHECK_CKR(ret, "VerifyInit double: first C_VerifyInit", CKR_OK); + + ret = funcList->C_VerifyInit(session, &mech, hmacKey); + CHECK_CKR(ret, "VerifyInit double: second C_VerifyInit", + CKR_OPERATION_ACTIVE); + +cleanup: + XMEMSET(buf, 0, sizeof(buf)); + (void)funcList->C_Verify(session, (CK_BYTE_PTR)"abc", 3, buf, sizeof(buf)); + return result; +} +#endif /* !NO_HMAC */ + +static int operation_active_test(void) +{ + CK_RV ret; + CK_SESSION_HANDLE session = 0; + CK_OBJECT_HANDLE aesKey; +#ifndef NO_HMAC + CK_OBJECT_HANDLE hmacKey; +#endif + int result = 0; + + printf("\n=== Testing Init double-call returns CKR_OPERATION_ACTIVE ===\n"); + + cleanup_test_files(OP_ACTIVE_TEST_DIR); + + ret = pkcs11_init(); + if (ret != CKR_OK) { + fprintf(stderr, "FAIL: pkcs11_init: 0x%lx\n", (unsigned long)ret); + test_failed++; + return -1; + } + + ret = pkcs11_init_token(); + if (ret != CKR_OK) { + fprintf(stderr, "FAIL: C_InitToken: 0x%lx\n", (unsigned long)ret); + test_failed++; + pkcs11_final(); + return -1; + } + + /* Set user PIN via SO session */ + { + CK_SESSION_HANDLE soSession; + int sessFlags = CKF_SERIAL_SESSION | CKF_RW_SESSION; + + ret = funcList->C_OpenSession(slot, sessFlags, NULL, NULL, &soSession); + if (ret != CKR_OK) { + fprintf(stderr, "FAIL: C_OpenSession (SO): 0x%lx\n", + (unsigned long)ret); + test_failed++; + pkcs11_final(); + return -1; + } + + ret = funcList->C_Login(soSession, CKU_SO, soPin, soPinLen); + if (ret != CKR_OK) { + fprintf(stderr, "FAIL: C_Login (SO): 0x%lx\n", + (unsigned long)ret); + test_failed++; + funcList->C_CloseSession(soSession); + pkcs11_final(); + return -1; + } + + ret = funcList->C_InitPIN(soSession, userPin, userPinLen); + if (ret != CKR_OK) { + fprintf(stderr, "FAIL: C_InitPIN: 0x%lx\n", (unsigned long)ret); + test_failed++; + funcList->C_Logout(soSession); + funcList->C_CloseSession(soSession); + pkcs11_final(); + return -1; + } + + funcList->C_Logout(soSession); + funcList->C_CloseSession(soSession); + } + + ret = pkcs11_open_session(&session); + if (ret != CKR_OK) { + fprintf(stderr, "FAIL: pkcs11_open_session: 0x%lx\n", + (unsigned long)ret); + test_failed++; + pkcs11_final(); + return -1; + } + + /* Create keys */ + ret = create_aes_128_key(session, &aesKey); + if (ret != CKR_OK) { + fprintf(stderr, "FAIL: create_aes_128_key: 0x%lx\n", + (unsigned long)ret); + test_failed++; + pkcs11_close_session(session); + pkcs11_final(); + return -1; + } + +#ifndef NO_HMAC + ret = create_hmac_key(session, &hmacKey); + if (ret != CKR_OK) { + fprintf(stderr, "FAIL: create_hmac_key: 0x%lx\n", + (unsigned long)ret); + test_failed++; + pkcs11_close_session(session); + pkcs11_final(); + return -1; + } +#endif + + /* Run tests -- close and reopen the session between each test + * to ensure no leftover operation state leaks between tests. */ + if (test_encrypt_init_double(session, aesKey) != 0) + result = -1; + pkcs11_close_session(session); + session = CK_INVALID_HANDLE; + ret = pkcs11_open_session(&session); + if (ret != CKR_OK) goto done; + + if (test_decrypt_init_double(session, aesKey) != 0) + result = -1; + pkcs11_close_session(session); + session = CK_INVALID_HANDLE; + ret = pkcs11_open_session(&session); + if (ret != CKR_OK) goto done; + + if (test_digest_init_double(session) != 0) + result = -1; + pkcs11_close_session(session); + session = CK_INVALID_HANDLE; + ret = pkcs11_open_session(&session); + if (ret != CKR_OK) goto done; + +#ifndef NO_HMAC + if (test_sign_init_double(session, hmacKey) != 0) + result = -1; + pkcs11_close_session(session); + session = CK_INVALID_HANDLE; + ret = pkcs11_open_session(&session); + if (ret != CKR_OK) goto done; + + if (test_verify_init_double(session, hmacKey) != 0) + result = -1; +#endif + +done: + if (session != CK_INVALID_HANDLE) + pkcs11_close_session(session); + pkcs11_final(); + return result; +} + +static void print_results(void) +{ + printf("\n=== Test Results ===\n"); + printf("Tests passed: %d\n", test_passed); + printf("Tests failed: %d\n", test_failed); + + if (test_failed == 0) { + printf("ALL TESTS PASSED!\n"); + } else { + printf("SOME TESTS FAILED!\n"); + } +} + +int main(int argc, char* argv[]) +{ +#ifndef WOLFPKCS11_NO_ENV + XSETENV("WOLFPKCS11_TOKEN_PATH", OP_ACTIVE_TEST_DIR, 1); +#endif + + (void)argc; + (void)argv; + + printf("=== wolfPKCS11 Operation Active Test (bug #1616) ===\n"); + + (void)operation_active_test(); + + print_results(); + + return (test_failed == 0) ? 0 : 1; +} + +#else /* NO_AES || NO_AES_CBC */ + +int main(int argc, char* argv[]) +{ + (void)argc; + (void)argv; + + printf("AES-CBC not available, skipping operation active test\n"); + return 0; +} + +#endif /* !NO_AES && !NO_AES_CBC */ diff --git a/tests/pkcs11mtt.c b/tests/pkcs11mtt.c index 4fd187fc..559a3c2d 100644 --- a/tests/pkcs11mtt.c +++ b/tests/pkcs11mtt.c @@ -2627,6 +2627,10 @@ static CK_RV rsa_pkcs15_sig_test(CK_SESSION_HANDLE session, ret = funcList->C_Verify(session, hash, hashSz, out, outSz); CHECK_CKR(ret, "RSA PKCS#1.5 Verify"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pub); + CHECK_CKR(ret, "RSA PKCS#1.5 Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, badHash, sizeof(badHash), out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, @@ -2687,6 +2691,10 @@ static CK_RV rsa_pss_test(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv, ret = funcList->C_Verify(session, hash, hashSz, out, outSz); CHECK_CKR(ret, "RSA PKCS#1 PSS Verify"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pub); + CHECK_CKR(ret, "RSA PKCS#1 PSS Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, badHash, hashSz, out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, @@ -2703,6 +2711,10 @@ static CK_RV rsa_pss_test(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv, "RSA PKCS#1 PSS Sign out size too small"); outSz = sizeof(out); } + if (ret == CKR_OK) { + ret = funcList->C_Sign(session, hash, hashSz, out, &outSz); + CHECK_CKR(ret, "RSA PKCS#1 PSS Sign cleanup"); + } return ret; } @@ -3805,10 +3817,18 @@ static CK_RV ecdsa_test(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE privKey, ret = funcList->C_Verify(session, hash, hashSz, out, outSz); CHECK_CKR(ret, "ECDSA Verify"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pubKey); + CHECK_CKR(ret, "ECDSA Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, hash, hashSz - 1, out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, "ECDSA Verify bad hash"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pubKey); + CHECK_CKR(ret, "ECDSA Verify Init bad sig"); + } if (ret == CKR_OK) { outSz = 1; ret = funcList->C_Verify(session, hash, hashSz, out, outSz); @@ -5951,6 +5971,10 @@ static CK_RV test_hmac_update(CK_SESSION_HANDLE session, int mechanism, "HMAC Sign Final out size too small"); outSz = sizeof(out); } + if (ret == CKR_OK) { + ret = funcList->C_SignFinal(session, out, &outSz); + CHECK_CKR(ret, "HMAC Sign Final cleanup"); + } return ret; } diff --git a/tests/pkcs11test.c b/tests/pkcs11test.c index 17a3e62f..d73661d3 100644 --- a/tests/pkcs11test.c +++ b/tests/pkcs11test.c @@ -7212,6 +7212,10 @@ static CK_RV rsa_x_509_sig_test(CK_SESSION_HANDLE session, ret = funcList->C_Verify(session, hash, hashSz, out, outSz); CHECK_CKR(ret, "RSA X_509 Verify"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pub); + CHECK_CKR(ret, "RSA X_509 Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, badHash, sizeof(badHash), out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, "RSA X_509 Verify bad hash"); @@ -7267,6 +7271,10 @@ static CK_RV rsa_pkcs15_sig_test(CK_SESSION_HANDLE session, ret = funcList->C_Verify(session, hash, hashSz, out, outSz); CHECK_CKR(ret, "RSA PKCS#1.5 Verify"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pub); + CHECK_CKR(ret, "RSA PKCS#1.5 Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, badHash, sizeof(badHash), out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, @@ -7400,6 +7408,10 @@ static CK_RV sha256_rsa_pkcs15_sig_test(CK_SESSION_HANDLE session, ret = funcList->C_Verify(session, hash, hashSz, out, outSz); CHECK_CKR(ret, "RSA PKCS#1.5 Verify"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pub); + CHECK_CKR(ret, "RSA PKCS#1.5 Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, badHash, sizeof(badHash), out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, @@ -7461,6 +7473,10 @@ static CK_RV rsa_pss_test(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv, ret = funcList->C_Verify(session, hash, hashSz, out, outSz); CHECK_CKR(ret, "RSA PKCS#1 PSS Verify"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pub); + CHECK_CKR(ret, "RSA PKCS#1 PSS Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, badHash, hashSz, out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, @@ -7477,6 +7493,10 @@ static CK_RV rsa_pss_test(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE priv, "RSA PKCS#1 PSS Sign out size too small"); outSz = sizeof(out); } + if (ret == CKR_OK) { + ret = funcList->C_Sign(session, hash, hashSz, out, &outSz); + CHECK_CKR(ret, "RSA PKCS#1 PSS Sign cleanup"); + } return ret; } @@ -7533,6 +7553,10 @@ static CK_RV sha256_rsa_pss_test(CK_SESSION_HANDLE session, ret = funcList->C_Verify(session, hash, hashSz, out, outSz); CHECK_CKR(ret, "RSA PKCS#1 PSS Verify"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pub); + CHECK_CKR(ret, "RSA PKCS#1 PSS Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, badHash, hashSz, out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, @@ -7549,6 +7573,10 @@ static CK_RV sha256_rsa_pss_test(CK_SESSION_HANDLE session, "RSA PKCS#1 PSS Sign out size too small"); outSz = sizeof(out); } + if (ret == CKR_OK) { + ret = funcList->C_Sign(session, hash, hashSz, out, &outSz); + CHECK_CKR(ret, "RSA PKCS#1 PSS Sign cleanup"); + } return ret; } @@ -8835,10 +8863,18 @@ static CK_RV ecdsa_test(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE privKey, CHECK_CKR(ret, "ECDSA Verify"); } #endif + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pubKey); + CHECK_CKR(ret, "ECDSA Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, hash, hashSz - 1, out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, "ECDSA Verify bad hash"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pubKey); + CHECK_CKR(ret, "ECDSA Verify Init bad sig"); + } if (ret == CKR_OK) { outSz = 1; ret = funcList->C_Verify(session, hash, hashSz, out, outSz); @@ -8893,10 +8929,18 @@ static CK_RV ecdsa_test(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE privKey, CHECK_CKR(ret, "ECDSA Verify"); } #endif + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pubKey); + CHECK_CKR(ret, "ECDSA Verify Init bad hash"); + } if (ret == CKR_OK) { ret = funcList->C_Verify(session, data, dataSz - 1, out, outSz); CHECK_CKR_FAIL(ret, CKR_SIGNATURE_INVALID, "ECDSA Verify bad hash"); } + if (ret == CKR_OK) { + ret = funcList->C_VerifyInit(session, &mech, pubKey); + CHECK_CKR(ret, "ECDSA Verify Init bad sig"); + } if (ret == CKR_OK) { outSz = 1; ret = funcList->C_Verify(session, data, dataSz, out, outSz); @@ -12396,6 +12440,10 @@ static CK_RV test_aes_cmac_update(CK_SESSION_HANDLE session, unsigned char* exp, "AES-CMAC Sign Final out size too small"); outSz = sizeof(out); } + if (ret == CKR_OK) { + ret = funcList->C_SignFinal(session, out, &outSz); + CHECK_CKR(ret, "AES-CMAC Sign Final cleanup"); + } return ret; } @@ -12568,6 +12616,10 @@ static CK_RV test_aes_cmac_general_update(CK_SESSION_HANDLE session, "AES-CMAC Sign Final out size too small"); outSz = sizeof(out); } + if (ret == CKR_OK) { + ret = funcList->C_SignFinal(session, out, &outSz); + CHECK_CKR(ret, "AES-CMAC Sign Final cleanup"); + } return ret; } @@ -12915,6 +12967,10 @@ static CK_RV test_hmac_update(CK_SESSION_HANDLE session, int mechanism, "HMAC Sign Final out size too small"); outSz = sizeof(out); } + if (ret == CKR_OK) { + ret = funcList->C_SignFinal(session, out, &outSz); + CHECK_CKR(ret, "HMAC Sign Final cleanup"); + } return ret; } diff --git a/wolfpkcs11/internal.h b/wolfpkcs11/internal.h index f7494dde..d8afe1fd 100644 --- a/wolfpkcs11/internal.h +++ b/wolfpkcs11/internal.h @@ -368,6 +368,8 @@ WP11_LOCAL int WP11_Session_Get(CK_SESSION_HANDLE sessionHandle, WP11_Session** WP11_LOCAL int WP11_Session_GetState(WP11_Session* session); WP11_LOCAL int WP11_Session_IsRW(WP11_Session* session); WP11_LOCAL int WP11_Session_IsOpInitialized(WP11_Session* session, int init); +WP11_LOCAL int WP11_Session_IsOpInitializedExact(WP11_Session* session, + int init); WP11_LOCAL int WP11_Session_UpdateData(WP11_Session *session, byte *data, word32 dataLen); WP11_LOCAL void WP11_Session_GetData(WP11_Session *session, byte** data, word32* dataLen); WP11_LOCAL void WP11_Session_FreeData(WP11_Session *session);