Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 23 additions & 3 deletions src/crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,11 @@ static CK_RV SetAttributeDefaults(WP11_Object* obj, CK_OBJECT_CLASS keyType,
ulCount);
break;
case CKO_SECRET_KEY:
#ifndef WOLFPKCS11_NSS
if (ret == CKR_OK)
ret = SetIfNotFound(obj, CKA_SENSITIVE, trueVal, pTemplate,
ulCount);
#endif
if (ret == CKR_OK)
ret = SetIfNotFound(obj, CKA_EXTRACTABLE, trueVal, pTemplate,
ulCount);
Expand All @@ -531,9 +536,21 @@ static CK_RV SetAttributeDefaults(WP11_Object* obj, CK_OBJECT_CLASS keyType,
ulCount);
break;
case CKO_PRIVATE_KEY:
#ifndef WOLFPKCS11_NSS
if (ret == CKR_OK)
ret = SetIfNotFound(obj, CKA_SENSITIVE, trueVal, pTemplate,
ulCount);
if (ret == CKR_OK)
ret = SetIfNotFound(obj, CKA_EXTRACTABLE, falseVal, pTemplate,
ulCount);
#else
/* NSS operates as the internal crypto module and needs both
* non-sensitive and extractable private keys to read key material
* directly via C_GetAttributeValue during TLS operations. */
if (ret == CKR_OK)
ret = SetIfNotFound(obj, CKA_EXTRACTABLE, trueVal, pTemplate,
ulCount);
#endif
if (ret == CKR_OK)
ret = SetIfNotFound(obj, CKA_DECRYPT, encrypt, pTemplate,
ulCount);
Expand Down Expand Up @@ -2277,10 +2294,13 @@ CK_RV C_Encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
}
if (!CK_ULONG_FITS_WORD32(ulDataLen))
return CKR_DATA_LEN_RANGE;
/* Ensure padded result fits in word32 */
if (ulDataLen > (CK_ULONG)(0xFFFFFFFF - AES_BLOCK_SIZE))
return CKR_DATA_LEN_RANGE;

/* PKCS#5 pad makes the output a multiple of 16 */
encDataLen = (word32)((ulDataLen + AES_BLOCK_SIZE - 1) /
AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
/* PKCS#7 padding always adds at least 1 byte */
encDataLen = (word32)((ulDataLen / AES_BLOCK_SIZE) + 1) *
AES_BLOCK_SIZE;
if (pEncryptedData == NULL) {
*pulEncryptedDataLen = encDataLen;
return CKR_OK;
Expand Down
64 changes: 59 additions & 5 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,31 @@ static void wp11_Session_Final(WP11_Session* session)
}
#endif
#endif
/* Clear any remaining active operation state not handled above. */
#ifndef NO_HMAC
if ((session->init & ~WP11_INIT_DIGEST_MASK) == WP11_INIT_HMAC_SIGN ||
(session->init & ~WP11_INIT_DIGEST_MASK) == WP11_INIT_HMAC_VERIFY) {
wc_HmacFree(&session->params.hmac.hmac);
session->init &= WP11_INIT_DIGEST_MASK;
}
#endif
#ifdef HAVE_AESCMAC
if ((session->init & ~WP11_INIT_DIGEST_MASK) == WP11_INIT_AES_CMAC_SIGN ||
(session->init & ~WP11_INIT_DIGEST_MASK) == WP11_INIT_AES_CMAC_VERIFY) {
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3))
(void)wc_CmacFree(&session->params.cmac.cmac);
#else
wc_ForceZero(&session->params.cmac.cmac,
sizeof(session->params.cmac.cmac));
#endif
session->init &= WP11_INIT_DIGEST_MASK;
}
#endif
if ((session->init & ~WP11_INIT_DIGEST_MASK) == WP11_INIT_DIGEST) {
wc_HashFree(&session->params.digest.hash,
session->params.digest.hashType);
session->init &= ~WP11_INIT_DIGEST_MASK;
}
/* Ensure no stale bits remain after all cleanup. */
session->init = 0;
}

