Skip to content
Merged
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
17 changes: 16 additions & 1 deletion .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,27 @@ jobs:
uses: ./.github/workflows/build-workflow.yml
with:
config: CFLAGS="-DWOLFPKCS11_NO_STORE"
no_keystore_debug:
uses: ./.github/workflows/build-workflow.yml
with:
config: --enable-debug CFLAGS="-DWOLFPKCS11_NO_STORE"
no_keystore_nss:
uses: ./.github/workflows/build-workflow.yml
with:
config: --enable-nss CFLAGS="-DWOLFPKCS11_NO_STORE"
no_keystore_pqc:
uses: ./.github/workflows/build-workflow.yml
with:
config: --enable-mldsa --enable-mlkem --enable-lms --enable-xmss CFLAGS="-DWOLFPKCS11_NO_STORE"
no_env:
uses: ./.github/workflows/build-workflow.yml
with:
config: C_EXTRA_FLAGS="-DWOLFPKCS11_NO_ENV" --with-default-token-path=./store/default
check: mkdir -p store && ./tests/pkcs11test
no_aescbc:
uses: ./.github/workflows/build-workflow.yml
with:
config: --disable-aescbc
no_aesgcm:
uses: ./.github/workflows/build-workflow.yml
with:
Expand Down Expand Up @@ -194,5 +210,4 @@ jobs:
uses: ./.github/workflows/wolfssl-v5.6.6-build-workflow.yml

#TODO: --disable-aes Enable AES (default: enabled)
#TODO: --disable-aescbc Enable AES-CBC (default: enabled)
#TODO: --disable-sha256 Enable SHA-256 (default: enabled)
119 changes: 72 additions & 47 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -751,8 +751,7 @@ static wolfSSL_Mutex libraryInitLock
#endif

#if !defined(WP11_NO_LOCKING) && defined(WOLFSSL_MUTEX_INITIALIZER) && \
defined(WOLFSSL_MUTEX_INITIALIZER_CLAUSE) && \
!defined(WOLFPKCS11_TPM_STORE) && defined(WOLFPKCS11_NSS)
defined(WOLFSSL_MUTEX_INITIALIZER_CLAUSE) && defined(WP11_NSS_STORE_DIR)
/* Permanently-live leaf mutex serializing the module-global storeDir, which
* is set at C_Initialize (before globalLock exists), read in
* wolfPKCS11_Store_Name, and freed in WP11_Library_Final after globalLock is
Expand Down Expand Up @@ -1699,7 +1698,7 @@ static word32 wolfPKCS11_Store_Handle(int type, CK_ULONG id1, CK_ULONG id2)
}
#else

#ifdef WOLFPKCS11_NSS
#ifdef WP11_NSS_STORE_DIR
static char* storeDir = NULL;

int WP11_SetStoreDir(const char *dir, size_t dirSz)
Expand Down Expand Up @@ -2062,7 +2061,7 @@ static int wolfPKCS11_Store_Name(int type, CK_ULONG id1, CK_ULONG id2, char* nam
str = XGETENV("WOLFPKCS11_TOKEN_PATH");
#endif

#ifdef WOLFPKCS11_NSS
#ifdef WP11_NSS_STORE_DIR
if (str == NULL) {
#ifdef WP11_HAVE_STORE_DIR_LOCK
/* Copy storeDir into a local under storeDirLock so a concurrent
Expand Down Expand Up @@ -7174,6 +7173,8 @@ static int wp11_Object_Store_MlKemKey(WP11_Object* object, int tokenId,
}
#endif /* WOLFPKCS11_MLKEM */

#endif /* !WOLFPKCS11_NO_STORE */

#ifdef WOLFPKCS11_LMS
/* ===========================================================================
* LMS/HSS (RFC 8554): verification and public-key import.
Expand Down Expand Up @@ -7269,6 +7270,7 @@ static int wp11_HssCheckParamAttrs(LmsKey* key,
return 0;
}

#ifndef WOLFPKCS11_NO_STORE
/* Serialize the public key: keyData holds the raw RFC 8554 HSS public key. */
static int wp11_Object_Encode_HssKey(WP11_Object* object)
{
Expand Down Expand Up @@ -7348,6 +7350,8 @@ static int wp11_Object_Store_HssKey(WP11_Object* object, int tokenId, int objId)
return ret;
}

#endif /* !WOLFPKCS11_NO_STORE */

