diff --git a/linuxkm/lkcapi_aes_glue.c b/linuxkm/lkcapi_aes_glue.c index a338487acb..1bdb45e20c 100644 --- a/linuxkm/lkcapi_aes_glue.c +++ b/linuxkm/lkcapi_aes_glue.c @@ -1129,15 +1129,16 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) tfm = crypto_aead_reqtfm(req); ctx = crypto_aead_ctx(tfm); + if (((word32)req->assoclen + (word32)req->cryptlen) != + ((word64)req->assoclen + (word64)req->cryptlen)) + { + return -EOVERFLOW; + } + if (decrypt_p) { /* Copy out original auth tag from req->src. */ if (req->cryptlen < tfm->authsize) return -EINVAL; - if (((word32)req->assoclen + (word32)req->cryptlen) != - ((word64)req->assoclen + (word64)req->cryptlen)) - { - return -EOVERFLOW; - } scatterwalk_map_and_copy(authTag, req->src, req->assoclen + req->cryptlen - tfm->authsize, tfm->authsize, 0); @@ -1355,15 +1356,16 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) tfm = crypto_aead_reqtfm(req); ctx = crypto_aead_ctx(tfm); + if (((word32)req->assoclen + (word32)req->cryptlen) != + ((word64)req->assoclen + (word64)req->cryptlen)) + { + return -EOVERFLOW; + } + if (decrypt_p) { /* Copy out original auth tag from req->src. */ if (req->cryptlen < tfm->authsize) return -EINVAL; - if (((word32)req->assoclen + (word32)req->cryptlen) != - ((word64)req->assoclen + (word64)req->cryptlen)) - { - return -EOVERFLOW; - } scatterwalk_map_and_copy(authTag, req->src, req->assoclen + req->cryptlen - tfm->authsize, tfm->authsize, 0); @@ -1378,7 +1380,7 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) crypto_tfm_alg_driver_name(crypto_aead_tfm(tfm)), decrypt_p ? "skcipher_walk_aead_decrypt" : "skcipher_walk_aead_encrypt", err); - return -EINVAL; + return err; } err = km_AesGet(ctx, decrypt_p, 1 /* copy_p */, &aes_copy); @@ -1513,6 +1515,7 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) out: if (sg_buf) { + ForceZero(sg_buf, req->assoclen + req->cryptlen); free(sg_buf); } else { @@ -1835,15 +1838,16 @@ static int AesCcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4309_p) tfm = crypto_aead_reqtfm(req); ctx = crypto_aead_ctx(tfm); + if (((word32)req->assoclen + (word32)req->cryptlen) != + ((word64)req->assoclen + (word64)req->cryptlen)) + { + return -EOVERFLOW; + } + if (decrypt_p) { /* Copy out the original auth tag from req->src. */ if (req->cryptlen < tfm->authsize) return -EINVAL; - if (((word32)req->assoclen + (word32)req->cryptlen) != - ((word64)req->assoclen + (word64)req->cryptlen)) - { - return -EOVERFLOW; - } scatterwalk_map_and_copy(authTag, req->src, req->assoclen + req->cryptlen - tfm->authsize, tfm->authsize, 0); @@ -2006,6 +2010,7 @@ static int AesCcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4309_p) out: if (sg_buf) { + ForceZero(sg_buf, req->assoclen + req->cryptlen); free(sg_buf); } else { @@ -2312,6 +2317,11 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) err = skcipher_walk_done(&walk, 0); } else if (! (stream.bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))) { err = wc_AesXtsEncryptFinal(ctx->aesXts, NULL, NULL, 0, &stream); + if (unlikely(err)) { + pr_err("%s: wc_AesXtsEncryptFinal failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + err = -EINVAL; + } } } @@ -2458,6 +2468,11 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) err = skcipher_walk_done(&walk, 0); } else if (! (stream.bytes_crypted_with_this_tweak & ((word32)WC_AES_BLOCK_SIZE - 1U))) { err = wc_AesXtsDecryptFinal(ctx->aesXts, NULL, NULL, 0, &stream); + if (unlikely(err)) { + pr_err("%s: wc_AesXtsDecryptFinal failed: %d\n", + crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); + err = -EINVAL; + } } } @@ -3099,12 +3114,14 @@ static int linuxkm_test_aescbc(void) enc2 = malloc(sizeof(p_vector)); if (!enc2) { pr_err("error: malloc failed\n"); + ret = MEMORY_E; goto test_cbc_end; } dec2 = malloc(sizeof(p_vector)); if (!dec2) { pr_err("error: malloc failed\n"); + ret = MEMORY_E; goto test_cbc_end; } @@ -3140,7 +3157,7 @@ static int linuxkm_test_aescbc(void) req = skcipher_request_alloc(tfm, GFP_KERNEL); if (! req) { ret = -ENOMEM; - pr_err("error: allocating AES skcipher request %s failed\n", + pr_err("error: allocating AES skcipher request %s failed.\n", WOLFKM_AESCBC_DRIVER); goto test_cbc_end; } @@ -3310,12 +3327,14 @@ static int linuxkm_test_aescfb(void) enc2 = malloc(sizeof(p_vector)); if (!enc2) { pr_err("error: malloc failed\n"); + ret = MEMORY_E; goto test_cfb_end; } dec2 = malloc(sizeof(p_vector)); if (!dec2) { pr_err("error: malloc failed\n"); + ret = MEMORY_E; goto test_cfb_end; } @@ -3342,7 +3361,7 @@ static int linuxkm_test_aescfb(void) req = skcipher_request_alloc(tfm, GFP_KERNEL); if (! req) { ret = -ENOMEM; - pr_err("error: allocating AES skcipher request %s failed\n", + pr_err("error: allocating AES skcipher request %s failed.\n", WOLFKM_AESCFB_DRIVER); goto test_cfb_end; } @@ -3552,6 +3571,7 @@ static int linuxkm_test_aesgcm(void) assoc2 = malloc(sizeof(assoc)); if (! assoc2) { pr_err("error: malloc failed\n"); + ret = MEMORY_E; goto test_gcm_end; } memset(assoc2, 0, sizeof(assoc)); @@ -3560,6 +3580,7 @@ static int linuxkm_test_aesgcm(void) iv = malloc(WC_AES_BLOCK_SIZE); if (! iv) { pr_err("error: malloc failed\n"); + ret = MEMORY_E; goto test_gcm_end; } memset(iv, 0, WC_AES_BLOCK_SIZE); @@ -3568,12 +3589,14 @@ static int linuxkm_test_aesgcm(void) enc2 = malloc(decryptLen); if (! enc2) { pr_err("error: malloc failed\n"); + ret = MEMORY_E; goto test_gcm_end; } dec2 = malloc(decryptLen); if (! dec2) { pr_err("error: malloc failed\n"); + ret = MEMORY_E; goto test_gcm_end; } @@ -3608,24 +3631,24 @@ static int linuxkm_test_aesgcm(void) req = aead_request_alloc(tfm, GFP_KERNEL); if (! req) { ret = -ENOMEM; - pr_err("error: allocating AES aead request %s failed: %ld\n", - WOLFKM_AESCBC_DRIVER, PTR_ERR(req)); + pr_err("error: allocating AES aead request %s failed.\n", + WOLFKM_AESCBC_DRIVER); goto test_gcm_end; } src = malloc(sizeof(struct scatterlist) * 2); if (! src) { - pr_err("error: malloc src failed: %ld\n", - PTR_ERR(src)); + pr_err("error: malloc src failed.\n"); + ret = MEMORY_E; goto test_gcm_end; } dst = malloc(sizeof(struct scatterlist) * 2); if (! dst) { - pr_err("error: malloc dst failed: %ld\n", - PTR_ERR(dst)); + pr_err("error: malloc dst failed.\n"); + ret = MEMORY_E; goto test_gcm_end; } @@ -4511,11 +4534,27 @@ static int aes_xts_256_test(void) goto out; } +#if defined(DEBUG_VECTOR_REGISTER_ACCESS) && defined(WC_C_DYNAMIC_FALLBACK) + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(WC_NO_ERR_TRACE(SYSLIB_FAILED_E)); + ret = wc_AesXtsEncrypt(aes, buf, p1, sizeof(p1), i1, sizeof(i1)); + WC_DEBUG_SET_VECTOR_REGISTERS_RETVAL(0); + if (ret != 0) + goto out; + if (XMEMCMP(c1, buf, WC_AES_BLOCK_SIZE)) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } +#endif + /* partial block encryption test */ XMEMSET(cipher, 0, AES_XTS_256_TEST_BUF_SIZ); ret = wc_AesXtsEncrypt(aes, cipher, pp, sizeof(pp), i1, sizeof(i1)); if (ret != 0) goto out; + if (XMEMCMP(cp, cipher, sizeof(cp))) { + ret = LINUXKM_LKCAPI_AES_KAT_MISMATCH_E; + goto out; + } /* partial block decrypt test */ XMEMSET(buf, 0, AES_XTS_256_TEST_BUF_SIZ); @@ -4705,8 +4744,8 @@ static int aes_xts_256_test(void) req = skcipher_request_alloc(tfm, GFP_KERNEL); if (! req) { ret = -ENOMEM; - pr_err("error: allocating AES skcipher request %s failed: %d\n", - WOLFKM_AESXTS_DRIVER, ret); + pr_err("error: allocating AES skcipher request %s failed.\n", + WOLFKM_AESXTS_DRIVER); goto test_xts_end; } diff --git a/linuxkm/lkcapi_dh_glue.c b/linuxkm/lkcapi_dh_glue.c index cc4dc8781e..6196c2a0fe 100644 --- a/linuxkm/lkcapi_dh_glue.c +++ b/linuxkm/lkcapi_dh_glue.c @@ -562,6 +562,9 @@ static int km_dh_set_secret(struct crypto_kpp *tfm, const void *buf, ctx->has_pub_key = 0; dh_secret_end: + if (err != 0) + km_dh_reset_ctx(ctx); + #ifdef WOLFKM_DEBUG_DH pr_info("info: exiting km_dh_set_secret\n"); #endif /* WOLFKM_DEBUG_DH */ @@ -754,6 +757,7 @@ static int km_ffdhe_init(struct crypto_kpp *tfm, int name, word32 nbits) { struct km_dh_ctx * ctx = NULL; int err = 0; + int key_inited = 0; ctx = kpp_tfm_ctx(tfm); memset(ctx, 0, sizeof(struct km_dh_ctx)); @@ -770,16 +774,18 @@ static int km_ffdhe_init(struct crypto_kpp *tfm, int name, word32 nbits) ctx->key = (DhKey *)malloc(sizeof(DhKey)); if (!ctx->key) { - return -ENOMEM; + err = -ENOMEM; + goto out; } err = wc_InitDhKey(ctx->key); if (err < 0) { - free(ctx->key); - ctx->key = NULL; - return -ENOMEM; + err = -ENOMEM; + goto out; } + key_inited = 1; + if (ctx->name) { err = wc_DhSetNamedKey(ctx->key, ctx->name); if (err) { @@ -787,10 +793,8 @@ static int km_ffdhe_init(struct crypto_kpp *tfm, int name, word32 nbits) pr_err("%s: wc_DhSetNamedKey returned: %d\n", WOLFKM_DH_DRIVER, err); #endif /* WOLFKM_DEBUG_DH */ - wc_FreeDhKey(ctx->key); - free(ctx->key); - ctx->key = NULL; - return -ENOMEM; + err = -ENOMEM; + goto out; } } @@ -798,7 +802,20 @@ static int km_ffdhe_init(struct crypto_kpp *tfm, int name, word32 nbits) pr_info("info: exiting km_dh_init: name %d, nbits %d\n", ctx->name, ctx->nbits); #endif /* WOLFKM_DEBUG_DH */ - return 0; + +out: + + if (err != 0) { + if (ctx->key) { + if (key_inited) + wc_FreeDhKey(ctx->key); + free(ctx->key); + ctx->key = NULL; + } + wc_FreeRng(&ctx->rng); + } + + return err; } #ifdef LINUXKM_DH @@ -2888,7 +2905,7 @@ static int linuxkm_test_kpp_driver(const char * driver, req = kpp_request_alloc(tfm, GFP_KERNEL); if (! req) { - test_rc = -ENOMEM; + test_rc = MEMORY_E; pr_err("error: allocating kpp request %s failed\n", driver); goto test_kpp_end; diff --git a/linuxkm/lkcapi_ecdh_glue.c b/linuxkm/lkcapi_ecdh_glue.c index be1186b060..d00cfa8a2f 100644 --- a/linuxkm/lkcapi_ecdh_glue.c +++ b/linuxkm/lkcapi_ecdh_glue.c @@ -382,6 +382,7 @@ static int km_ecdh_init(struct crypto_kpp *tfm, int curve_id) { struct km_ecdh_ctx * ctx = NULL; int ret = 0; + int key_inited = 0; ctx = kpp_tfm_ctx(tfm); memset(ctx, 0, sizeof(struct km_ecdh_ctx)); @@ -410,23 +411,23 @@ static int km_ecdh_init(struct crypto_kpp *tfm, int curve_id) ctx->key = (ecc_key *)malloc(sizeof(ecc_key)); if (!ctx->key) { - return -ENOMEM; + ret = -ENOMEM; + goto out; } ret = wc_ecc_init(ctx->key); if (ret < 0) { - free(ctx->key); - ctx->key = NULL; - return -ENOMEM; + ret = -ENOMEM; + goto out; } + key_inited = 1; + #ifdef ECC_TIMING_RESISTANT ret = wc_ecc_set_rng(ctx->key, &ctx->rng); if (ret < 0) { - wc_ecc_free(ctx->key); - free(ctx->key); - ctx->key = NULL; - return -ENOMEM; + ret = -ENOMEM; + goto out; } #endif /* ECC_TIMING_RESISTANT */ @@ -434,7 +435,20 @@ static int km_ecdh_init(struct crypto_kpp *tfm, int curve_id) pr_info("info: exiting km_ecdh_init: curve_id %d, curve_len %d\n", ctx->curve_id, ctx->curve_len); #endif /* WOLFKM_DEBUG_ECDH */ - return 0; + +out: + + if (ret != 0) { + if (ctx->key) { + if (key_inited) + wc_ecc_free(ctx->key); + free(ctx->key); + ctx->key = NULL; + } + wc_FreeRng(&ctx->rng); + } + + return ret; } #if defined(LINUXKM_ECC192) diff --git a/linuxkm/lkcapi_ecdsa_glue.c b/linuxkm/lkcapi_ecdsa_glue.c index 62e2eca120..6832419ab2 100644 --- a/linuxkm/lkcapi_ecdsa_glue.c +++ b/linuxkm/lkcapi_ecdsa_glue.c @@ -417,6 +417,11 @@ static int km_ecdsa_verify(struct akcipher_request *req) goto ecdsa_verify_end; } + if ((sig_len + hash_len) != ((word64)sig_len + (word64)hash_len)) { + err = -EINVAL; + goto ecdsa_verify_end; + } + sig = malloc(sig_len + hash_len); if (unlikely(sig == NULL)) { err = -ENOMEM; diff --git a/linuxkm/lkcapi_glue.c b/linuxkm/lkcapi_glue.c index b51d403601..8b23b015ac 100644 --- a/linuxkm/lkcapi_glue.c +++ b/linuxkm/lkcapi_glue.c @@ -292,8 +292,10 @@ static int linuxkm_lkcapi_sysfs_install(void) { if (ret) return ret; ret = linuxkm_lkcapi_sysfs_install_node(&deinstall_algs_attr, NULL); - if (ret) + if (ret) { + (void)linuxkm_lkcapi_sysfs_deinstall_node(&install_algs_attr, NULL); return ret; + } installed_sysfs_LKCAPI_files = 1; } return 0; @@ -949,9 +951,6 @@ static int linuxkm_lkcapi_unregister(void) #ifdef WOLFSSL_SHA384 UNREGISTER_ALG(pkcs1_sha384, akcipher); #endif /* WOLFSSL_SHA384 */ - #ifdef WOLFSSL_SHA384 - UNREGISTER_ALG(pkcs1_sha384, akcipher); - #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 UNREGISTER_ALG(pkcs1_sha512, akcipher); #endif /* WOLFSSL_SHA512 */ @@ -970,9 +969,6 @@ static int linuxkm_lkcapi_unregister(void) #ifdef WOLFSSL_SHA384 UNREGISTER_ALG(pkcs1_sha384, sig); #endif /* WOLFSSL_SHA384 */ - #ifdef WOLFSSL_SHA384 - UNREGISTER_ALG(pkcs1_sha384, sig); - #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 UNREGISTER_ALG(pkcs1_sha512, sig); #endif /* WOLFSSL_SHA512 */ diff --git a/linuxkm/lkcapi_rsa_glue.c b/linuxkm/lkcapi_rsa_glue.c index 4fb126605d..b90c42429b 100644 --- a/linuxkm/lkcapi_rsa_glue.c +++ b/linuxkm/lkcapi_rsa_glue.c @@ -746,8 +746,11 @@ static int km_direct_rsa_enc(struct akcipher_request *req) err = 0; rsa_enc_out: - if (enc != NULL) { free(enc); enc = NULL; } - if (dec != NULL) { free(dec); dec = NULL; } + free(enc); + if (dec != NULL) { + ForceZero(dec, req->src_len); + free(dec); + } #ifdef WOLFKM_DEBUG_RSA pr_info("info: exiting km_direct_rsa_enc\n"); @@ -769,6 +772,7 @@ static int km_direct_rsa_dec(struct akcipher_request *req) struct km_rsa_ctx * ctx = NULL; int err = 0; word32 out_len = 0; + word32 dec_alloc = 0; byte * enc = NULL; byte * dec = NULL; @@ -793,11 +797,12 @@ static int km_direct_rsa_dec(struct akcipher_request *req) } if (req->dst_len != (unsigned int)ctx->key_len) { - if ((req->dst_len > 0) && (req->dst_len < (unsigned int)ctx->key_len)) + if ((req->dst_len > 0) && (req->dst_len < (unsigned int)ctx->key_len)) { err = -EOVERFLOW; + req->dst_len = ctx->key_len; + } else err = -EINVAL; - req->dst_len = ctx->key_len; goto rsa_dec_out; } @@ -807,7 +812,8 @@ static int km_direct_rsa_dec(struct akcipher_request *req) goto rsa_dec_out; } - dec = malloc(req->dst_len); + dec_alloc = req->dst_len; + dec = malloc(dec_alloc); if (unlikely(dec == NULL)) { err = -ENOMEM; goto rsa_dec_out; @@ -845,8 +851,11 @@ static int km_direct_rsa_dec(struct akcipher_request *req) err = 0; rsa_dec_out: - if (enc != NULL) { free(enc); enc = NULL; } - if (dec != NULL) { free(dec); dec = NULL; } + free(enc); + if (dec != NULL) { + ForceZero(dec, dec_alloc); + free(dec); + } #ifdef WOLFKM_DEBUG_RSA pr_info("info: exiting km_direct_rsa_dec\n"); @@ -1092,8 +1101,8 @@ static int km_pkcs1pad_sign(struct akcipher_request *req) struct crypto_akcipher * tfm = NULL; struct km_rsa_ctx * ctx = NULL; int err = 0; - word32 sig_len = 0; - word32 enc_len = 0; + int sig_len = 0; + int enc_len = 0; int hash_enc_len = 0; byte * msg = NULL; byte * sig = NULL; @@ -1119,7 +1128,7 @@ static int km_pkcs1pad_sign(struct akcipher_request *req) goto pkcs1pad_sign_out; } - if (req->src_len + hash_enc_len + RSA_MIN_PAD_SZ > ctx->key_len) { + if ((word64)req->src_len + (word64)hash_enc_len + RSA_MIN_PAD_SZ > ctx->key_len) { err = -EOVERFLOW; goto pkcs1pad_sign_out; } @@ -1161,7 +1170,7 @@ static int km_pkcs1pad_sign(struct akcipher_request *req) /* sign encoded message. */ sig_len = wc_RsaSSL_Sign(msg, enc_len, sig, ctx->key_len, ctx->key, &ctx->rng); - if (unlikely(sig_len != ctx->key_len)) { + if (unlikely(sig_len != (int)ctx->key_len)) { #ifdef WOLFKM_DEBUG_RSA pr_err("error: %s: wc_RsaSSL_Sign returned: %d\n", WOLFKM_RSA_DRIVER, sig_len); @@ -1175,7 +1184,10 @@ static int km_pkcs1pad_sign(struct akcipher_request *req) err = 0; pkcs1pad_sign_out: - if (work_buffer != NULL) { free(work_buffer); work_buffer = NULL; } + if (work_buffer) { + ForceZero(work_buffer, 2 * ctx->key_len); + free(work_buffer); + } #ifdef WOLFKM_DEBUG_RSA pr_info("info: exiting km_pkcs1pad_sign msg_len %d, enc_msg_len %d," @@ -1201,9 +1213,9 @@ static int km_pkcs1pad_verify(struct akcipher_request *req) struct km_rsa_ctx * ctx = NULL; int err = 0; word32 sig_len = 0; - word32 dec_len = 0; + int dec_len = 0; word32 msg_len = 0; - word32 enc_msg_len = 0; + int enc_msg_len = 0; int hash_enc_len = 0; int n_diff = 0; byte * sig = NULL; @@ -1290,7 +1302,7 @@ static int km_pkcs1pad_verify(struct akcipher_request *req) err = 0; pkcs1pad_verify_out: - if (work_buffer != NULL) { free(work_buffer); work_buffer = NULL; } + free(work_buffer); #ifdef WOLFKM_DEBUG_RSA pr_info("info: exiting km_pkcs1pad_verify msg_len %d, enc_msg_len %d," @@ -1340,8 +1352,8 @@ static int km_pkcs1_sign(struct crypto_sig *tfm, { struct km_rsa_ctx * ctx = NULL; int err = 0; - word32 sig_len = 0; - word32 enc_msg_len = 0; + int sig_len = 0; + int enc_msg_len = 0; int hash_enc_len = 0; byte * msg = NULL; byte * sig = dst; /* reuse dst buffer. we will check if @@ -1366,7 +1378,7 @@ static int km_pkcs1_sign(struct crypto_sig *tfm, goto pkcs1_sign_out; } - if (slen + hash_enc_len + RSA_MIN_PAD_SZ > ctx->key_len) { + if ((word64)slen + (word64)hash_enc_len + RSA_MIN_PAD_SZ > ctx->key_len) { err = -EOVERFLOW; goto pkcs1_sign_out; } @@ -1406,7 +1418,7 @@ static int km_pkcs1_sign(struct crypto_sig *tfm, /* sign encoded message. */ sig_len = wc_RsaSSL_Sign(msg, enc_msg_len, sig, ctx->key_len, ctx->key, &ctx->rng); - if (unlikely(sig_len != ctx->key_len)) { + if (unlikely(sig_len != (int)ctx->key_len)) { #ifdef WOLFKM_DEBUG_RSA pr_err("error: %s: wc_RsaSSL_Sign returned: %d\n", WOLFKM_RSA_DRIVER, sig_len); @@ -1423,7 +1435,10 @@ static int km_pkcs1_sign(struct crypto_sig *tfm, err = 0; #endif /* linux >= 6.15.0 */ pkcs1_sign_out: - if (msg != NULL) { free(msg); msg = NULL; } + if (msg != NULL) { + ForceZero(msg, ctx->key_len); + free(msg); + } #ifdef WOLFKM_DEBUG_RSA pr_info("info: exiting km_pkcs1_sign msg_len %d, enc_msg_len %d," @@ -1453,9 +1468,9 @@ static int km_pkcs1_verify(struct crypto_sig *tfm, struct km_rsa_ctx * ctx = NULL; int err = 0; word32 sig_len = 0; - word32 dec_len = 0; + int dec_len = 0; word32 msg_len = 0; - word32 enc_msg_len = 0; + int enc_msg_len = 0; int hash_enc_len = 0; int n_diff = 0; byte * enc_digest = NULL; @@ -1541,7 +1556,7 @@ static int km_pkcs1_verify(struct crypto_sig *tfm, err = 0; pkcs1_verify_out: - if (work_buffer != NULL) { free(work_buffer); work_buffer = NULL; } + free(work_buffer); #ifdef WOLFKM_DEBUG_RSA pr_info("info: exiting km_pkcs1_verify msg_len %d, enc_msg_len %d," @@ -1621,6 +1636,12 @@ static int km_pkcs1_set_pub(struct crypto_sig *tfm, const void *key, if (unlikely(err)) { return -ENOMEM; } + + /* Note the initialization of ctx->rng is deferred unless/until needed. */ + err = wc_RsaSetRNG(ctx->key, &ctx->rng); + if (unlikely(err)) { + return -ENOMEM; + } } err = wc_RsaPublicKeyDecode(key, &idx, ctx->key, keylen); @@ -1687,7 +1708,7 @@ static int km_pkcs1pad_enc(struct akcipher_request *req) goto pkcs1_enc_out; } - if (req->src_len + RSA_MIN_PAD_SZ > ctx->key_len) { + if ((word64)req->src_len + RSA_MIN_PAD_SZ > ctx->key_len) { err = -EOVERFLOW; goto pkcs1_enc_out; } @@ -1736,8 +1757,12 @@ static int km_pkcs1pad_enc(struct akcipher_request *req) err = 0; pkcs1_enc_out: - if (enc != NULL) { free(enc); enc = NULL; } - if (dec != NULL) { free(dec); dec = NULL; } + free(enc); + if (dec != NULL) { + ForceZero(dec, req->src_len); + free(dec); + } + #ifdef WOLFKM_DEBUG_RSA pr_info("info: exiting km_pkcs1pad_enc %d\n", err); #endif /* WOLFKM_DEBUG_RSA */ @@ -1749,7 +1774,8 @@ static int km_pkcs1pad_dec(struct akcipher_request *req) struct crypto_akcipher * tfm = NULL; struct km_rsa_ctx * ctx = NULL; int err = 0; - word32 dec_len = 0; + int dec_len = 0; + word32 dec_alloc = 0; byte * enc = NULL; byte * dec = NULL; @@ -1782,7 +1808,8 @@ static int km_pkcs1pad_dec(struct akcipher_request *req) goto pkcs1_dec_out; } - dec = malloc(req->dst_len); + dec_alloc = req->dst_len; + dec = malloc(dec_alloc); if (unlikely(dec == NULL)) { err = -ENOMEM; goto pkcs1_dec_out; @@ -1802,7 +1829,7 @@ static int km_pkcs1pad_dec(struct akcipher_request *req) dec_len = wc_RsaPrivateDecrypt(enc, ctx->key_len, dec, req->dst_len, ctx->key); - if (unlikely(dec_len <= 0 || dec_len > ctx->key_len)) { + if (unlikely(dec_len <= 0 || dec_len > (int)ctx->key_len)) { #ifdef WOLFKM_DEBUG_RSA pr_err("error: %s: rsa private decrypt returned: %d, %d\n", WOLFKM_RSA_DRIVER, dec_len, ctx->key_len); @@ -1811,7 +1838,7 @@ static int km_pkcs1pad_dec(struct akcipher_request *req) goto pkcs1_dec_out; } - if (dec_len > req->dst_len) { + if (dec_len > (int)req->dst_len) { err = -EOVERFLOW; req->dst_len = dec_len; goto pkcs1_dec_out; @@ -1822,8 +1849,11 @@ static int km_pkcs1pad_dec(struct akcipher_request *req) err = 0; pkcs1_dec_out: - if (enc != NULL) { free(enc); enc = NULL; } - if (dec != NULL) { free(dec); dec = NULL; } + free(enc); + if (dec != NULL) { + ForceZero(dec, dec_alloc); + free(dec); + } #ifdef WOLFKM_DEBUG_RSA pr_info("info: exiting km_pkcs1pad_dec %d\n", err); @@ -2080,9 +2110,9 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) RsaKey * key = NULL; WC_RNG rng; byte * priv = NULL; /* priv der */ - word32 priv_len = 0; + int priv_len = 0; byte * pub = NULL; /* pub der */ - word32 pub_len = 0; + int pub_len = 0; byte init_rng = 0; byte init_key = 0; static const byte p_vector[] = @@ -2096,7 +2126,7 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) byte * enc = NULL; byte * dec = NULL; /* wc decrypt */ byte * plaintext = NULL; /* km decrypt */ - word32 key_len = 0; + int key_len = 0; word32 out_len = 0; int enc_ret = 0; int dec_ret = 0; @@ -2197,7 +2227,7 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) out_len = key_len; enc_ret = wc_RsaDirect(dec, key_len, enc, &out_len, key, RSA_PUBLIC_ENCRYPT, &rng); - if (enc_ret != (int) key_len || key_len != out_len) { + if (enc_ret != key_len || key_len != (int)out_len) { pr_err("error: rsa pub enc returned: %d, %d\n", enc_ret, out_len); ret = -1; goto test_rsa_end; @@ -2206,7 +2236,7 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) memset(dec, 0, key_len); dec_ret = wc_RsaDirect(enc, key_len, dec, &out_len, key, RSA_PRIVATE_DECRYPT, &rng); - if (dec_ret != (int) key_len || key_len != out_len) { + if (dec_ret != key_len || key_len != (int)out_len) { pr_err("error: rsa priv dec returned: %d, %d\n", dec_ret, out_len); goto test_rsa_end; } @@ -2291,7 +2321,7 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) { unsigned int maxsize = crypto_akcipher_maxsize(tfm); - if (maxsize != key_len) { + if (key_len != (int)maxsize) { pr_err("error: crypto_akcipher_maxsize " "returned %d, expected %d\n", maxsize, key_len); goto test_rsa_end; @@ -2315,7 +2345,7 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) dec_ret = wc_RsaDirect(enc, key_len, dec, &out_len, key, RSA_PRIVATE_DECRYPT, &rng); - if (dec_ret != (int) key_len || key_len != out_len) { + if (dec_ret != key_len || key_len != (int)out_len) { pr_err("error: rsa priv dec returned: %d, %d\n", dec_ret, out_len); goto test_rsa_end; } @@ -2330,7 +2360,7 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) enc_ret = wc_RsaDirect(dec, key_len, enc, &out_len, key, RSA_PUBLIC_ENCRYPT, &rng); - if (enc_ret != (int) key_len || key_len != out_len) { + if (enc_ret != key_len || key_len != (int)out_len) { pr_err("error: rsa pub enc returned: %d, %d\n", enc_ret, out_len); ret = -1; goto test_rsa_end; @@ -2344,7 +2374,7 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) { unsigned int maxsize = crypto_akcipher_maxsize(tfm); - if (maxsize != key_len) { + if (key_len != (int)maxsize) { pr_err("error: crypto_akcipher_maxsize " "returned %d, expected %d\n", maxsize, key_len); goto test_rsa_end; @@ -2381,20 +2411,24 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) test_rc = 0; test_rsa_end: - if (req) { akcipher_request_free(req); req = NULL; } - if (tfm) { crypto_free_akcipher(tfm); tfm = NULL; } - - if (pub) { free(pub); pub = NULL; } - if (priv) { free(priv); priv = NULL; } - - if (plaintext) { free(plaintext); plaintext = NULL; } - if (dec) { free(dec); dec = NULL; } - if (enc) { free(enc); enc = NULL; } - - if (init_key) { wc_FreeRsaKey(key); init_key = 0; } - if (init_rng) { wc_FreeRng(&rng); init_rng = 0; } - - if (key) { free(key); key = NULL; } + if (req) + akcipher_request_free(req); + if (tfm) + crypto_free_akcipher(tfm); + free(pub); + if (priv) { + if (priv_len > 0) + ForceZero(priv, priv_len); + free(priv); + } + free(plaintext); + free(dec); + free(enc); + if (init_key) + wc_FreeRsaKey(key); + if (init_rng) + wc_FreeRng(&rng); + free(key); #ifdef WOLFKM_DEBUG_RSA pr_info("info: %s, %d, %d: self test returned: %d\n", driver, @@ -2422,9 +2456,9 @@ static int linuxkm_test_pkcs1pad_driver(const char * driver, int nbits, RsaKey * key = NULL; WC_RNG rng; byte * priv = NULL; /* priv der */ - word32 priv_len = 0; + int priv_len = 0; byte * pub = NULL; /* pub der */ - word32 pub_len = 0; + int pub_len = 0; byte init_rng = 0; byte init_key = 0; static const byte p_vector[] = @@ -2444,10 +2478,10 @@ static int linuxkm_test_pkcs1pad_driver(const char * driver, int nbits, byte * enc = NULL; byte * dec2 = NULL; byte * enc2 = NULL; - word32 key_len = 0; + int key_len = 0; #if !defined(LINUXKM_AKCIPHER_NO_SIGNVERIFY) - word32 sig_len = 0; - word32 enc_len = 0; + int sig_len = 0; + int enc_len = 0; #endif /* !LINUXKM_AKCIPHER_NO_SIGNVERIFY */ struct scatterlist src, dst; #if !defined(LINUXKM_AKCIPHER_NO_SIGNVERIFY) @@ -2722,7 +2756,7 @@ static int linuxkm_test_pkcs1pad_driver(const char * driver, int nbits, { unsigned int maxsize = crypto_akcipher_maxsize(tfm); - if (maxsize != key_len) { + if (key_len != (int)maxsize) { pr_err("error: crypto_akcipher_maxsize " "returned %d, expected %d\n", maxsize, key_len); test_rc = BAD_FUNC_ARG; @@ -2761,7 +2795,7 @@ static int linuxkm_test_pkcs1pad_driver(const char * driver, int nbits, { unsigned int maxsize = crypto_akcipher_maxsize(tfm); - if (maxsize != key_len) { + if (key_len != (int)maxsize) { pr_err("error: crypto_akcipher_maxsize " "returned %d, expected %d\n", maxsize, key_len); test_rc = BAD_FUNC_ARG; @@ -2909,26 +2943,32 @@ static int linuxkm_test_pkcs1pad_driver(const char * driver, int nbits, test_rc = 0; test_pkcs1_end: - if (req) { akcipher_request_free(req); req = NULL; } - if (tfm) { crypto_free_akcipher(tfm); tfm = NULL; } - - if (priv) { free(priv); priv = NULL; } - if (pub) { free(pub); pub = NULL; } - - if (enc2) { free(enc2); enc2 = NULL; } - if (dec2) { free(dec2); dec2 = NULL; } - if (enc) { free(enc); enc = NULL; } - if (dec) { free(dec); dec = NULL; } + if (req) + akcipher_request_free(req); + if (tfm) + crypto_free_akcipher(tfm); + if (priv) { + if (priv_len > 0) + ForceZero(priv, priv_len); + free(priv); + } + free(pub); + free(enc2); + free(dec2); + free(enc); + free(dec); #if !defined(LINUXKM_AKCIPHER_NO_SIGNVERIFY) - if (km_sig) { free(km_sig); km_sig = NULL; } - if (sig) { free(sig); sig = NULL; } - if (hash) { free(hash); } + free(km_sig); + free(sig); + free(hash); #endif /* !LINUXKM_AKCIPHER_NO_SIGNVERIFY */ - if (init_rng) { wc_FreeRng(&rng); init_rng = 0; } - if (init_key) { wc_FreeRsaKey(key); init_key = 0; } - if (key) { free(key); key = NULL; } + if (init_rng) + wc_FreeRng(&rng); + if (init_key) + wc_FreeRsaKey(key); + free(key); #ifdef WOLFKM_DEBUG_RSA if (skipped) { @@ -2961,9 +3001,9 @@ static int linuxkm_test_pkcs1_driver(const char * driver, int nbits, RsaKey * key = NULL; WC_RNG rng; byte * priv = NULL; /* priv der */ - word32 priv_len = 0; + int priv_len = 0; byte * pub = NULL; /* pub der */ - word32 pub_len = 0; + int pub_len = 0; byte init_rng = 0; byte init_key = 0; static const byte p_vector[] = @@ -2979,9 +3019,9 @@ static int linuxkm_test_pkcs1_driver(const char * driver, int nbits, byte * km_sig = NULL; byte * dec = NULL; byte * enc = NULL; - word32 key_len = 0; - word32 sig_len = 0; - word32 enc_len = 0; + int key_len = 0; + int sig_len = 0; + int enc_len = 0; int n_diff = 0; uint8_t skipped = 0; @@ -3228,9 +3268,9 @@ static int linuxkm_test_pkcs1_driver(const char * driver, int nbits, maxsize, keysize, digestsize); #endif /* WOLFKM_DEBUG_RSA */ - if (maxsize != key_len || - keysize != key_len || - digestsize != key_len) { + if ((int)maxsize != key_len || + (int)keysize != key_len || + (int)digestsize != key_len) { pr_err("error: crypto_sig_{max, key, digest}size " "returned {%d, %d, %d}, expected %d\n", maxsize, keysize, digestsize, key_len); @@ -3249,7 +3289,7 @@ static int linuxkm_test_pkcs1_driver(const char * driver, int nbits, /* in 6.15 crypto_sig_sign switched from returning 0 on success to * returning sig_len. */ #if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 15, 0) - if ((word32) ret != sig_len) { + if (ret != sig_len) { pr_err("error: crypto_sig_sign returned %d, expected %d\n", ret, sig_len); test_rc = BAD_FUNC_ARG; @@ -3273,21 +3313,25 @@ static int linuxkm_test_pkcs1_driver(const char * driver, int nbits, test_rc = 0; test_pkcs1_end: - if (tfm) { crypto_free_sig(tfm); tfm = NULL; } - - if (priv) { free(priv); priv = NULL; } - if (pub) { free(pub); pub = NULL; } - - if (enc) { free(enc); enc = NULL; } - if (dec) { free(dec); dec = NULL; } - - if (km_sig) { free(km_sig); km_sig = NULL; } - if (sig) { free(sig); sig = NULL; } - if (hash) { free(hash); } - - if (init_rng) { wc_FreeRng(&rng); init_rng = 0; } - if (init_key) { wc_FreeRsaKey(key); init_key = 0; } - if (key) { free(key); key = NULL; } + if (tfm) + crypto_free_sig(tfm); + if (priv) { + if (priv_len > 0) + ForceZero(priv, priv_len); + free(priv); + } + free(pub); + free(enc); + free(dec); + free(km_sig); + free(sig); + free(hash); + + if (init_rng) + wc_FreeRng(&rng); + if (init_key) + wc_FreeRsaKey(key); + free(key); #ifdef WOLFKM_DEBUG_RSA if (skipped) { diff --git a/linuxkm/lkcapi_sha_glue.c b/linuxkm/lkcapi_sha_glue.c index 9a80247bc3..a23598927d 100644 --- a/linuxkm/lkcapi_sha_glue.c +++ b/linuxkm/lkcapi_sha_glue.c @@ -604,8 +604,11 @@ static int km_ ## name ## _init(struct shash_desc *desc) { \ ret = init_f(ctx-> name ## _state, NULL, INVALID_DEVID); \ if (ret == 0) \ return 0; \ - else \ + else { \ + free(ctx-> name ## _state); \ + ctx-> name ## _state = NULL; \ return -EINVAL; \ + } \ } \ \ static int km_ ## name ## _update(struct shash_desc *desc, const u8 *data, \ @@ -646,6 +649,7 @@ static int km_ ## name ## _finup(struct shash_desc *desc, const u8 *data, \ \ if (ret != 0) { \ free_f(ctx-> name ## _state); \ + km_sha3_free_tstate(ctx); \ return -EINVAL; \ } \ \ @@ -818,6 +822,7 @@ WC_MAYBE_UNUSED static int km_hmac_init(struct shash_desc *desc) { ret = wc_HmacCopy(&p_ctx->wc_hmac, t_ctx->wc_hmac); if (ret != 0) { + ForceZero(t_ctx->wc_hmac, sizeof *t_ctx->wc_hmac); free(t_ctx->wc_hmac); t_ctx->wc_hmac = NULL; return -EINVAL; @@ -861,8 +866,10 @@ WC_MAYBE_UNUSED static int km_hmac_finup(struct shash_desc *desc, const u8 *data int ret = wc_HmacUpdate(ctx->wc_hmac, data, len); - if (ret != 0) + if (ret != 0) { + km_hmac_free_tstate(ctx); return -EINVAL; + } return km_hmac_final(desc, out); } diff --git a/linuxkm/module_hooks.c b/linuxkm/module_hooks.c index 88a1e97d8d..edb66864f0 100644 --- a/linuxkm/module_hooks.c +++ b/linuxkm/module_hooks.c @@ -472,6 +472,7 @@ static WC_INLINE int IntelRDseed64_r(word64* rnd) WC_SANITIZE_ENABLE(); buf = 0; } + wc_ForceZero(&buf, sizeof buf); return 0; } @@ -731,7 +732,7 @@ static int wolfssl_init(void) unsigned int stabilized_rodata_hash = 1; if (! canon_buf) { - pr_err("ERROR: malloc(%d) for WOLFSSL_*_SEGMENT_CANONICALIZER failed: %ld.\n", WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ, PTR_ERR(canon_buf)); + pr_err("ERROR: malloc(%d) for WOLFSSL_*_SEGMENT_CANONICALIZER failed.\n", WOLFSSL_SEGMENT_CANONICALIZER_BUFSIZ); return -ECANCELED; } diff --git a/linuxkm/x86_vector_register_glue.c b/linuxkm/x86_vector_register_glue.c index 90ae0efcc1..8ada98f9e4 100644 --- a/linuxkm/x86_vector_register_glue.c +++ b/linuxkm/x86_vector_register_glue.c @@ -72,7 +72,7 @@ WARN_UNUSED_RESULT int allocate_wolfcrypt_linuxkm_fpu_states(void) if (! wc_linuxkm_fpu_states) { pr_err("ERROR: allocation of %lu bytes for " "wc_linuxkm_fpu_states failed.\n", - nr_cpu_ids * sizeof(struct fpu_state *)); + nr_cpu_ids * sizeof(wc_linuxkm_fpu_states[0])); return MEMORY_E; }