Expand Down Expand Up @@ -6964,6 +6988,9 @@ void WP11_Slot_Logout(WP11_Slot* slot)
ret = wp11_Object_Encode(object, 1);
object = object->next;
}
/* Zero token key only on user logout — SO logout must preserve it
* for subsequent object encryption (e.g., empty-PIN flow). */
wc_ForceZero(slot->token.key, sizeof(slot->token.key));
}
#endif
slot->token.loginState = WP11_APP_STATE_RW_PUBLIC;
Expand Down Expand Up @@ -8223,6 +8250,9 @@ static WP11_Object* wp11_Session_FindNext(WP11_Session* session, int onToken,
}
#endif

/* Note: this CKA_PRIVATE check is intentionally active in NSS mode.
* NSS accesses private objects by handle (via WP11_Object_Find) rather
* than discovering them through C_FindObjects enumeration. */
if ((ret->opFlag & WP11_FLAG_PRIVATE) == WP11_FLAG_PRIVATE) {
if (!onToken)
WP11_Lock_LockRO(&session->slot->token.lock);
Expand Down Expand Up @@ -9242,8 +9272,26 @@ int WP11_Object_Find(WP11_Session* session, CK_OBJECT_HANDLE objHandle,
WP11_Lock_UnlockRO(&session->slot->token.lock);
}

if (obj && (obj->handle == objHandle))
*object = obj;
if (ret == 0 && obj != NULL && (obj->handle == objHandle)) {
#ifndef WOLFPKCS11_NSS
/* Enforce CKA_PRIVATE: reject private objects from public sessions.
* Skipped in NSS mode because NSS operates as the internal crypto
* module without calling C_Login. */
if ((obj->opFlag & WP11_FLAG_PRIVATE) == WP11_FLAG_PRIVATE) {
int loginState;
WP11_Lock_LockRO(&session->slot->lock);
loginState = session->slot->token.loginState;
if (!WP11_Slot_Has_Empty_Pin(session->slot) &&
(loginState == WP11_APP_STATE_RW_PUBLIC ||
loginState == WP11_APP_STATE_RO_PUBLIC)) {
ret = BAD_FUNC_ARG;
}
WP11_Lock_UnlockRO(&session->slot->lock);
}
#endif
if (ret == 0)
*object = obj;
}

return ret;
}
Expand Down Expand Up @@ -11516,7 +11564,7 @@ int WP11_Rsa_Verify_Recover(CK_MECHANISM_TYPE mechanism, unsigned char* sig,
}
}
if (data_out != NULL) {
*outLen = (out + *outLen) - data_out;
*outLen = (CK_ULONG)((out + *outLen) - data_out);
XMEMMOVE(out, data_out, *outLen);
}
}
Expand Down Expand Up @@ -14304,15 +14352,21 @@ int WP11_Digest_Single(unsigned char* data, word32 dataLen,
WP11_Digest* digest = &session->params.digest;

blockLen = wc_HashGetDigestSize(digest->hashType);
if (blockLen < 0) {
wc_HashFree(&digest->hash, digest->hashType);
session->init = 0;
return CKR_FUNCTION_FAILED;
}

if (data == NULL) {
if (dataOut == NULL) {
*dataOutLen = (word32)blockLen;
return CKR_OK;
}
if (*dataOutLen < (word32)blockLen) {
return BUFFER_E;
}
ret = wc_Hash(digest->hashType, data, dataLen, dataOut, *dataOutLen);
*dataOutLen = (word32)blockLen;

wc_HashFree(&digest->hash, digest->hashType);

Expand Down
9 changes: 9 additions & 0 deletions tests/pkcs11mtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@ static CK_RV test_attribute(void* args)
{ CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
{ CKA_KEY_TYPE, &genericKeyType, sizeof(genericKeyType) },
{ CKA_EXTRACTABLE, &ckTrue, sizeof(ckTrue) },
{ CKA_SENSITIVE, &ckFalse, sizeof(ckFalse) },
{ CKA_VALUE, keyData, sizeof(keyData) },
};
CK_ULONG tmplCnt = sizeof(tmpl) / sizeof(*tmpl);
Expand Down Expand Up @@ -789,10 +790,12 @@ static CK_RV get_generic_key(CK_SESSION_HANDLE session, unsigned char* data,
CK_OBJECT_HANDLE* key)
{
CK_RV ret;
CK_BBOOL sensitive = (extractable == CK_TRUE) ? CK_FALSE : CK_TRUE;
CK_ATTRIBUTE generic_key[] = {
{ CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass) },
{ CKA_KEY_TYPE, &genericKeyType, sizeof(genericKeyType) },
{ CKA_EXTRACTABLE, &extractable, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &sensitive, sizeof(CK_BBOOL) },
{ CKA_SIGN, &ckTrue, sizeof(ckTrue) },
{ CKA_VERIFY, &ckTrue, sizeof(ckTrue) },
{ CKA_VALUE, data, len },
Expand Down Expand Up @@ -2053,6 +2056,7 @@ static CK_RV get_rsa_priv_key(CK_SESSION_HANDLE session, unsigned char* privId,
CK_OBJECT_HANDLE* obj)
{
CK_RV ret;
CK_BBOOL sensitive = (extractable == CK_TRUE) ? CK_FALSE : CK_TRUE;
CK_ATTRIBUTE rsa_2048_priv_key[] = {
{ CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
{ CKA_KEY_TYPE, &rsaKeyType, sizeof(rsaKeyType) },
Expand All @@ -2067,6 +2071,7 @@ static CK_RV get_rsa_priv_key(CK_SESSION_HANDLE session, unsigned char* privId,
{ CKA_COEFFICIENT, rsa_2048_u, sizeof(rsa_2048_u) },
{ CKA_PUBLIC_EXPONENT, rsa_2048_pub_exp, sizeof(rsa_2048_pub_exp) },
{ CKA_EXTRACTABLE, &extractable, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &sensitive, sizeof(CK_BBOOL) },
{ CKA_TOKEN, &ckTrue, sizeof(ckTrue) },
{ CKA_ID, privId, privIdLen },
};
Expand Down Expand Up @@ -3415,10 +3420,12 @@ static CK_OBJECT_HANDLE get_ecc_priv_key(CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE* obj)
{
CK_RV ret;
CK_BBOOL sensitive = (extractable == CK_TRUE) ? CK_FALSE : CK_TRUE;
CK_ATTRIBUTE ecc_p256_priv_key[] = {
{ CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
{ CKA_KEY_TYPE, &eccKeyType, sizeof(eccKeyType) },
{ CKA_EXTRACTABLE, &extractable, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &sensitive, sizeof(CK_BBOOL) },
{ CKA_VERIFY, &ckTrue, sizeof(ckTrue) },
{ CKA_EC_PARAMS, ecc_p256_params, sizeof(ecc_p256_params) },
{ CKA_VALUE, ecc_p256_priv, sizeof(ecc_p256_priv) },
Expand Down Expand Up @@ -4212,10 +4219,12 @@ static CK_OBJECT_HANDLE get_dh_priv_key(CK_SESSION_HANDLE session,
CK_OBJECT_HANDLE* obj)
{
CK_RV ret;
CK_BBOOL sensitive = (extractable == CK_TRUE) ? CK_FALSE : CK_TRUE;
CK_ATTRIBUTE dh_2048_priv_key[] = {
{ CKA_CLASS, &privKeyClass, sizeof(privKeyClass) },
{ CKA_KEY_TYPE, &dhKeyType, sizeof(dhKeyType) },
{ CKA_EXTRACTABLE, &extractable, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &sensitive, sizeof(CK_BBOOL) },
{ CKA_DERIVE, &ckTrue, sizeof(ckTrue) },
{ CKA_PRIME, dh_ffdhe2048_p, sizeof(dh_ffdhe2048_p) },
{ CKA_BASE, dh_ffdhe2048_g, sizeof(dh_ffdhe2048_g) },
Expand Down
Loading
Loading