From 643dd336578f29387a23446ea9294555b0ac5ac8 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 6 Nov 2023 17:22:00 -0800 Subject: [PATCH] wolfPKCS11 support for using TPM 2.0 module as backend. Uses wolfTPM and supports RSA and ECC. --- .github/workflows/unit-test.yml | 5 + README.md | 15 +- configure.ac | 14 ++ src/internal.c | 366 ++++++++++++++++++++++++-------- tests/pkcs11mtt.c | 22 +- tests/pkcs11test.c | 31 ++- 6 files changed, 345 insertions(+), 108 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 8bf687e..dc9ab55 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -11,6 +11,11 @@ jobs: defaults_all: uses: ./.github/workflows/build-workflow.yml + single_theaded: + uses: ./.github/workflows/build-workflow.yml + with: + config: --enable-singlethreaded + no_rsa: uses: ./.github/workflows/build-workflow.yml with: diff --git a/README.md b/README.md index 70dc10a..56f48c9 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Build wolfSSL: git clone https://github.com/wolfSSL/wolfssl.git cd wolfssl ./autogen.sh -./configure --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT" +./configure -enable-aescfb --enable-cryptocb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT" make make check sudo make install @@ -35,6 +35,18 @@ make check ### Build options and defines +#### TPM support with wolfTPM + +Enables using a TPM for cryptography and keystore. +Tested using `./configure --enable-singlethreaded --enable-wolftpm --disable-dh CFLAGS="-DWOLFPKCS11_TPM_STORE" && make`. + +Note: The TPM does not support DH, so only RSA and ECC are supported. + +##### Define WOLFPKCS11_TPM_STORE + +Use `WOLFPKCS11_TPM_STORE` storing objects in TPM NV. + + #### Define WOLFPKCS11_NO_STORE Disables storage of tokens. @@ -48,6 +60,7 @@ See wolfpkcs11/store.h for prototypes of functions to implement. Sets the private key's label against the public key when generating key pairs. + ## Environment variables ### WOLFPKCS11_TOKEN_PATH diff --git a/configure.ac b/configure.ac index db5fc06..873cc76 100644 --- a/configure.ac +++ b/configure.ac @@ -324,6 +324,20 @@ if test "$enable_shared" = "no"; then AM_CFLAGS="$AM_CFLAGS -DHAVE_PKCS11_STATIC" fi + +AC_ARG_ENABLE([wolftpm], + [AS_HELP_STRING([--enable-wolftpm],[Enable wolfTPM keystore support (default: disabled)])], + [ ENABLED_TPM=$enableval ], + [ ENABLED_TPM=no ] + ) +if test "$ENABLED_TPM" = "yes" +then + LIBS="$LIBS -lwolftpm" + AM_CFLAGS="$AM_CFLAGS -DWOLFPKCS11_TPM" +fi + + + AM_CONDITIONAL([BUILD_STATIC],[test "x$enable_shared" = "xno"]) diff --git a/src/internal.c b/src/internal.c index bd64d5b..071773e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -48,6 +48,17 @@ "--enable-scrypt C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT"` #endif +#ifdef WOLFPKCS11_TPM + #include + + #ifndef WOLFPKCS11_TPM_CUST_IO + #include + #ifndef TPM2_IOCB_CTX + #define TPM2_IOCB_CTX NULL + #endif + #endif +#endif + /* Size of hash calculated from PIN. */ #define PIN_HASH_SZ 32 /* Size of seed used when calculating hash from PIN. */ @@ -104,10 +115,10 @@ typedef int WP11_Lock; #define WP11_Lock_Init(l) 0 #define WP11_Lock_Free(l) -#define WP11_Lock_LockRW(l) 0 -#define WP11_Lock_UnlockRW(l) 0 -#define WP11_Lock_LockRO(l) 0 -#define WP11_Lock_UnlockRO(l) 0 +#define WP11_Lock_LockRW(l) +#define WP11_Lock_UnlockRW(l) +#define WP11_Lock_LockRO(l) +#define WP11_Lock_UnlockRO(l) #else typedef struct WP11_Lock { @@ -145,6 +156,9 @@ struct WP11_Object { #endif WP11_Data symmKey; /* Symmetric key object */ } data; +#ifdef WOLFPKCS11_TPM + WOLFTPM2_KEYBLOB tpmKey; +#endif CK_KEY_TYPE type; /* Key type of this object */ word32 size; /* Size of the key in bits or bytes */ #ifndef WOLFPKCS11_NO_STORE @@ -272,6 +286,7 @@ struct WP11_Session { #endif } params; + int devId; WP11_Session* next; /* Next session for slot */ }; @@ -307,6 +322,14 @@ struct WP11_Slot { WP11_Token token; /* Token information for slot */ WP11_Session* session; /* Linked list of sessions */ WP11_Lock lock; /* Lock for access to slot info */ + + int devId; +#ifdef WOLFPKCS11_TPM + WOLFTPM2_DEV tpmDev; + WOLFTPM2_KEY tpmSrk; + WOLFTPM2_SESSION tpmSession; + TpmCryptoDevCtx tpmCtx; +#endif }; @@ -464,6 +487,7 @@ static int Rng_New(WC_RNG* baseRng, WP11_Lock* lock, WC_RNG* rng) WP11_Lock_LockRW(lock); ret = wc_RNG_GenerateBlock(baseRng, seed, sizeof(seed)); WP11_Lock_UnlockRW(lock); + (void)lock; if (ret == 0) ret = wc_InitRngNonce_ex(rng, seed, sizeof(seed), NULL, INVALID_DEVID); @@ -501,6 +525,7 @@ static int wp11_Session_New(WP11_Slot* slot, CK_OBJECT_HANDLE handle, sess->slotId = slot->id; sess->slot = slot; sess->handle = handle; + sess->devId = slot->devId; *session = sess; } @@ -1375,6 +1400,7 @@ static int wp11_Object_Decode_RsaKey(WP11_Object* object) ret = wc_RsaPrivateKeyDecode(der, &idx, &object->data.rsaKey, len); XMEMSET(der, 0, len); } + if (der != NULL) XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); } @@ -1662,13 +1688,14 @@ static int wp11_Object_Decode_EccKey(WP11_Object* object) sizeof(object->iv)); } if (ret == 0) { - ret = wc_ecc_init(&object->data.ecKey); + ret = wc_ecc_init_ex(&object->data.ecKey, NULL, object->slot->devId); } if (ret == 0) { /* Decode ECC private key. */ ret = wc_EccPrivateKeyDecode(der, &idx, &object->data.ecKey, len); XMEMSET(der, 0, len); } + if (der != NULL) XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); } @@ -2967,6 +2994,68 @@ static void wp11_Slot_FreeSession(WP11_Slot* slot, WP11_Session* session) } } + +#ifdef WOLFPKCS11_TPM +static int wp11_TpmInit(WP11_Slot* slot) +{ + int ret; + WOLFTPM2_CAPS caps; + TPM_ALG_ID alg; + + ret = wolfTPM2_Init(&slot->tpmDev, TPM2_IoCb, TPM2_IOCB_CTX); + if (ret == 0) { + /* Get device capabilities + options */ + ret = wolfTPM2_GetCapabilities(&slot->tpmDev, &caps); + } + if (ret == 0) { + printf("Mfg %s (%d), Vendor %s, Fw %u.%u (0x%x), " + "FIPS 140-2 %d, CC-EAL4 %d\n", + caps.mfgStr, caps.mfg, caps.vendorStr, caps.fwVerMajor, + caps.fwVerMinor, caps.fwVerVendor, caps.fips140_2, caps.cc_eal4); + } + if (ret == 0) { + ret = wolfTPM2_SetCryptoDevCb(&slot->tpmDev, wolfTPM2_CryptoDevCb, + &slot->tpmCtx, &slot->devId); + } + if (ret == 0) { + /* Create a primary storage key - no auth needed for param enc to work */ + /* Prefer ECC as its faster */ + #ifdef HAVE_ECC + alg = TPM_ALG_ECC; + #elif !defined(NO_RSA) + alg = TPM_ALG_RSA; + #else + alg = TPM_ALG_NULL; + #endif + ret = wolfTPM2_CreateSRK(&slot->tpmDev, &slot->tpmSrk, alg, NULL, 0); + if (ret == 0) { + /* set values needed for crypto callback */ + slot->tpmCtx.dev = &slot->tpmDev; + slot->tpmCtx.storageKey = &slot->tpmSrk; + + /* Setup a TPM session that can be used for parameter encryption */ + ret = wolfTPM2_StartSession(&slot->tpmDev, &slot->tpmSession, + &slot->tpmSrk, NULL, TPM_SE_HMAC, TPM_ALG_CFB); + } + if (ret != 0) { + printf("TPM Create SRK or Session error %d (%s)!\n", + ret, wolfTPM2_GetRCString(ret)); + } + } + + if (ret != 0) { + printf("TPM Init failed! %d (%s)\n", ret, wolfTPM2_GetRCString(ret)); + } + return ret; +} + +static void wp11_TpmFinal(WP11_Slot* slot) +{ + wolfTPM2_Cleanup(&slot->tpmDev); +} +#endif /* WOLFPKCS11_TPM */ + + /** * Free dynamic memory associated with the slot. * @@ -2977,6 +3066,9 @@ static void wp11_Slot_Final(WP11_Slot* slot) while (slot->session != NULL) wp11_Slot_FreeSession(slot, slot->session); wp11_Token_Final(&slot->token); +#ifdef WOLFPKCS11_TPM + wp11_TpmFinal(slot); +#endif WP11_Lock_Free(&slot->lock); } @@ -3001,6 +3093,11 @@ static int wp11_Slot_Init(WP11_Slot* slot, int id) ret = WP11_Lock_Init(&slot->lock); if (ret == 0) { + #ifdef WOLFPKCS11_TPM + if (ret == 0) { + ret = wp11_TpmInit(slot); + } + #endif /* Create the minimum number of unused sessions. */ for (i = 0; ret == 0 && i < WP11_SESSION_CNT_MIN; i++) ret = wp11_Slot_AddSession(slot, &curr); @@ -4176,13 +4273,15 @@ int WP11_Session_SetCbcParams(WP11_Session* session, unsigned char* iv, /* AES object on session. */ ret = wc_AesInit(&cbc->aes, NULL, INVALID_DEVID); if (ret == 0) { - if (object->onToken) + if (object->onToken) { WP11_Lock_LockRO(object->lock); + } key = &object->data.symmKey; ret = wc_AesSetKey(&cbc->aes, key->data, key->len, iv, enc ? AES_ENCRYPTION : AES_DECRYPTION); - if (object->onToken) + if (object->onToken) { WP11_Lock_UnlockRO(object->lock); + } } return ret; @@ -4433,15 +4532,17 @@ static WP11_Object* wp11_Session_FindNext(WP11_Session* session, int onToken, #endif if ((ret->opFlag | WP11_FLAG_PRIVATE) == WP11_FLAG_PRIVATE) { - if (!onToken) + if (!onToken) { WP11_Lock_LockRO(&session->slot->token.lock); + } if (session->slot->token.loginState == WP11_APP_STATE_RW_PUBLIC || session->slot->token.loginState == WP11_APP_STATE_RO_PUBLIC) { object = ret; ret = NULL; } - if (!onToken) + if (!onToken) { WP11_Lock_UnlockRO(&session->slot->token.lock); + } } } @@ -4485,8 +4586,9 @@ void WP11_Session_Find(WP11_Session* session, int onToken, int i; CK_ATTRIBUTE* attr; - if (onToken) + if (onToken) { WP11_Lock_LockRO(&session->slot->token.lock); + } while ((obj = wp11_Session_FindNext(session, onToken, obj)) != NULL) { for (i = 0; i < (int)ulCount; i++) { attr = &pTemplate[i]; @@ -4501,8 +4603,9 @@ void WP11_Session_Find(WP11_Session* session, int onToken, break; } } - if (onToken) + if (onToken) { WP11_Lock_UnlockRO(&session->slot->token.lock); + } } /** @@ -4544,6 +4647,10 @@ void WP11_Session_FindFinal(WP11_Session* session) */ void WP11_Object_Free(WP11_Object* object) { +#ifdef WOLFPKCS11_TPM + wolfTPM2_UnloadHandle(&object->slot->tpmDev, &object->tpmKey.handle); +#endif + /* Release dynamic memory. */ if (object->label != NULL) XFREE(object->label, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -4646,11 +4753,12 @@ int WP11_Object_SetRsaKey(WP11_Object* object, unsigned char** data, int ret; RsaKey* key; - if (object->onToken) + if (object->onToken) { WP11_Lock_LockRW(object->lock); + } key = &object->data.rsaKey; - ret = wc_InitRsaKey_ex(key, NULL, INVALID_DEVID); + ret = wc_InitRsaKey_ex(key, NULL, object->slot->devId); if (ret == 0) { ret = SetMPI(&key->n, data[0], (int)len[0]); if (ret == 0) @@ -4681,13 +4789,23 @@ int WP11_Object_SetRsaKey(WP11_Object* object, unsigned char** data, key->type = RSA_PRIVATE; } } + #ifdef WOLFPKCS11_TPM + if (ret == 0 && key->type == RSA_PRIVATE) { + /* load private key - populates handle */ + object->slot->tpmCtx.rsaKey = (WOLFTPM2_KEY*)&object->tpmKey; + ret = wolfTPM2_RsaKey_WolfToTpm_ex(&object->slot->tpmDev, + &object->slot->tpmSrk, &object->data.rsaKey, + (WOLFTPM2_KEY*)&object->tpmKey); + } + #endif if (ret != 0) wc_FreeRsaKey(key); } - if (object->onToken) + if (object->onToken) { WP11_Lock_UnlockRW(object->lock); + } return ret; } @@ -4723,8 +4841,8 @@ static int ecc_get_curve_id_from_oid(const byte* oid, word32 len) return ecc_sets[curve_idx].id; } - #endif + /** * Set the EC Parameters based on the DER encoding of the OID. * @@ -4824,11 +4942,12 @@ int WP11_Object_SetEcKey(WP11_Object* object, unsigned char** data, int ret; ecc_key* key; - if (object->onToken) + if (object->onToken) { WP11_Lock_LockRW(object->lock); + } key = &object->data.ecKey; - ret = wc_ecc_init_ex(key, NULL, INVALID_DEVID); + ret = wc_ecc_init_ex(key, NULL, object->slot->devId); if (ret == 0) { if (ret == 0 && data[0] != NULL) ret = EcSetParams(key, data[0], (int)len[0]); @@ -4843,13 +4962,23 @@ int WP11_Object_SetEcKey(WP11_Object* object, unsigned char** data, key->type = ECC_PUBLICKEY; ret = EcSetPoint(key, data[2], (int)len[2]); } + #ifdef WOLFPKCS11_TPM + if (ret == 0 && key->type != ECC_PUBLICKEY) { + /* load private key */ + object->slot->tpmCtx.eccKey = (WOLFTPM2_KEY*)&object->tpmKey; + ret = wolfTPM2_EccKey_WolfToTpm_ex(&object->slot->tpmDev, + &object->slot->tpmSrk, &object->data.ecKey, + (WOLFTPM2_KEY*)&object->tpmKey); + } + #endif if (ret != 0) wc_ecc_free(key); } - if (object->onToken) + if (object->onToken) { WP11_Lock_UnlockRW(object->lock); + } return ret; } @@ -4873,8 +5002,9 @@ int WP11_Object_SetDhKey(WP11_Object* object, unsigned char** data, int ret; WP11_DhKey* key; - if (object->onToken) + if (object->onToken) { WP11_Lock_LockRW(object->lock); + } key = &object->data.dhKey; ret = wc_InitDhKey_ex(&key->params, NULL, INVALID_DEVID); @@ -4895,8 +5025,9 @@ int WP11_Object_SetDhKey(WP11_Object* object, unsigned char** data, wc_FreeDhKey(&key->params); } - if (object->onToken) + if (object->onToken) { WP11_Lock_UnlockRW(object->lock); + } return ret; } @@ -4920,8 +5051,9 @@ int WP11_Object_SetSecretKey(WP11_Object* object, unsigned char** data, int ret = 0; WP11_Data* key; - if (object->onToken) + if (object->onToken) { WP11_Lock_LockRW(object->lock); + } key = &object->data.symmKey; key->len = 0; @@ -4952,8 +5084,9 @@ int WP11_Object_SetSecretKey(WP11_Object* object, unsigned char** data, if (ret == 0 && data[1] != NULL) XMEMCPY(key->data, data[1], key->len); - if (object->onToken) + if (object->onToken) { WP11_Lock_UnlockRW(object->lock); + } return ret; } @@ -4967,11 +5100,13 @@ int WP11_Object_SetSecretKey(WP11_Object* object, unsigned char** data, */ int WP11_Object_SetClass(WP11_Object* object, CK_OBJECT_CLASS objClass) { - if (object->onToken) + if (object->onToken) { WP11_Lock_LockRW(object->lock); + } object->objClass = objClass; - if (object->onToken) + if (object->onToken) { WP11_Lock_UnlockRW(object->lock); + } return 0; } @@ -5451,8 +5586,9 @@ int WP11_Object_GetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, { int ret = 0; - if (object->onToken) + if (object->onToken) { WP11_Lock_LockRO(object->lock); + } switch (type) { case CKA_CLASS: @@ -5599,8 +5735,9 @@ int WP11_Object_GetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, break; } - if (object->onToken) + if (object->onToken) { WP11_Lock_UnlockRO(object->lock); + } return ret; } @@ -5752,8 +5889,9 @@ int WP11_Object_SetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, { int ret = 0; - if (object->onToken) + if (object->onToken) { WP11_Lock_LockRW(object->lock); + } switch (type) { case CKA_CLASS: @@ -5902,8 +6040,9 @@ int WP11_Object_SetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, byte* data, break; } - if (object->onToken) + if (object->onToken) { WP11_Lock_UnlockRW(object->lock); + } return ret; } @@ -5960,7 +6099,7 @@ int WP11_Rsa_ParsePrivKey(byte* data, word32 dataLen, WP11_Object* privKey) int ret = 0; word32 idx = 0; - ret = wc_InitRsaKey(&privKey->data.rsaKey, NULL); + ret = wc_InitRsaKey_ex(&privKey->data.rsaKey, NULL, privKey->slot->devId); if (ret == 0) { ret = wc_RsaPrivateKeyDecode(data, &idx, &privKey->data.rsaKey, dataLen); } @@ -5983,7 +6122,7 @@ int WP11_Rsa_PrivKey2PubKey(WP11_Object* privKey, WP11_Object* pubKey, int ret; word32 idx = 0; - ret = wc_InitRsaKey(&pubKey->data.rsaKey, NULL); + ret = wc_InitRsaKey_ex(&pubKey->data.rsaKey, NULL, pubKey->slot->devId); if (ret == 0) { ret = wc_RsaKeyToPublicDer(&privKey->data.rsaKey, workbuf, worksz); if (ret >= 0) { @@ -6041,8 +6180,19 @@ int WP11_Rsa_GenerateKeyPair(WP11_Object* pub, WP11_Object* priv, if (ret == 0) { ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); if (ret == 0) { - /* Generate into the private key. */ - ret = wc_MakeRsaKey(&priv->data.rsaKey, pub->size, e, &rng); + ret = wc_InitRsaKey_ex(&priv->data.rsaKey, NULL, priv->slot->devId); + if (ret == 0) { + #ifdef WOLFPKCS11_TPM + priv->slot->tpmCtx.rsaKeyGen = &priv->tpmKey; + priv->slot->tpmCtx.rsaKey = (WOLFTPM2_KEY*)&priv->tpmKey; + #endif + + /* Generate into the private key. */ + ret = wc_MakeRsaKey(&priv->data.rsaKey, pub->size, e, &rng); + if (ret != 0) { + wc_FreeRsaKey(&priv->data.rsaKey); + } + } Rng_Free(&rng); } } @@ -6093,16 +6243,18 @@ int WP11_Rsa_PublicEncrypt(unsigned char* in, word32 inLen, unsigned char* out, int ret; WC_RNG rng; - if (pub->onToken) + if (pub->onToken) { WP11_Lock_LockRO(pub->lock); + } ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); if (ret == 0) { ret = wc_RsaFunction(in, inLen, out, outLen, RSA_PUBLIC_ENCRYPT, &pub->data.rsaKey, &rng); Rng_Free(&rng); } - if (pub->onToken) + if (pub->onToken) { WP11_Lock_UnlockRO(pub->lock); + } return ret; } @@ -6127,16 +6279,18 @@ int WP11_Rsa_PrivateDecrypt(unsigned char* in, word32 inLen, unsigned char* out, int ret; WC_RNG rng; - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRO(priv->lock); + } ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); if (ret == 0) { ret = wc_RsaFunction(in, inLen, out, outLen, RSA_PRIVATE_DECRYPT, &priv->data.rsaKey, &rng); Rng_Free(&rng); } - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRO(priv->lock); + } return ret; } @@ -6161,8 +6315,9 @@ int WP11_RsaPkcs15_PublicEncrypt(unsigned char* in, word32 inLen, int ret; WC_RNG rng; - if (pub->onToken) + if (pub->onToken) { WP11_Lock_LockRO(pub->lock); + } ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); if (ret == 0) { ret = wc_RsaPublicEncrypt_ex(in, inLen, out, *outLen, &pub->data.rsaKey, @@ -6170,8 +6325,9 @@ int WP11_RsaPkcs15_PublicEncrypt(unsigned char* in, word32 inLen, WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0); Rng_Free(&rng); } - if (pub->onToken) + if (pub->onToken) { WP11_Lock_UnlockRO(pub->lock); + } if (ret >= 0) { *outLen = ret; @@ -6204,8 +6360,9 @@ int WP11_RsaPkcs15_PrivateDecrypt(unsigned char* in, word32 inLen, WC_RNG rng; #endif /* A random number generator is needed for blinding. */ - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRW(priv->lock); + } #if defined(WC_RSA_BLINDING) && (!defined(HAVE_FIPS) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); @@ -6223,8 +6380,9 @@ int WP11_RsaPkcs15_PrivateDecrypt(unsigned char* in, word32 inLen, Rng_Free(&rng); #endif } - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRW(priv->lock); + } if (ret >= 0) { *outLen = ret; @@ -6258,8 +6416,9 @@ int WP11_RsaOaep_PublicEncrypt(unsigned char* in, word32 inLen, WP11_Slot* slot = WP11_Session_GetSlot(session); WC_RNG rng; - if (pub->onToken) + if (pub->onToken) { WP11_Lock_LockRO(pub->lock); + } ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); if (ret == 0) { ret = wc_RsaPublicEncrypt_ex(in, inLen, out, *outLen, &pub->data.rsaKey, @@ -6267,8 +6426,9 @@ int WP11_RsaOaep_PublicEncrypt(unsigned char* in, word32 inLen, oaep->mgf, oaep->label, oaep->labelSz); Rng_Free(&rng); } - if (pub->onToken) + if (pub->onToken) { WP11_Lock_UnlockRO(pub->lock); + } if (ret >= 0) { *outLen = ret; @@ -6309,8 +6469,9 @@ int WP11_RsaOaep_PrivateDecrypt(unsigned char* in, word32 inLen, #endif /* A random number generator is needed for blinding. */ - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRW(priv->lock); + } #if defined(WC_RSA_BLINDING) && (!defined(HAVE_FIPS) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); @@ -6329,8 +6490,9 @@ int WP11_RsaOaep_PrivateDecrypt(unsigned char* in, word32 inLen, Rng_Free(&rng); #endif } - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRW(priv->lock); + } if (ret >= 0) { *outLen = ret; @@ -6377,8 +6539,9 @@ int WP11_Rsa_Sign(unsigned char* in, word32 inLen, unsigned char* sig, inLen = keyLen; } - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRO(priv->lock); + } ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); if (ret == 0) { ret = wc_RsaDirect(in, inLen, sig, sigLen, &priv->data.rsaKey, @@ -6386,8 +6549,9 @@ int WP11_Rsa_Sign(unsigned char* in, word32 inLen, unsigned char* sig, Rng_Free(&rng); } - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRO(priv->lock); + } if (ret > 0) *sigLen = ret; @@ -6419,13 +6583,15 @@ int WP11_Rsa_Verify(unsigned char* sig, word32 sigLen, unsigned char* in, *stat = 0; - if (pub->onToken) + if (pub->onToken) { WP11_Lock_LockRO(pub->lock); + } decSigLen = wc_RsaEncryptSize(&pub->data.rsaKey); ret = wc_RsaDirect(sig, sigLen, decSig, &decSigLen, &pub->data.rsaKey, RSA_PUBLIC_DECRYPT, NULL); - if (pub->onToken) + if (pub->onToken) { WP11_Lock_UnlockRO(pub->lock); + } if (ret > 0) ret = 0; @@ -6467,16 +6633,18 @@ int WP11_RsaPkcs15_Sign(unsigned char* encHash, word32 encHashLen, int ret; WC_RNG rng; - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRO(priv->lock); + } ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); if (ret == 0) { ret = wc_RsaSSL_Sign(encHash, encHashLen, sig, *sigLen, &priv->data.rsaKey, &rng); Rng_Free(&rng); } - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRO(priv->lock); + } if (ret > 0) *sigLen = ret; @@ -6506,12 +6674,14 @@ int WP11_RsaPkcs15_Verify(unsigned char* sig, word32 sigLen, *stat = 0; - if (pub->onToken) + if (pub->onToken) { WP11_Lock_LockRO(pub->lock); + } decSigLen = ret = wc_RsaSSL_Verify(sig, sigLen, decSig, sizeof(decSig), &pub->data.rsaKey); - if (pub->onToken) + if (pub->onToken) { WP11_Lock_UnlockRO(pub->lock); + } if (ret > 0) ret = 0; @@ -6549,8 +6719,9 @@ int WP11_RsaPKCSPSS_Sign(unsigned char* hash, word32 hashLen, WP11_Slot* slot = WP11_Session_GetSlot(session); WC_RNG rng; - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRO(priv->lock); + } ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); if (ret == 0) { ret = wc_RsaPSS_Sign_ex(hash, hashLen, sig, *sigLen, pss->hashType, @@ -6558,8 +6729,9 @@ int WP11_RsaPKCSPSS_Sign(unsigned char* hash, word32 hashLen, &rng); Rng_Free(&rng); } - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRO(priv->lock); + } if (ret > 0) *sigLen = ret; @@ -6590,13 +6762,15 @@ int WP11_RsaPKCSPSS_Verify(unsigned char* sig, word32 sigLen, *stat = 1; - if (pub->onToken) + if (pub->onToken) { WP11_Lock_LockRO(pub->lock); + } decSz = ret = wc_RsaPSS_Verify_ex(sig, sigLen, decSig, sizeof(decSig), pss->hashType, pss->mgf, pss->saltLen, &pub->data.rsaKey); - if (pub->onToken) + if (pub->onToken) { WP11_Lock_UnlockRO(pub->lock); + } if (ret >= 0) ret = 0; @@ -6635,21 +6809,32 @@ int WP11_Ec_GenerateKeyPair(WP11_Object* pub, WP11_Object* priv, int ret = 0; WC_RNG rng; - /* Copy parameters from public key into private key. */ - priv->data.ecKey.dp = pub->data.ecKey.dp; - - /* Generate into the private key. */ - ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); + ret = wc_ecc_init_ex(&priv->data.ecKey, NULL, priv->slot->devId); if (ret == 0) { - ret = wc_ecc_make_key(&rng, priv->data.ecKey.dp->size, + #ifdef WOLFPKCS11_TPM + priv->slot->tpmCtx.ecdhKey = (WOLFTPM2_KEY*)&priv->tpmKey; + #endif + + /* Copy parameters from public key into private key. */ + priv->data.ecKey.dp = pub->data.ecKey.dp; + + /* Generate into the private key. */ + ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); + if (ret == 0) { + ret = wc_ecc_make_key(&rng, priv->data.ecKey.dp->size, &priv->data.ecKey); - Rng_Free(&rng); - } - if (ret == 0) { - /* Copy the public part into public key. */ - ret = wc_ecc_copy_point(&priv->data.ecKey.pubkey, + Rng_Free(&rng); + } + if (ret == 0) { + /* Copy the public part into public key. */ + ret = wc_ecc_copy_point(&priv->data.ecKey.pubkey, &pub->data.ecKey.pubkey); + } + if (ret != 0) { + wc_ecc_free(&priv->data.ecKey); + } } + if (ret == 0) { priv->data.ecKey.type = ECC_PRIVATEKEY; pub->data.ecKey.type = ECC_PUBLICKEY; @@ -6839,28 +7024,31 @@ int WP11_Ec_Sign(unsigned char* hash, word32 hashLen, unsigned char* sig, word32 ordSz; WC_RNG rng; - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRO(priv->lock); + } ordSz = priv->data.ecKey.dp->size; - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRO(priv->lock); + } if (*sigLen < ordSz * 2) ret = BUFFER_E; if (ret == 0) { encSigLen = sizeof(encSig); - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRO(priv->lock); + } ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); if (ret == 0) { ret = wc_ecc_sign_hash(hash, hashLen, encSig, &encSigLen, &rng, &priv->data.ecKey); Rng_Free(&rng); } - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRO(priv->lock); - + } if (ret == 0) { ret = Pkcs11ECDSASig_Decode(encSig, encSigLen, sig, ordSz); } @@ -6892,8 +7080,9 @@ int WP11_Ec_Verify(unsigned char* sig, word32 sigLen, unsigned char* hash, word32 encSigLen; *stat = 0; - if (pub->onToken) + if (pub->onToken) { WP11_Lock_LockRO(pub->lock); + } if (sigLen != (word32)(2 * pub->data.ecKey.dp->size)) ret = BAD_FUNC_ARG; if (ret == 0) { @@ -6901,8 +7090,9 @@ int WP11_Ec_Verify(unsigned char* sig, word32 sigLen, unsigned char* hash, ret = wc_ecc_verify_hash(encSig, encSigLen, hash, hashLen, stat, &pub->data.ecKey); } - if (pub->onToken) + if (pub->onToken) { WP11_Lock_UnlockRO(pub->lock); + } return ret; } @@ -6929,7 +7119,7 @@ int WP11_EC_Derive(unsigned char* point, word32 pointLen, unsigned char* key, WC_RNG rng; #endif - ret = wc_ecc_init_ex(&pubKey, NULL, INVALID_DEVID); + ret = wc_ecc_init_ex(&pubKey, NULL, priv->slot->devId); if (ret == 0) { ret = wc_ecc_import_x963(point, pointLen, &pubKey); } @@ -6941,11 +7131,13 @@ int WP11_EC_Derive(unsigned char* point, word32 pointLen, unsigned char* key, } #endif if (ret == 0) { - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRO(priv->lock); + } ret = wc_ecc_shared_secret(&priv->data.ecKey, &pubKey, key, &keyLen); - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRO(priv->lock); + } #if defined(ECC_TIMING_RESISTANT) && (!defined(HAVE_FIPS) || \ (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) Rng_Free(&rng); @@ -7015,12 +7207,14 @@ int WP11_Dh_Derive(unsigned char* pub, word32 pubLen, unsigned char* key, { int ret; - if (priv->onToken) + if (priv->onToken) { WP11_Lock_LockRO(priv->lock); + } ret = wc_DhAgree(&priv->data.dhKey.params, key, keyLen, priv->data.dhKey.key, priv->data.dhKey.len, pub, pubLen); - if (priv->onToken) + if (priv->onToken) { WP11_Lock_UnlockRO(priv->lock); + } return ret; } @@ -7604,13 +7798,14 @@ int WP11_AesGcm_EncryptUpdate(unsigned char* plain, word32 plainSz, ret = wc_AesInit(&aes, NULL, INVALID_DEVID); if (ret == 0) { - if (secret->onToken) + if (secret->onToken) { WP11_Lock_LockRO(secret->lock); + } key = &secret->data.symmKey; ret = wc_AesGcmSetKey(&aes, key->data, key->len); - if (secret->onToken) + if (secret->onToken) { WP11_Lock_UnlockRO(secret->lock); - + } if (ret == 0) ret = wc_AesGcmEncrypt(&aes, enc, plain, plainSz, gcm->iv, gcm->ivSz, authTag, authTagSz, gcm->aad, @@ -7854,12 +8049,14 @@ int WP11_Hmac_Init(CK_MECHANISM_TYPE mechanism, WP11_Object* secret, if (ret == 0) ret = wc_HmacInit(&hmac->hmac, NULL, INVALID_DEVID); if (ret == 0) { - if (secret->onToken) + if (secret->onToken) { WP11_Lock_LockRO(secret->lock); + } key = &secret->data.symmKey; ret = wc_HmacSetKey(&hmac->hmac, hashType, key->data, key->len); - if (secret->onToken) + if (secret->onToken) { WP11_Lock_UnlockRO(secret->lock); + } } return ret; @@ -8036,4 +8233,3 @@ int WP11_Slot_GenerateRandom(WP11_Slot* slot, unsigned char* data, int len) return ret; } - diff --git a/tests/pkcs11mtt.c b/tests/pkcs11mtt.c index be864f9..97c31e0 100644 --- a/tests/pkcs11mtt.c +++ b/tests/pkcs11mtt.c @@ -28,9 +28,12 @@ #endif #include -#include - #include + +#include + +#ifdef _POSIX_THREADS +#include #include #define TEST_MULTITHREADED @@ -5686,7 +5689,7 @@ static CK_RV test_hmac_fail(CK_SESSION_HANDLE session, CK_MECHANISM* mech, mech->pParameter = data; ret = funcList->C_SignInit(session, mech, key); CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID, - "HMAC Sign Init bad parametere"); + "HMAC Sign Init bad parameter"); mech->pParameter = NULL; } if (ret == CKR_OK) { @@ -5707,7 +5710,7 @@ static CK_RV test_hmac_fail(CK_SESSION_HANDLE session, CK_MECHANISM* mech, mech->pParameter = data; ret = funcList->C_VerifyInit(session, mech, key); CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID, - "HMAC Verify Init bad parametere"); + "HMAC Verify Init bad parameter"); mech->pParameter = NULL; } if (ret == CKR_OK) { @@ -6596,3 +6599,14 @@ int main(int argc, char* argv[]) return ret; } +#else + +int main(int argc, char* argv[]) +{ + (void)argc; + (void)argv; + fprintf(stderr, "%s: multi-threaded example not compiled in!\n", argv[0]); + return 0; +} + +#endif /* _POSIX_THREADS */ diff --git a/tests/pkcs11test.c b/tests/pkcs11test.c index 1c22c3c..f05bfbc 100644 --- a/tests/pkcs11test.c +++ b/tests/pkcs11test.c @@ -3824,6 +3824,7 @@ static CK_RV test_rsa_fixed_keys_store_token(void* args) { CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args; CK_RV ret; + CK_SESSION_HANDLE sessionRO = CK_INVALID_HANDLE; CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; unsigned char* privId = (unsigned char *)"123rsafixedpriv"; @@ -3835,26 +3836,21 @@ static CK_RV test_rsa_fixed_keys_store_token(void* args) if (ret == CKR_OK) ret = get_rsa_pub_key(session, pubId, pubIdLen, &pub); - return ret; -} - -static CK_RV test_rsa_token_keys_raw(void* args) -{ - CK_SESSION_HANDLE session = *(CK_SESSION_HANDLE*)args; - CK_RV ret; - CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE; - unsigned char* privId = (unsigned char *)"123rsafixedpriv"; - int privIdLen = (int)strlen((char*)privId); - unsigned char* pubId = (unsigned char *)"123rsafixedpub"; - int pubIdLen = (int)strlen((char*)pubId); - - ret = find_rsa_priv_key(session, &priv, privId, privIdLen); + if (ret == CKR_OK) { + ret = funcList->C_OpenSession(slot, CKF_SERIAL_SESSION, NULL, NULL, + &sessionRO); + CHECK_CKR(ret, "Open Session read only"); + } + if (ret == CKR_OK) + ret = find_rsa_priv_key(session, &priv, privId, privIdLen); if (ret == CKR_OK) ret = find_rsa_pub_key(session, &pub, pubId, pubIdLen); if (ret == CKR_OK) ret = rsa_raw_test(session, priv, pub); + funcList->C_CloseSession(sessionRO); + funcList->C_DestroyObject(session, pub); + funcList->C_DestroyObject(session, priv); return ret; } @@ -7120,7 +7116,7 @@ static CK_RV test_hmac_fail(CK_SESSION_HANDLE session, CK_MECHANISM* mech, mech->pParameter = data; ret = funcList->C_SignInit(session, mech, key); CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID, - "HMAC Sign Init bad parametere"); + "HMAC Sign Init bad parameter"); mech->pParameter = NULL; } if (ret == CKR_OK) { @@ -7141,7 +7137,7 @@ static CK_RV test_hmac_fail(CK_SESSION_HANDLE session, CK_MECHANISM* mech, mech->pParameter = data; ret = funcList->C_VerifyInit(session, mech, key); CHECK_CKR_FAIL(ret, CKR_MECHANISM_PARAM_INVALID, - "HMAC Verify Init bad parametere"); + "HMAC Verify Init bad parameter"); mech->pParameter = NULL; } if (ret == CKR_OK) { @@ -7701,7 +7697,6 @@ static TEST_FUNC testFunc[] = { PKCS11TEST_FUNC_SESS_DECL(test_rsa_fixed_keys_pss), #endif PKCS11TEST_FUNC_SESS_DECL(test_rsa_fixed_keys_store_token), - PKCS11TEST_FUNC_SESS_DECL(test_rsa_token_keys_raw), PKCS11TEST_FUNC_SESS_DECL(test_rsa_x_509_fail), PKCS11TEST_FUNC_SESS_DECL(test_rsa_pkcs_encdec_fail), #ifndef WC_NO_RSA_OAEP