diff --git a/src/wp_dec_pem2der.c b/src/wp_dec_pem2der.c index 55a84846..0635db05 100644 --- a/src/wp_dec_pem2der.c +++ b/src/wp_dec_pem2der.c @@ -439,8 +439,8 @@ static int wp_pem2der_decode(wp_Pem2Der* ctx, OSSL_CORE_BIO* coreBio, dataCbArg, pwCb, pwCbArg); } } - /* Dispose of the PEM data buffer. */ - OPENSSL_free(data); + /* Dispose of the PEM data buffer (may contain private key material). */ + OPENSSL_clear_free(data, len); WOLFPROV_LEAVE(WP_LOG_COMP_PK, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; diff --git a/src/wp_ecx_kmgmt.c b/src/wp_ecx_kmgmt.c index 2a80b977..d3a60b44 100644 --- a/src/wp_ecx_kmgmt.c +++ b/src/wp_ecx_kmgmt.c @@ -339,6 +339,8 @@ void wp_ecx_free(wp_Ecx* ecx) wc_FreeMutex(&ecx->mutex); #endif (*ecx->data->freeKey)((void*)&ecx->key); + /* unclamped holds 2 bytes of the original private key. */ + OPENSSL_cleanse(ecx->unclamped, sizeof(ecx->unclamped)); OPENSSL_free(ecx); } } diff --git a/src/wp_file_store.c b/src/wp_file_store.c index 571b180d..eebd8d11 100644 --- a/src/wp_file_store.c +++ b/src/wp_file_store.c @@ -440,6 +440,9 @@ static void wp_bio_consume_all(BIO* bio) do { bytes_read = BIO_read(bio, buffer, sizeof(buffer)); } while (bytes_read > 0); + + /* buffer may hold private key material from the drained file. */ + OPENSSL_cleanse(buffer, sizeof(buffer)); } /** diff --git a/src/wp_hkdf.c b/src/wp_hkdf.c index 6dabe2f5..43a53d5e 100644 --- a/src/wp_hkdf.c +++ b/src/wp_hkdf.c @@ -674,6 +674,9 @@ static int wp_tls13_hkdf_extract(wp_HkdfCtx* ctx, unsigned char* key, } } + /* secret may hold a Derive-Secret intermediate used as the salt. */ + OPENSSL_cleanse(secret, sizeof(secret)); + WOLFPROV_LEAVE(WP_LOG_COMP_HKDF, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; } diff --git a/src/wp_internal.c b/src/wp_internal.c index 058e71f0..ceb2fce6 100644 --- a/src/wp_internal.c +++ b/src/wp_internal.c @@ -1207,6 +1207,9 @@ int wp_read_der_bio(WOLFPROV_CTX *provctx, OSSL_CORE_BIO *coreBio, unsigned char } } + /* buf may hold plaintext private key DER fragments. */ + OPENSSL_cleanse(buf, sizeof(buf)); + BIO_free(bio); WOLFPROV_LEAVE(WP_LOG_COMP_PROVIDER, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; @@ -1266,6 +1269,9 @@ int wp_read_pem_bio(WOLFPROV_CTX *provctx, OSSL_CORE_BIO *coreBio, } } + /* buf may hold plaintext private key PEM line fragments. */ + OPENSSL_cleanse(buf, sizeof(buf)); + BIO_free(bio); WOLFPROV_LEAVE(WP_LOG_COMP_PROVIDER, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); diff --git a/src/wp_kbkdf.c b/src/wp_kbkdf.c index b96f429a..7b595cb6 100644 --- a/src/wp_kbkdf.c +++ b/src/wp_kbkdf.c @@ -402,6 +402,9 @@ static int wp_kbkdf_init_hmac(wp_KbkdfCtx* ctx, unsigned char* key, } } + /* localKey holds a copy of the secret KDF key. */ + OPENSSL_cleanse(localKey, sizeof(localKey)); + WOLFPROV_LEAVE(WP_LOG_COMP_KDF, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); /* Use rc style return */ return (ok == 1) ? 0 : -1; @@ -683,6 +686,9 @@ static int wp_kdf_kbkdf_derive(wp_KbkdfCtx* ctx, unsigned char* key, wp_kbkdf_mac_free(ctx); } + /* k_i holds derived key block(s) (and feedback state). */ + OPENSSL_cleanse(k_i, sizeof(k_i)); + WOLFPROV_LEAVE(WP_LOG_COMP_KDF, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; } diff --git a/src/wp_krb5kdf.c b/src/wp_krb5kdf.c index b1eda69e..a2ec853c 100644 --- a/src/wp_krb5kdf.c +++ b/src/wp_krb5kdf.c @@ -528,6 +528,10 @@ static int wp_kdf_krb5kdf_derive(wp_Krb5kdfCtx* ctx, unsigned char* key, wc_AesFree(&aes); + /* block and cipherBlock hold derived key material. */ + OPENSSL_cleanse(block, sizeof(block)); + OPENSSL_cleanse(cipherBlock, sizeof(cipherBlock)); + WOLFPROV_LEAVE(WP_LOG_COMP_KRB5KDF, "wp_kdf_krb5kdf_derive", ok); return ok; } diff --git a/src/wp_params.c b/src/wp_params.c index 761123a4..b7b02308 100644 --- a/src/wp_params.c +++ b/src/wp_params.c @@ -63,6 +63,9 @@ int wp_mp_read_unsigned_bin_le(mp_int* mp, const unsigned char* data, } } + /* rdata may hold private key material (RSA d/p/q, EC/DH private). */ + OPENSSL_cleanse(rdata, sizeof(rdata)); + WOLFPROV_LEAVE(WP_LOG_COMP_PROVIDER, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok); return ok; } diff --git a/src/wp_rsa_kmgmt.c b/src/wp_rsa_kmgmt.c index c65f09f5..becaa404 100644 --- a/src/wp_rsa_kmgmt.c +++ b/src/wp_rsa_kmgmt.c @@ -3316,6 +3316,10 @@ static int wp_rsa_encode_enc_pki(const wp_RsaEncDecCtx* ctx, const wp_Rsa* rsa, } } + /* encodedKey holds the plaintext PKCS#8 private key before encryption. */ + if (encodedKey != NULL) { + OPENSSL_cleanse(encodedKey, len); + } XFREE(encodedKey, NULL, DYNAMIC_TYPE_RSA_BUFFER); OPENSSL_cleanse(password, sizeof(password)); @@ -4276,7 +4280,7 @@ static int wp_rsa_encode_text_format_hex(BIO *out, const mp_int* num, } else if (mp_to_unsigned_bin((mp_int*)num, binData) != MP_OKAY) { ok = 0; - OPENSSL_free(binData); + OPENSSL_clear_free(binData, binLen); binData = NULL; } else { @@ -4315,7 +4319,8 @@ static int wp_rsa_encode_text_format_hex(BIO *out, const mp_int* num, } } - OPENSSL_free(binData); + /* binData may hold private CRT components (d/p/q/dP/dQ/u). */ + OPENSSL_clear_free(binData, binLen); binData = NULL; } diff --git a/src/wp_seed_src.c b/src/wp_seed_src.c index 3e9ac97b..49268853 100644 --- a/src/wp_seed_src.c +++ b/src/wp_seed_src.c @@ -657,14 +657,14 @@ static size_t wp_seed_src_get_seed(wp_SeedSrcCtx* ctx, unsigned char** pSeed, if (rc != (int)minLen) { WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wp_urandom_read failed", rc); - OPENSSL_free(buffer); + OPENSSL_clear_free(buffer, minLen); buffer = NULL; goto end; } /* Mix in additional input if provided */ if (!wp_seed_src_adin_mix_in(buffer, minLen, addIn, addInLen)) { - OPENSSL_free(buffer); + OPENSSL_clear_free(buffer, minLen); buffer = NULL; goto end; }