/* Import an HSS public key from a C_CreateObject template. Following the
* PKCS#11 v3.3 HSS profile the collected attributes are data[0]=CKA_HSS_LEVELS,
* data[1]=CKA_HSS_LMS_TYPE, data[2]=CKA_HSS_LMOTS_TYPE (all optional CK_ULONG)
Expand Down Expand Up @@ -7395,16 +7399,20 @@ int WP11_Object_SetHssKey(WP11_Object* object, unsigned char** data,
/* Replace the live key and drop the cached serialization so a later
* store re-encodes from the new key instead of persisting stale bytes. */
if (object->data.lmsKey != NULL) {
#ifndef WOLFPKCS11_NO_STORE
if (!object->encoded)
#endif
wc_LmsKey_Free(object->data.lmsKey);
XFREE(object->data.lmsKey, NULL, DYNAMIC_TYPE_KEY);
}
object->data.lmsKey = newKey;
object->encoded = 0;
newKey = NULL;
#ifndef WOLFPKCS11_NO_STORE
object->encoded = 0;
XFREE(object->keyData, NULL, DYNAMIC_TYPE_TMP_BUFFER);
object->keyData = NULL;
object->keyDataLen = 0;
#endif
}
if (newKey != NULL) {
wc_LmsKey_Free(newKey);
Expand Down Expand Up @@ -7725,6 +7733,7 @@ static int wp11_XmssImportPub(XmssKey* key, int is_xmssmt, int devId,
return ret;
}

#ifndef WOLFPKCS11_NO_STORE
/* Serialize the public key: keyData holds the raw RFC 8391 public key. */
static int wp11_Object_Encode_XmssKey(WP11_Object* object)
{
Expand Down Expand Up @@ -7805,6 +7814,8 @@ static int wp11_Object_Store_XmssKey(WP11_Object* object, int tokenId,
return ret;
}

#endif /* !WOLFPKCS11_NO_STORE */

/* Import an XMSS/XMSS^MT public key from a C_CreateObject template. data[1] is
* the raw RFC 8391 public key; data[0] (CKA_PARAMETER_SET, the OID as a
* CK_ULONG) is optional and, when present, is validated against the key.
Expand Down Expand Up @@ -7842,16 +7853,20 @@ int WP11_Object_SetXmssKey(WP11_Object* object, unsigned char** data,
/* Replace the live key and drop the cached serialization so a later
* store re-encodes from the new key. */
if (object->data.xmssKey != NULL) {
#ifndef WOLFPKCS11_NO_STORE
if (!object->encoded)
#endif
wc_XmssKey_Free(object->data.xmssKey);
XFREE(object->data.xmssKey, NULL, DYNAMIC_TYPE_KEY);
}
object->data.xmssKey = newKey;
object->encoded = 0;
newKey = NULL;
#ifndef WOLFPKCS11_NO_STORE
object->encoded = 0;
XFREE(object->keyData, NULL, DYNAMIC_TYPE_TMP_BUFFER);
object->keyData = NULL;
object->keyDataLen = 0;
#endif
}
if (newKey != NULL) {
wc_XmssKey_Free(newKey);
Expand Down Expand Up @@ -8018,6 +8033,8 @@ static int XmssObject_GetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type,
}
#endif /* WOLFPKCS11_XMSS */

#ifndef WOLFPKCS11_NO_STORE

/**
* Get the length of the secret in a stored symmetric key record.
*
Expand Down Expand Up @@ -10252,7 +10269,7 @@ int WP11_Library_Final(void)
if (ret == 0)
ret = storeRet;
}
#if !defined (WOLFPKCS11_CUSTOM_STORE) && defined(WOLFPKCS11_NSS)
#ifdef WP11_NSS_STORE_DIR
/* Serialize the free against a concurrent WP11_SetStoreDir /
* wolfPKCS11_Store_Name (F-5868, F-5150). Nested inside libraryInitLock
* (held here); storeDirLock is a leaf so the fixed order
Expand Down Expand Up @@ -11971,6 +11988,7 @@ void WP11_Slot_Logout(WP11_Slot* slot)
}

#ifdef DEBUG_WOLFPKCS11
#ifndef WOLFPKCS11_NO_STORE
/**
* Test hook: report whether a slot's token object-encryption key is zeroized.
* Exposed only in debug builds so a white-box test can observe the logout
Expand All @@ -11996,6 +12014,7 @@ WP11_API int WP11_Slot_TokenKeyIsZero(CK_SLOT_ID slotId)

return acc == 0 ? 1 : 0;
}
#endif

/**
* Test hook: count the token objects whose encrypted key material is held
Expand Down Expand Up @@ -14298,15 +14317,19 @@ void WP11_Object_Free(WP11_Object* object)
#endif
#ifdef WOLFPKCS11_MLKEM
if (object->type == CKK_ML_KEM && object->data.mlKemKey != NULL) {
#ifndef WOLFPKCS11_NO_STORE
if (!object->encoded)
#endif
wc_MlKemKey_Free(object->data.mlKemKey);
XFREE(object->data.mlKemKey, NULL, DYNAMIC_TYPE_KEY);
object->data.mlKemKey = NULL;
}
#endif
#ifdef WOLFPKCS11_LMS
if (object->type == CKK_HSS && object->data.lmsKey != NULL) {
#ifndef WOLFPKCS11_NO_STORE
if (!object->encoded)
#endif
wc_LmsKey_Free(object->data.lmsKey);
XFREE(object->data.lmsKey, NULL, DYNAMIC_TYPE_KEY);
object->data.lmsKey = NULL;
Expand All @@ -14315,7 +14338,9 @@ void WP11_Object_Free(WP11_Object* object)
#ifdef WOLFPKCS11_XMSS
if ((object->type == CKK_XMSS || object->type == CKK_XMSSMT) &&
object->data.xmssKey != NULL) {
#ifndef WOLFPKCS11_NO_STORE
if (!object->encoded)
#endif
wc_XmssKey_Free(object->data.xmssKey);
XFREE(object->data.xmssKey, NULL, DYNAMIC_TYPE_KEY);
object->data.xmssKey = NULL;
Expand Down Expand Up @@ -20206,46 +20231,6 @@ int WP11_MlKem_Decapsulate(WP11_Object* priv, unsigned char** sharedSecret,
}
#endif /* WOLFPKCS11_MLKEM */

#ifndef NO_AES

#ifdef HAVE_AES_CBC
/**
* Return the amount of data not yet processed.
*
* @param session [in] Session object.
* @return Unprocessed amount in bytes.
*/
int WP11_AesCbc_PartLen(WP11_Session* session)
{
WP11_CbcParams* cbc = &session->params.cbc;

return cbc->partialSz;
}


int WP11_AesCbc_DeriveKey(unsigned char* plain, word32 plainSz,
unsigned char* enc, byte* iv,
WP11_Object* key)
{
Aes aes;
int ret = 0;

if (key->type != CKK_AES && key->type != CKK_GENERIC_SECRET)
return BAD_FUNC_ARG;

XMEMSET(&aes, 0, sizeof(aes));
ret = wc_AesInit(&aes, NULL, key->devId);
if (ret == 0) {
ret = wc_AesSetKey(&aes, key->data.symmKey->data, key->data.symmKey->len,
iv, AES_ENCRYPTION);
}
if (ret == 0)
ret = wc_AesCbcEncrypt(&aes, enc, plain, plainSz);
wc_AesFree(&aes);

return ret;
}

#ifdef WOLFSSL_HAVE_PRF
/* Used for wc_PRF_TLS, less than sha256_mac not possible */
static enum wc_MACAlgorithm MechToMac(CK_MECHANISM_TYPE mech)
Expand Down Expand Up @@ -20495,6 +20480,46 @@ int WP11_Nss_Tls12_Master_Key_Derive(CK_BYTE_PTR pSessionHash,
#endif
#endif /* WOLFSSL_HAVE_PRF */

#ifndef NO_AES

#ifdef HAVE_AES_CBC
/**
* Return the amount of data not yet processed.
*
* @param session [in] Session object.
* @return Unprocessed amount in bytes.
*/
int WP11_AesCbc_PartLen(WP11_Session* session)
{
WP11_CbcParams* cbc = &session->params.cbc;

return cbc->partialSz;
}


int WP11_AesCbc_DeriveKey(unsigned char* plain, word32 plainSz,
unsigned char* enc, byte* iv,
WP11_Object* key)
{
Aes aes;
int ret = 0;

if (key->type != CKK_AES && key->type != CKK_GENERIC_SECRET)
return BAD_FUNC_ARG;

XMEMSET(&aes, 0, sizeof(aes));
ret = wc_AesInit(&aes, NULL, key->devId);
if (ret == 0) {
ret = wc_AesSetKey(&aes, key->data.symmKey->data, key->data.symmKey->len,
iv, AES_ENCRYPTION);
}
if (ret == 0)
ret = wc_AesCbcEncrypt(&aes, enc, plain, plainSz);
wc_AesFree(&aes);

return ret;
}

/**
* Encrypt plain text with AES-CBC.
* Output buffer must be large enough to hold all data.
Expand Down
11 changes: 6 additions & 5 deletions src/wolfpkcs11.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
return ret;
}

#if (defined(WOLFPKCS11_NSS) && !defined(WOLFPKCS11_NO_STORE))
#ifdef WP11_NSS_STORE_DIR
/*
* Parse a string of NSS configuration parameters. For now only the
* configdir parameter is supported.
Expand Down Expand Up @@ -437,7 +437,7 @@ static CK_RV ParseNssConfigString(char *nssArgs,

return CKR_OK;
}
#endif /* defined WOLFPKCS11_NSS && !defined WOLFPKCS11_NO_STORE */
#endif /* WP11_NSS_STORE_DIR */

#if defined (WOLFPKCS11_PKCS11_V3_0)

Expand Down Expand Up @@ -524,8 +524,9 @@ CK_RV C_GetInterface(CK_UTF8CHAR_PTR pInterfaceName, CK_VERSION_PTR pVersion,
*
* @param pInitArgs [in] Optional CK_C_INITIALIZE_ARGS. The mutex callbacks
* must be all set or all NULL and pReserved must be
* NULL. NSS builds read the configdir from
* LibraryParameters. The callbacks are not used.
* NULL. NSS builds with the file store read the
* configdir from LibraryParameters. The callbacks
* are not used.
* @return CKR_ARGUMENTS_BAD when pInitArgs is not valid.
* CKR_FUNCTION_FAILED when initializing fails.
* CKR_OK on success.
Expand All @@ -552,7 +553,7 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs)

WOLFPKCS11_MSG("Warning: C_Initialize called with arguments, but most "
"are ignored.");
#if (defined(WOLFPKCS11_NSS) && !defined(WOLFPKCS11_NO_STORE))
#ifdef WP11_NSS_STORE_DIR
if (args->LibraryParameters != NULL) {
char* configdir = NULL;
size_t configdirLen = 0;
Expand Down
7 changes: 7 additions & 0 deletions tests/pkcs11test.c
Original file line number Diff line number Diff line change
Expand Up @@ -19610,10 +19610,17 @@ static CK_RV test_private_object_access(void* args)
ret = funcList->C_FindObjects(session, &found, 1, &count);
CHECK_CKR(ret, "Find Objects - not logged in");
}
#if !defined(WOLFPKCS11_NSS) || !defined(WOLFPKCS11_NO_STORE)
if (ret == CKR_OK && count != 0) {
ret = -1;
CHECK_CKR(ret, "Private object should not be found when not logged in");
}
#else
if (ret == CKR_OK && (count != 1 || found != obj)) {
ret = -1;
CHECK_CKR(ret, "NSS should find the private object when not logged in");
}
#endif
if (ret == CKR_OK) {
ret = funcList->C_FindObjectsFinal(session);
CHECK_CKR(ret, "Find Objects Final - not logged in");
Expand Down
10 changes: 10 additions & 0 deletions wolfpkcs11/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ extern "C" {
#endif
#endif

/* The NSS configdir is a file store path. */
#if defined(WOLFPKCS11_NSS) && !defined(WOLFPKCS11_NO_STORE) && \
!defined(WOLFPKCS11_CUSTOM_STORE) && !defined(WOLFPKCS11_TPM_STORE)
#define WP11_NSS_STORE_DIR
#endif

#if !defined(WOLFSSL_PUBLIC_MP)
#error Please build wolfSSL using recommended options: \
./configure --enable-aescfb --enable-rsapss --enable-keygen \
Expand Down Expand Up @@ -442,7 +448,9 @@ WP11_LOCAL WP11_ObjectCalls* WP11_Slot_ObjectCallEnter(
WP11_LOCAL void WP11_Slot_ObjectCallLeave(WP11_ObjectCalls* calls);
WP11_LOCAL void WP11_Slot_DiscardObject(WP11_Slot* slot, WP11_Object* object);
#ifdef DEBUG_WOLFPKCS11
#ifndef WOLFPKCS11_NO_STORE
WP11_API int WP11_Slot_TokenKeyIsZero(CK_SLOT_ID slotId);
#endif
WP11_API int WP11_Slot_TokenDecodedObjectCount(CK_SLOT_ID slotId);
WP11_API void WP11_Session_SetFindHook(void (*hook)(void));
WP11_API void WP11_Object_SetFindHook(void (*hook)(void));
Expand Down Expand Up @@ -612,8 +620,10 @@ WP11_LOCAL int WP11_Object_IsModifiable(WP11_Object* object);
#ifdef WOLFPKCS11_NSS
WP11_LOCAL int WP11_Object_SetTrust(WP11_Object* object, unsigned char** data,
CK_ULONG* len);
#ifdef WP11_NSS_STORE_DIR
int WP11_SetStoreDir(const char *dir, size_t dirSz);
#endif
#endif

WP11_LOCAL int WP11_Object_Find(WP11_Session* session, CK_OBJECT_HANDLE objHandle,
WP11_Object** object);
Expand Down
Loading