From 9510dc77217872a21e5e1252044c68e7d9333449 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 28 Nov 2023 15:46:51 -0800 Subject: [PATCH 1/5] wolfPKCS11 support for using TPM 2.0 module as backend. Uses wolfTPM and supports RSA and ECC. Requires https://github.com/wolfSSL/wolfTPM/pull/311 Added CI testing for wolfPKCS11 with wolfTPM backend and single threaded. --- .github/workflows/build-workflow.yml | 40 +++++- .github/workflows/unit-test.yml | 13 +- README.md | 15 +- configure.ac | 14 ++ src/internal.c | 200 +++++++++++++++++++++++---- tests/pkcs11mtt.c | 22 ++- tests/pkcs11test.c | 31 ++--- 7 files changed, 285 insertions(+), 50 deletions(-) diff --git a/.github/workflows/build-workflow.yml b/.github/workflows/build-workflow.yml index 077b1b0..06505e2 100644 --- a/.github/workflows/build-workflow.yml +++ b/.github/workflows/build-workflow.yml @@ -7,6 +7,10 @@ on: config: required: false type: string + check: + required: false + type: string + default: 'make check' jobs: build: @@ -30,7 +34,7 @@ jobs: - name: wolfssl configure working-directory: ./wolfssl run: | - ./configure --enable-cryptonly --enable-aescfb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt \ + ./configure --enable-cryptocb --enable-aescfb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt \ C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT" - name: wolfssl make install working-directory: ./wolfssl @@ -41,6 +45,38 @@ jobs: sudo make install sudo ldconfig +#setup ibmswtpm2 + - uses: actions/checkout@v3 + with: + repository: kgoldman/ibmswtpm2 + path: ibmswtpm2 + - name: ibmswtpm2 make + working-directory: ./ibmswtpm2/src + run: | + make + ./tpm_server & + +#setup wolftpm + - uses: actions/checkout@v3 + with: + repository: wolfssl/wolftpm + path: wolftpm + - name: wolftpm autogen + working-directory: ./wolftpm + run: ./autogen.sh + - name: wolftpm configure + working-directory: ./wolftpm + run: | + ./configure --enable-swtpm + - name: wolftpm make install + working-directory: ./wolftpm + run: make + - name: wolftpm make install + working-directory: ./wolftpm + run: | + sudo make install + sudo ldconfig + #setup wolfPKCS11 - name: wolfpkcs11 autogen run: ./autogen.sh @@ -49,7 +85,7 @@ jobs: - name: wolfpkcs11 make run: make - name: wolfpkcs11 make check - run: make check + run: ${{inputs.check}} - name: wolfpkcs11 make install run: sudo make install - name: wolfpkcs11 make dist diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 8bf687e..e42d2a5 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -2,7 +2,7 @@ name: wolfPKCS11 Build Tests on: push: - branches: [ '*' ] + branches: [ 'master', 'main', 'release/**' ] pull_request: branches: [ '*' ] @@ -11,6 +11,17 @@ jobs: defaults_all: uses: ./.github/workflows/build-workflow.yml + single_theaded: + uses: ./.github/workflows/build-workflow.yml + with: + config: --enable-singlethreaded + + tpm: + uses: ./.github/workflows/build-workflow.yml + with: + config: --enable-singlethreaded --enable-wolftpm --disable-dh CFLAGS="-DWOLFPKCS11_TPM_STORE" + check: ./tests/pkcs11test + no_rsa: uses: ./.github/workflows/build-workflow.yml with: diff --git a/README.md b/README.md index 70dc10a..c30bb2b 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..0cef815 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. */ @@ -102,12 +113,12 @@ /* Disable locking. */ typedef int WP11_Lock; -#define WP11_Lock_Init(l) 0 +#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) ({ 0; }) +#define WP11_Lock_UnlockRW(l) ({ 0; }) +#define WP11_Lock_LockRO(l) ({ 0; }) +#define WP11_Lock_UnlockRO(l) ({ 0; }) #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; } @@ -1662,7 +1687,7 @@ 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. */ @@ -2967,6 +2992,73 @@ 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) +{ +#ifdef WOLFPKCS11_TPM + wolfTPM2_UnloadHandle(&slot->tpmDev, &slot->tpmSession.handle); + wolfTPM2_UnloadHandle(&slot->tpmDev, &slot->tpmSrk.handle); +#endif + + wolfTPM2_Cleanup(&slot->tpmDev); +} +#endif /* WOLFPKCS11_TPM */ + + /** * Free dynamic memory associated with the slot. * @@ -2974,9 +3066,13 @@ static void wp11_Slot_FreeSession(WP11_Slot* slot, WP11_Session* session) */ static void wp11_Slot_Final(WP11_Slot* slot) { + if (slot == NULL) return; 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 +3097,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); @@ -4544,6 +4645,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); @@ -4650,7 +4755,7 @@ int WP11_Object_SetRsaKey(WP11_Object* object, unsigned char** data, 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,6 +4786,15 @@ 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); @@ -4828,7 +4942,7 @@ int WP11_Object_SetEcKey(WP11_Object* object, unsigned char** data, 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,6 +4957,16 @@ 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_PRIVATEKEY_ONLY || key->type == ECC_PRIVATEKEY)) { + /* 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); @@ -5960,7 +6084,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 +6107,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 +6165,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); } } @@ -6635,21 +6770,38 @@ 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, - &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, + #ifdef WOLFPKCS11_TPM + CK_BBOOL isSign = CK_FALSE; + CK_ULONG len = sizeof(isSign); + ret = WP11_Object_GetAttr(priv, CKA_SIGN, &isSign, &len); + if (isSign) + priv->slot->tpmCtx.eccKey = (WOLFTPM2_KEY*)&priv->tpmKey; + else + 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_ex(&rng, priv->data.ecKey.dp->size, + &priv->data.ecKey, priv->data.ecKey.dp->id); + 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; 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 From 424decba63c1a224aef988aa3cd9b64c171d87f8 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 29 Nov 2023 15:59:14 -0800 Subject: [PATCH 2/5] Added PKCS11 TPM NV store (enabled with `WOLFPKCS11_TPM_STORE`). --- .github/workflows/unit-test.yml | 2 +- README.md | 13 +- src/internal.c | 265 ++++++++++++++++++++++++++------ wolfpkcs11/store.h | 14 +- 4 files changed, 231 insertions(+), 63 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index e42d2a5..afd52e0 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -20,7 +20,7 @@ jobs: uses: ./.github/workflows/build-workflow.yml with: config: --enable-singlethreaded --enable-wolftpm --disable-dh CFLAGS="-DWOLFPKCS11_TPM_STORE" - check: ./tests/pkcs11test + check: ./tests/pkcs11str && ./tests/pkcs11test no_rsa: uses: ./.github/workflows/build-workflow.yml diff --git a/README.md b/README.md index c30bb2b..a94f4ca 100644 --- a/README.md +++ b/README.md @@ -33,24 +33,29 @@ make make check ``` -### Build options and defines -#### TPM support with wolfTPM +### 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. +### Build options and defines +#### Define WOLFPKCS11_TPM_STORE + +Use `WOLFPKCS11_TPM_STORE` storing objects in TPM NV. #### Define WOLFPKCS11_NO_STORE Disables storage of tokens. +#### Define WOLFPKCS11_DEBUG_STORE + +Enables debugging printf's for store. + #### Define WOLFPKCS11_CUSTOM_STORE Removes default implementation of storage functions. diff --git a/src/internal.c b/src/internal.c index 0cef815..36206e9 100644 --- a/src/internal.c +++ b/src/internal.c @@ -42,12 +42,6 @@ #include #include -#ifndef HAVE_SCRYPT - #error PKCS11 requires scrypt. Please build wolfssl with " \ - "`./configure --enable-rsapss --enable-keygen --enable-pwdbased " \ - "--enable-scrypt C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT"` -#endif - #ifdef WOLFPKCS11_TPM #include @@ -613,6 +607,71 @@ static void wp11_Session_Final(WP11_Session* session) #ifndef WOLFPKCS11_NO_STORE #ifndef WOLFPKCS11_CUSTOM_STORE + +#ifdef WOLFPKCS11_TPM_STORE + +/* determine which hierarchy to store in platform or owner */ +#ifndef WOLFPKCS11_TPM_AUTH_TYPE + #define WOLFPKCS11_TPM_AUTH_TYPE 1 /* 1=TPM_RH_OWNER, 2=TPM_RH_PLATFORM */ +#endif + +#ifndef WOLFPKCS11_TPM_NV_BASE + #if WOLFPKCS11_TPM_AUTH_TYPE == 1 + /* Owner Range: 0x1800000 -> 0x1c00000 */ + #undef WOLFPKCS11_TPM_AUTH_TYPE + #define WOLFPKCS11_TPM_AUTH_TYPE TPM_RH_OWNER + #define WOLFPKCS11_TPM_NV_BASE TPM_20_OWNER_NV_SPACE + #else + /* Platform Range: 0x1400000 -> 0x1800000 */ + #undef WOLFPKCS11_TPM_AUTH_TYPE + #define WOLFPKCS11_TPM_AUTH_TYPE TPM_RH_PLATFORM + #define WOLFPKCS11_TPM_NV_BASE TPM_20_PLATFORM_MFG_NV_SPACE + #endif +#endif + +typedef struct WP11_TpmStore { + WOLFTPM2_DEV* dev; + WOLFTPM2_NV nv; + word32 offset; +} WP11_TpmStore; +static WP11_TpmStore tpmStores[1]; /* maximum of 1 open store */ + +/* Internal function to get maximum size for each store type */ +static int wolfPKCS11_Store_GetMaxSize(int type) +{ + int maxSz = 0; + switch (type) { + case WOLFPKCS11_STORE_TOKEN: + maxSz = 240; + break; + case WOLFPKCS11_STORE_OBJECT: + maxSz = 86; + break; + case WOLFPKCS11_STORE_SYMMKEY: + maxSz = 4 + 32; + break; + case WOLFPKCS11_STORE_RSAKEY_PRIV: + maxSz = 4 + 1208; + break; + case WOLFPKCS11_STORE_RSAKEY_PUB: + maxSz = 4 + 294; + break; + case WOLFPKCS11_STORE_ECCKEY_PRIV: + maxSz = 4 + 67; + break; + case WOLFPKCS11_STORE_ECCKEY_PUB: + maxSz = 4 + 91; + break; + case WOLFPKCS11_STORE_DHKEY_PRIV: + case WOLFPKCS11_STORE_DHKEY_PUB: + default: + maxSz = -1; + break; + } + return maxSz; +} +#endif /* WOLFPKCS11_TPM_STORE */ + /* Functions that handle storing data. */ /** @@ -631,10 +690,67 @@ int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read, void** store) { int ret = 0; +#ifdef WOLFPKCS11_TPM_STORE + WP11_Slot* slot = &slotList[0]; + WP11_TpmStore* tpmStore = &tpmStores[0]; + word32 nvIndex; + word32 nvAttributes; + int maxSz; + WOLFTPM2_HANDLE parent; +#else char name[120] = "\0"; XFILE file; const char* str; +#endif + +#ifdef WOLFPKCS11_DEBUG_STORE + printf("Store open: Type %d, id1 %ld, id2 %ld, read %d\n", + type, id1, id2, read); +#endif + +#ifdef WOLFPKCS11_TPM_STORE + XMEMSET(&parent, 0, sizeof(parent)); + XMEMSET(tpmStore, 0, sizeof(*tpmStore)); + tpmStore->dev = &slot->tpmDev; + + /* Build unique handle */ + nvIndex = WOLFPKCS11_TPM_NV_BASE + + ((type & 0x0F) << 16) + + (((word32)id1 & 0xFF) << 8) + + ((word32)id2 & 0xFF); + + maxSz = wolfPKCS11_Store_GetMaxSize(type); + if (maxSz <= 0) { + ret = NOT_AVAILABLE_E; + } + if (ret == 0) { + /* Get NV attributes */ + parent.hndl = WOLFPKCS11_TPM_AUTH_TYPE; + (void)wolfTPM2_GetNvAttributesTemplate(parent.hndl, &nvAttributes); + + /* Try and open handle */ + ret = wolfTPM2_NVOpen(tpmStore->dev, &tpmStore->nv, nvIndex, NULL, 0); + if (ret != 0) { + if (!read) { + ret = wolfTPM2_NVCreateAuth(tpmStore->dev, &parent, + &tpmStore->nv, nvIndex, nvAttributes, maxSz, NULL, 0); + } + else { + ret = NOT_AVAILABLE_E; /* read for handle that doesn't exist */ + } + } + } + if (ret == 0) { + /* place handle into pointer */ + *store = tpmStore; + } + #ifdef WOLFPKCS11_DEBUG_STORE + printf("Store Open %p: ret %d, max size %d, handle 0x%x\n", + *store, ret, maxSz, nvIndex); + #endif +#else + #ifdef XGETENV str = XGETENV("WOLFPKCS11_NO_STORE"); if (str != NULL) { return NOT_AVAILABLE_E; @@ -643,6 +759,8 @@ int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read, if (str == NULL) { str = "/tmp"; } + #endif + /* 47 is maximum number of character to a filename and path separator. */ else if (XSTRLEN(str) > sizeof(name) - 47) { return -1; @@ -710,7 +828,10 @@ int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read, /* Return the file pointer. */ *store = file; } - + #ifdef WOLFPKCS11_DEBUG_STORE + printf("Store Open %p: ret %d, name %s, ret %d\n", *store, ret, name); + #endif +#endif return ret; } @@ -722,11 +843,25 @@ int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read, */ void wolfPKCS11_Store_Close(void* store) { +#ifdef WOLFPKCS11_TPM_STORE + WP11_TpmStore* tpmStore = (WP11_TpmStore*)store; +#else XFILE file = (XFILE)store; +#endif + +#ifdef WOLFPKCS11_DEBUG_STORE + printf("Store close: %p\n", store); +#endif + +#ifdef WOLFPKCS11_TPM_STORE + /* nothing to do for TPM */ + (void)tpmStore; +#else /* Close a valid file pointer. */ - if (store != XBADFILE) { + if (file != XBADFILE) { XFCLOSE(file); } +#endif } /** @@ -740,17 +875,32 @@ void wolfPKCS11_Store_Close(void* store) */ int wolfPKCS11_Store_Read(void* store, unsigned char* buffer, int len) { - int ret; + int ret = BUFFER_E; +#ifdef WOLFPKCS11_TPM_STORE + WP11_TpmStore* tpmStore = (WP11_TpmStore*)store; + word32 readSize; +#else XFILE file = (XFILE)store; +#endif +#ifdef WOLFPKCS11_DEBUG_STORE + printf("Store %p read: buffer %p, len %d\n", store, buffer, len); +#endif +#ifdef WOLFPKCS11_TPM_STORE + readSize = len; + wolfTPM2_SetAuthHandle(tpmStore->dev, 0, &tpmStore->nv.handle); + ret = wolfTPM2_NVReadAuth(tpmStore->dev, &tpmStore->nv, + tpmStore->nv.handle.hndl, buffer, &readSize, tpmStore->offset); + if (ret == 0) { + tpmStore->offset += readSize; + ret = readSize; + } +#else /* Read from a valid file pointer. */ - if (store != XBADFILE) { + if (file != XBADFILE) { ret = (int)XFREAD(buffer, 1, len, file); } - else { - ret = BUFFER_E; - } - +#endif return ret; } @@ -765,9 +915,25 @@ int wolfPKCS11_Store_Read(void* store, unsigned char* buffer, int len) */ int wolfPKCS11_Store_Write(void* store, unsigned char* buffer, int len) { - int ret; + int ret = BUFFER_E; +#ifdef WOLFPKCS11_TPM_STORE + WP11_TpmStore* tpmStore = (WP11_TpmStore*)store; +#else XFILE file = (XFILE)store; +#endif +#ifdef WOLFPKCS11_DEBUG_STORE + printf("Store %p write: buffer %p, len %d\n", store, buffer, len); +#endif + +#ifdef WOLFPKCS11_TPM_STORE + ret = wolfTPM2_NVWriteAuth(tpmStore->dev, &tpmStore->nv, + tpmStore->nv.handle.hndl, buffer, len, tpmStore->offset); + if (ret == 0) { + tpmStore->offset += len; + ret = len; + } +#else /* Write to a valid file pointer. */ if (store != XBADFILE) { ret = (int)XFWRITE(buffer, 1, len, file); @@ -776,9 +942,7 @@ int wolfPKCS11_Store_Write(void* store, unsigned char* buffer, int len) (void)XFFLUSH(file); } } - else { - ret = BUFFER_E; - } +#endif return ret; } @@ -1249,7 +1413,7 @@ static int wp11_storage_write_string(void* storage, char* str, int max) { return wp11_storage_write(storage, (unsigned char *)str, max); } -#endif +#endif /* !WOLFPKCS11_NO_STORE */ /** * Create a new Object object. @@ -1655,7 +1819,7 @@ static int wp11_Object_Store_RsaKey(WP11_Object* object, int tokenId, int objId) return ret; } -#endif +#endif /* !NO_RSA */ #ifdef HAVE_ECC /** @@ -1850,7 +2014,7 @@ static int wp11_Object_Store_EccKey(WP11_Object* object, int tokenId, int objId) return ret; } -#endif +#endif /* HAVE_ECC */ #ifndef NO_DH /** @@ -2113,7 +2277,7 @@ static int wp11_DhParamsToDer(DhKey* key, byte* output, word32* outSz) } #define wc_DhParamsToDer wp11_DhParamsToDer -#endif +#endif /* !WOLFSSL_DH_EXTRA || LIBWOLFSSL_VERSION_HEX < 0x04008000 */ /** * Store an DH key to storage. @@ -2183,7 +2347,7 @@ static int wp11_Object_Store_DhKey(WP11_Object* object, int tokenId, int objId) return ret; } -#endif +#endif /* !NO_DH */ /** * Decode the symmetric key - requires decryption. @@ -2688,7 +2852,7 @@ static void wp11_Object_Unstore(WP11_Object* object, int tokenId, int objId) wp11_storage_open(storeObjType, tokenId, objId, 0, &storage); wp11_storage_close(storage); } -#endif +#endif /* !WOLFPKCS11_NO_STORE */ /** * Initialize the token. @@ -2780,7 +2944,7 @@ static int wp11_Token_Load(WP11_Slot* slot, int tokenId, WP11_Token* token) ret = wp11_storage_read_time(storage, &token->soLastFailedLogin); } if (ret == 0) { - /* Read failed login timout for Security Officer. */ + /* Read failed login timeout for Security Officer. */ ret = wp11_storage_read_time(storage, &token->soFailLoginTimeout); } if (ret == 0) { @@ -2803,7 +2967,7 @@ static int wp11_Token_Load(WP11_Slot* slot, int tokenId, WP11_Token* token) ret = wp11_storage_read_time(storage, &token->userLastFailedLogin); } if (ret == 0) { - /* Read failed login timout for User. */ + /* Read failed login timeout for User. */ ret = wp11_storage_read_time(storage, &token->userFailLoginTimeout); } if (ret == 0) { @@ -2905,7 +3069,7 @@ static int wp11_Token_Store(WP11_Token* token, int tokenId) ret = wp11_storage_write_time(storage, token->soLastFailedLogin); } if (ret == 0) { - /* Write failed login timout for Security Officer. */ + /* Write failed login timeout for Security Officer. */ ret = wp11_storage_write_time(storage, token->soFailLoginTimeout); } if (ret == 0) { @@ -2927,11 +3091,11 @@ static int wp11_Token_Store(WP11_Token* token, int tokenId) ret = wp11_storage_write_time(storage, token->userLastFailedLogin); } if (ret == 0) { - /* Write failed login timout for User. */ + /* Write failed login timeout for User. */ ret = wp11_storage_write_time(storage, token->userFailLoginTimeout); } if (ret == 0) { - /* Write seed used to calucate key. */ + /* Write seed used to calculate key. */ ret = wp11_storage_write_fixed_array(storage, token->seed, PIN_SEED_SZ); } @@ -2963,7 +3127,7 @@ static int wp11_Token_Store(WP11_Token* token, int tokenId) return ret; } -#endif +#endif /* !WOLFPKCS11_NO_STORE */ /** * Free first session in slot and any others not in use down to a minimum. @@ -3946,7 +4110,7 @@ int WP11_Slot_TokenFailedLogin(WP11_Slot* slot, int login) } /** - * Get the expirary time of failed login timeout on the slot/token for the login + * Get the expiry time of failed login timeout on the slot/token for the login * type. * * @param slot [in] Slot object. @@ -4179,7 +4343,7 @@ static int wp11_mgf(CK_MECHANISM_TYPE mgfType, int *mgf) return ret; } -#endif +#endif /* !WC_NO_RSA_OAEP || WC_RSA_PSS */ #ifndef WC_NO_RSA_OAEP /** @@ -4221,7 +4385,7 @@ int WP11_Session_SetOaepParams(WP11_Session* session, CK_MECHANISM_TYPE hashAlg, return ret; } -#endif +#endif /* WC_NO_RSA_OAEP */ #ifdef WC_RSA_PSS /** @@ -4252,8 +4416,8 @@ int WP11_Session_SetPssParams(WP11_Session* session, CK_MECHANISM_TYPE hashAlg, return ret; } -#endif -#endif +#endif /* WC_RSA_PSS */ +#endif /* !NO_RSA */ #ifndef NO_AES #ifdef HAVE_AES_CBC @@ -4288,7 +4452,7 @@ int WP11_Session_SetCbcParams(WP11_Session* session, unsigned char* iv, return ret; } -#endif +#endif /* HAVE_AES_CBC */ #ifdef HAVE_AESGCM /** @@ -4333,8 +4497,8 @@ int WP11_Session_SetGcmParams(WP11_Session* session, unsigned char* iv, return ret; } -#endif -#endif +#endif /* HAVE_AESGCM */ +#endif /* !NO_AES */ /** * Add object to the session or token. @@ -4977,7 +5141,7 @@ int WP11_Object_SetEcKey(WP11_Object* object, unsigned char** data, return ret; } -#endif +#endif /* HAVE_ECC */ #ifndef NO_DH /** @@ -5516,7 +5680,7 @@ static int DhObject_GetAttr(WP11_Object* object, CK_ATTRIBUTE_TYPE type, return ret; } -#endif +#endif /* !NO_DH */ /** * Get a secret object's data as an attribute. @@ -6194,7 +6358,7 @@ int WP11_Rsa_GenerateKeyPair(WP11_Object* pub, WP11_Object* priv, return ret; } -#endif +#endif /* WOLFSSL_KEY_GEN */ /** * Return the length of the RSA key in bytes. @@ -6480,7 +6644,7 @@ int WP11_RsaOaep_PrivateDecrypt(unsigned char* in, word32 inLen, return ret; } -#endif +#endif /* !WC_NO_RSA_OAEP */ /** * RSA sign data with private key. @@ -6751,8 +6915,8 @@ int WP11_RsaPKCSPSS_Verify(unsigned char* sig, word32 sigLen, return ret; } -#endif -#endif +#endif /* WC_RSA_PSS */ +#endif /* !NO_RSA */ #ifdef HAVE_ECC /** @@ -7108,7 +7272,7 @@ int WP11_EC_Derive(unsigned char* point, word32 pointLen, unsigned char* key, return ret; } -#endif +#endif /* HAVE_ECC */ #ifndef NO_DH /** @@ -7176,7 +7340,7 @@ int WP11_Dh_Derive(unsigned char* pub, word32 pubLen, unsigned char* key, return ret; } -#endif +#endif /* !NO_DH */ #ifndef NO_AES /** @@ -7647,7 +7811,7 @@ int WP11_AesCbcPad_DecryptFinal(unsigned char* dec, word32* decSz, return ret; } -#endif +#endif /* HAVE_AES_CBC */ #ifdef HAVE_AESGCM /** @@ -7926,8 +8090,8 @@ int WP11_AesGcm_DecryptFinal(unsigned char* dec, word32* decSz, return ret; } -#endif -#endif +#endif /* HAVE_AESGCM */ +#endif /* !NO_AES */ #ifndef NO_HMAC /** @@ -8146,7 +8310,7 @@ int WP11_Hmac_VerifyFinal(unsigned char* sig, word32 sigLen, int* stat, return ret; } -#endif +#endif /* !NO_HMAC */ /** * Seed the random number generator of the token in the slot. @@ -8188,4 +8352,3 @@ int WP11_Slot_GenerateRandom(WP11_Slot* slot, unsigned char* data, int len) return ret; } - diff --git a/wolfpkcs11/store.h b/wolfpkcs11/store.h index 94da857..39d6b40 100644 --- a/wolfpkcs11/store.h +++ b/wolfpkcs11/store.h @@ -24,13 +24,13 @@ #define WOLFPKCS11_STORE_TOKEN 0x00 #define WOLFPKCS11_STORE_OBJECT 0x01 -#define WOLFPKCS11_STORE_SYMMKEY 0x10 -#define WOLFPKCS11_STORE_RSAKEY_PRIV 0x12 -#define WOLFPKCS11_STORE_RSAKEY_PUB 0x13 -#define WOLFPKCS11_STORE_ECCKEY_PRIV 0x14 -#define WOLFPKCS11_STORE_ECCKEY_PUB 0x15 -#define WOLFPKCS11_STORE_DHKEY_PRIV 0x16 -#define WOLFPKCS11_STORE_DHKEY_PUB 0x17 +#define WOLFPKCS11_STORE_SYMMKEY 0x02 +#define WOLFPKCS11_STORE_RSAKEY_PRIV 0x03 +#define WOLFPKCS11_STORE_RSAKEY_PUB 0x04 +#define WOLFPKCS11_STORE_ECCKEY_PRIV 0x05 +#define WOLFPKCS11_STORE_ECCKEY_PUB 0x06 +#define WOLFPKCS11_STORE_DHKEY_PRIV 0x07 +#define WOLFPKCS11_STORE_DHKEY_PUB 0x08 /* * Opens access to location to read/write token data. From 8cabca73ce8d17bef554cdd01096a4852b508aa3 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 29 Nov 2023 16:06:28 -0800 Subject: [PATCH 3/5] Allow `WOLFPKCS11_NO_STORE` for TPM use case. --- src/internal.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/internal.c b/src/internal.c index 36206e9..01f4635 100644 --- a/src/internal.c +++ b/src/internal.c @@ -690,6 +690,9 @@ int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read, void** store) { int ret = 0; +#if defined(XGETENV) || !defined(WOLFPKCS11_TPM_STORE) + const char* str = NULL; +#endif #ifdef WOLFPKCS11_TPM_STORE WP11_Slot* slot = &slotList[0]; WP11_TpmStore* tpmStore = &tpmStores[0]; @@ -700,7 +703,6 @@ int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read, #else char name[120] = "\0"; XFILE file; - const char* str; #endif #ifdef WOLFPKCS11_DEBUG_STORE @@ -708,6 +710,13 @@ int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read, type, id1, id2, read); #endif +#ifdef XGETENV + str = XGETENV("WOLFPKCS11_NO_STORE"); + if (str != NULL) { + return NOT_AVAILABLE_E; + } +#endif + #ifdef WOLFPKCS11_TPM_STORE XMEMSET(&parent, 0, sizeof(parent)); XMEMSET(tpmStore, 0, sizeof(*tpmStore)); @@ -751,18 +760,14 @@ int wolfPKCS11_Store_Open(int type, CK_ULONG id1, CK_ULONG id2, int read, #else #ifdef XGETENV - str = XGETENV("WOLFPKCS11_NO_STORE"); - if (str != NULL) { - return NOT_AVAILABLE_E; - } str = XGETENV("WOLFPKCS11_TOKEN_PATH"); + #endif if (str == NULL) { str = "/tmp"; } - #endif /* 47 is maximum number of character to a filename and path separator. */ - else if (XSTRLEN(str) > sizeof(name) - 47) { + if (str == NULL || (XSTRLEN(str) > sizeof(name) - 47)) { return -1; } From 2eecc1d2cd0616736e1670164a1943bf5ef9a4c4 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 4 Dec 2023 12:57:56 -0800 Subject: [PATCH 4/5] Fix compiler warnings from mingw. Add portability macro `WOLFPKCS11_NO_ENV` when setenv/getenv is not available. Only require `-ldl` for non-static builds. --- configure.ac | 4 +++- include.am | 15 --------------- src/internal.c | 35 +++++++++++++++++------------------ tests/include.am | 6 +++--- tests/pkcs11mtt.c | 2 ++ tests/pkcs11str.c | 2 ++ tests/pkcs11test.c | 2 ++ tests/testdata.h | 22 ++++++++++++++++++++++ 8 files changed, 51 insertions(+), 37 deletions(-) delete mode 100644 include.am diff --git a/configure.ac b/configure.ac index 873cc76..79ce22b 100644 --- a/configure.ac +++ b/configure.ac @@ -322,6 +322,8 @@ fi if test "$enable_shared" = "no"; then AM_CFLAGS="$AM_CFLAGS -DHAVE_PKCS11_STATIC" +else + LIBS="$LIBS -ldl" fi @@ -347,7 +349,7 @@ AX_HARDEN_CC_COMPILER_FLAGS OPTION_FLAGS="$CFLAGS $CPPFLAGS $AM_CFLAGS" -LIBS="$LIBS -lwolfssl -ldl -lm" +LIBS="$LIBS -lwolfssl -lm" CREATE_HEX_VERSION AC_SUBST([AM_CPPFLAGS]) diff --git a/include.am b/include.am deleted file mode 100644 index 840a12c..0000000 --- a/include.am +++ /dev/null @@ -1,15 +0,0 @@ -# vim:ft=automake -# All paths should be given relative to the root - -check_PROGRAMS += test/pkcs11test -noinst_PROGRAMS += test/pkcs11test -test_pkcs11test_SOURCES = test/pkcs11test.c - -test_pkcs11test_LDADD = -lwolfssl -ldl -lm - -check_PROGRAMS += test/pkcs11mtt -noinst_PROGRAMS += test/pkcs11mtt -test_pkcs11mtt_SOURCES = test/pkcs11mtt.c - -test_pkcs11mtt_LDADD = -lwolfssl -ldl -lm - diff --git a/src/internal.c b/src/internal.c index 01f4635..714f423 100644 --- a/src/internal.c +++ b/src/internal.c @@ -53,6 +53,11 @@ #endif #endif +#if defined(WC_RSA_BLINDING) && (!defined(HAVE_FIPS) || \ + (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +#define WOLFPKCS11_NEED_RSA_RNG +#endif + /* Size of hash calculated from PIN. */ #define PIN_HASH_SZ 32 /* Size of seed used when calculating hash from PIN. */ @@ -6503,26 +6508,23 @@ int WP11_RsaPkcs15_PrivateDecrypt(unsigned char* in, word32 inLen, WP11_Object* priv, WP11_Slot* slot) { int ret = 0; -#if defined(WC_RSA_BLINDING) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +#ifdef WOLFPKCS11_NEED_RSA_RNG WC_RNG rng; #endif /* A random number generator is needed for blinding. */ if (priv->onToken) WP11_Lock_LockRW(priv->lock); -#if defined(WC_RSA_BLINDING) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +#ifdef WOLFPKCS11_NEED_RSA_RNG ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); - if (ret == 0) { - priv->data.rsaKey.rng = &rng; - } #endif if (ret == 0) { + #ifdef WOLFPKCS11_NEED_RSA_RNG + priv->data.rsaKey.rng = &rng; + #endif ret = wc_RsaPrivateDecrypt_ex(in, inLen, out, *outLen, &priv->data.rsaKey, WC_RSA_PKCSV15_PAD, WC_HASH_TYPE_NONE, WC_MGF1NONE, NULL, 0); - #if defined(WC_RSA_BLINDING) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) + #ifdef WOLFPKCS11_NEED_RSA_RNG priv->data.rsaKey.rng = NULL; Rng_Free(&rng); #endif @@ -6607,28 +6609,25 @@ int WP11_RsaOaep_PrivateDecrypt(unsigned char* in, word32 inLen, int ret = 0; WP11_OaepParams* oaep = &session->params.oaep; WP11_Slot* slot = WP11_Session_GetSlot(session); -#if defined(WC_RSA_BLINDING) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +#ifdef WOLFPKCS11_NEED_RSA_RNG WC_RNG rng; #endif /* A random number generator is needed for blinding. */ if (priv->onToken) WP11_Lock_LockRW(priv->lock); -#if defined(WC_RSA_BLINDING) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) +#ifdef WOLFPKCS11_NEED_RSA_RNG ret = Rng_New(&slot->token.rng, &slot->token.rngLock, &rng); - if (ret == 0) { - priv->data.rsaKey.rng = &rng; - } #endif if (ret == 0) { + #ifdef WOLFPKCS11_NEED_RSA_RNG + priv->data.rsaKey.rng = &rng; + #endif ret = wc_RsaPrivateDecrypt_ex(in, inLen, out, *outLen, &priv->data.rsaKey, WC_RSA_OAEP_PAD, oaep->hashType, oaep->mgf, oaep->label, oaep->labelSz); - #if defined(WC_RSA_BLINDING) && (!defined(HAVE_FIPS) || \ - (defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION > 2))) + #ifdef WOLFPKCS11_NEED_RSA_RNG priv->data.rsaKey.rng = NULL; Rng_Free(&rng); #endif diff --git a/tests/include.am b/tests/include.am index a7b255f..9483430 100644 --- a/tests/include.am +++ b/tests/include.am @@ -4,17 +4,17 @@ check_PROGRAMS += tests/pkcs11test noinst_PROGRAMS += tests/pkcs11test tests_pkcs11test_SOURCES = tests/pkcs11test.c -tests_pkcs11test_LDADD = -lwolfssl -ldl -lm +tests_pkcs11test_LDADD = check_PROGRAMS += tests/pkcs11mtt noinst_PROGRAMS += tests/pkcs11mtt tests_pkcs11mtt_SOURCES = tests/pkcs11mtt.c -tests_pkcs11mtt_LDADD = -lwolfssl -ldl -lm +tests_pkcs11mtt_LDADD = check_PROGRAMS += tests/pkcs11str noinst_PROGRAMS += tests/pkcs11str tests_pkcs11str_SOURCES = tests/pkcs11str.c -tests_pkcs11str_LDADD = -lwolfssl -ldl -lm +tests_pkcs11str_LDADD = if BUILD_STATIC tests_pkcs11test_LDADD +=src/libwolfpkcs11.la diff --git a/tests/pkcs11mtt.c b/tests/pkcs11mtt.c index 97c31e0..c9f1b3e 100644 --- a/tests/pkcs11mtt.c +++ b/tests/pkcs11mtt.c @@ -6494,7 +6494,9 @@ int main(int argc, char* argv[]) int closeDl = 1; int i; +#ifndef WOLFPKCS11_NO_ENV setenv("WOLFPKCS11_NO_STORE", "1", 1); +#endif argc--; argv++; diff --git a/tests/pkcs11str.c b/tests/pkcs11str.c index 2b3c9a5..610c587 100644 --- a/tests/pkcs11str.c +++ b/tests/pkcs11str.c @@ -918,9 +918,11 @@ int main(int argc, char* argv[]) int setPin = 1; int closeDl = 1; +#ifndef WOLFPKCS11_NO_ENV if (!getenv("WOLFPKCS11_TOKEN_PATH")) { setenv("WOLFPKCS11_TOKEN_PATH", "./tests", 1); } +#endif argc--; argv++; diff --git a/tests/pkcs11test.c b/tests/pkcs11test.c index f05bfbc..394a781 100644 --- a/tests/pkcs11test.c +++ b/tests/pkcs11test.c @@ -7908,7 +7908,9 @@ int main(int argc, char* argv[]) int closeDl = 1; int i; +#ifndef WOLFPKCS11_NO_ENV setenv("WOLFPKCS11_NO_STORE", "1", 1); +#endif argc--; argv++; diff --git a/tests/testdata.h b/tests/testdata.h index 48e24c8..a6b1467 100644 --- a/tests/testdata.h +++ b/tests/testdata.h @@ -440,3 +440,25 @@ static unsigned char aes_128_gcm_exp_tag[] = { #endif #endif + +#ifndef WOLFPKCS11_NO_ENV +#include +#include /* setenv/getenv */ +#include + +#if defined(__MINGW32__) || defined(_MSC_VER) +/* Windows/MinGw does not support setenv, but does have putenv and getenv */ +extern int putenv(const char *); +static inline int setenv(const char *name, const char *value, int overwrite) +{ + char env[255]; + size_t len = strlen(name) + 1 + strlen(value) + 1; + if (len < sizeof(env)) { + sprintf(env, "%s=%s", name, value); + return putenv(env); + } + (void)overwrite; + return EXIT_FAILURE; +} +#endif +#endif /* !WOLFPKCS11_NO_ENV */ From a7782fc55b1a064b66db25d07ebbc6284f91585a Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 5 Dec 2023 13:32:19 -0800 Subject: [PATCH 5/5] Peer review cleanups. --- src/internal.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/internal.c b/src/internal.c index 714f423..4e0fa11 100644 --- a/src/internal.c +++ b/src/internal.c @@ -670,7 +670,7 @@ static int wolfPKCS11_Store_GetMaxSize(int type) case WOLFPKCS11_STORE_DHKEY_PRIV: case WOLFPKCS11_STORE_DHKEY_PUB: default: - maxSz = -1; + maxSz = BAD_FUNC_ARG; break; } return maxSz; @@ -3240,9 +3240,12 @@ static void wp11_TpmFinal(WP11_Slot* slot) */ static void wp11_Slot_Final(WP11_Slot* slot) { - if (slot == NULL) return; - while (slot->session != NULL) + if (slot == NULL) { + return; + } + while (slot->session != NULL) { wp11_Slot_FreeSession(slot, slot->session); + } wp11_Token_Final(&slot->token); #ifdef WOLFPKCS11_TPM wp11_TpmFinal(slot); @@ -3272,21 +3275,20 @@ 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); - } + ret = wp11_TpmInit(slot); #endif /* Create the minimum number of unused sessions. */ - for (i = 0; ret == 0 && i < WP11_SESSION_CNT_MIN; i++) + for (i = 0; ret == 0 && i < WP11_SESSION_CNT_MIN; i++) { ret = wp11_Slot_AddSession(slot, &curr); - + } if (ret == 0) { ret = wp11_Token_Init(&slot->token, label); slot->token.state = WP11_TOKEN_STATE_UNKNOWN; } - if (ret != 0) + if (ret != 0) { wp11_Slot_Final(slot); + } } return ret;