diff --git a/.github/workflows/sanitizer-tests.yml b/.github/workflows/sanitizer-tests.yml index e85db885..3af94fe2 100644 --- a/.github/workflows/sanitizer-tests.yml +++ b/.github/workflows/sanitizer-tests.yml @@ -27,6 +27,19 @@ jobs: configure_flags: "--enable-nss --enable-tpm" - name: "PKCS#11 V3.2 PQC Build" configure_flags: "--enable-pkcs11v32 --enable-mldsa --enable-mlkem" + include: + # With HAVE_WOLF_BIGINT (--enable-pkcs11) and ML-DSA/ML-KEM dynamic + # key buffers, decoded wolfCrypt keys own heap memory, so a key that + # is re-initialised without being freed shows up as a leak. + # wolfSSL's wc_pkcs11.c narrows CK_ULONG to word32 in its ML-DSA + # code, which -Werror (on in a git checkout) turns into a build + # failure, so keep that one diagnostic a warning. + - sanitizer: asan + config: + name: "wolfSSL Bigint PQC Build" + configure_flags: "--enable-pkcs11v32 --enable-mldsa --enable-mlkem" + wolfssl_flags: "--enable-pkcs11" + wolfssl_cflags: "-DWOLFSSL_MLKEM_DYNAMIC_KEYS -DWOLFSSL_MLDSA_DYNAMIC_KEYS -Wno-error=shorten-64-to-32" steps: #pull wolfPKCS11 @@ -81,7 +94,8 @@ jobs: ;; esac ./configure --enable-cryptocb --enable-aescfb --enable-rsapss --enable-keygen --enable-pwdbased --enable-scrypt --enable-md5 --enable-debug \ - --enable-mldsa C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -DHAVE_AES_KEYWRAP" + --enable-mldsa ${{ matrix.config.wolfssl_flags }} \ + C_EXTRA_FLAGS="-DWOLFSSL_PUBLIC_MP -DWC_RSA_DIRECT -DHAVE_AES_ECB -DHAVE_AES_KEYWRAP ${{ matrix.config.wolfssl_cflags }}" - name: wolfssl make working-directory: ./wolfssl run: | diff --git a/src/internal.c b/src/internal.c index 32c00efb..ecb40eed 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5590,6 +5590,10 @@ static int wp11_Object_Decode_RsaKey(WP11_Object* object) word32 idx = 0; RsaKey* key = object->data.rsaKey; + /* A key decoded before, e.g. at an earlier login, holds allocations that + * re-initialising it would leak. */ + if (!object->encoded) + wc_FreeRsaKey(key); ret = wc_InitRsaKey_ex(key, NULL, object->devId); if (ret != 0) { return ret; @@ -5941,6 +5945,10 @@ static int wp11_Object_Decode_EccKey(WP11_Object* object) word32 idx = 0; ecc_key* key = object->data.ecKey; + /* A key decoded before, e.g. at an earlier login, holds allocations that + * re-initialising it would leak. */ + if (!object->encoded) + wc_ecc_free(key); ret = wc_ecc_init_ex(key, NULL, object->devId); if (ret != 0) { return ret; @@ -6195,6 +6203,11 @@ static int wp11_Object_Decode_MldsaKey(WP11_Object* object) { int ret = 0; + /* A key decoded before, e.g. at an earlier login, holds allocations that + * re-initialising it would leak. */ + if (!object->encoded) + wc_MlDsaKey_Free(object->data.mldsaKey); + if (object->objClass == CKO_PRIVATE_KEY) { unsigned char* der = NULL; int len = object->keyDataLen - AES_BLOCK_SIZE; @@ -6776,6 +6789,11 @@ static int wp11_Object_Decode_MlKemKey(WP11_Object* object) { int ret = 0; + /* A key decoded before, e.g. at an earlier login, holds allocations that + * re-initialising it would leak. */ + if (!object->encoded) + wc_MlKemKey_Free(object->data.mlKemKey); + if (object->objClass == CKO_PRIVATE_KEY) { unsigned char* der; int len;