diff --git a/.wolfssl_known_macro_extras b/.wolfssl_known_macro_extras index c23fd8949e..42d31cf0dd 100644 --- a/.wolfssl_known_macro_extras +++ b/.wolfssl_known_macro_extras @@ -661,8 +661,8 @@ WC_FORCE_LINUXKM_FORTIFY_SOURCE WC_HASH_CUSTOM_MAX_BLOCK_SIZE WC_HASH_CUSTOM_MAX_DIGEST_SIZE WC_HASH_CUSTOM_MIN_DIGEST_SIZE -WC_LINUXKM_NO_USE_HEAP_WRAPPERS WC_INIT_ERROR_WHEN_CONTENDED +WC_LINUXKM_NO_USE_HEAP_WRAPPERS WC_MLKEM_KERNEL_ASM WC_NO_ASYNC_SLEEP WC_NO_RNG_SIMPLE diff --git a/linuxkm/linuxkm_wc_port.h b/linuxkm/linuxkm_wc_port.h index 83e35dc692..a9c7689189 100644 --- a/linuxkm/linuxkm_wc_port.h +++ b/linuxkm/linuxkm_wc_port.h @@ -1449,8 +1449,8 @@ */ #undef tolower #undef toupper - #define tolower(c) (islower(c) ? (c) : ((c) + ('a'-'A'))) - #define toupper(c) (isupper(c) ? (c) : ((c) - ('a'-'A'))) + #define tolower(c) (isupper(c) ? ((c) + ('a'-'A')) : (c)) + #define toupper(c) (islower(c) ? ((c) - ('a'-'A')) : (c)) #if !defined(WOLFCRYPT_ONLY) && !defined(NO_CERTS) #define GetCA WC_PIE_INDIRECT_SYM(GetCA) diff --git a/linuxkm/lkcapi_aes_glue.c b/linuxkm/lkcapi_aes_glue.c index 574c7d20de..24d9025de2 100644 --- a/linuxkm/lkcapi_aes_glue.c +++ b/linuxkm/lkcapi_aes_glue.c @@ -1131,6 +1131,13 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) 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); @@ -1350,6 +1357,13 @@ static int AesGcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4106_p) 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); @@ -1823,6 +1837,13 @@ static int AesCcmCrypt_1(struct aead_request *req, int decrypt_p, int rfc4309_p) 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); @@ -2079,9 +2100,6 @@ static int ccmAesAead_rfc4309_loaded = 0; #endif /* LINUXKM_LKCAPI_REGISTER_AESCCM || LINUXKM_LKCAPI_REGISTER_AESCCM_RFC4309 */ - - - #ifdef LINUXKM_LKCAPI_REGISTER_AESXTS #ifndef WOLFSSL_AESXTS_STREAM @@ -2193,7 +2211,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsEncrypt failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, 0); @@ -2228,7 +2247,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsEncryptInit failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } while ((nbytes = walk.nbytes) != 0) { @@ -2250,7 +2270,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsEncryptUpdate failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); @@ -2284,7 +2305,8 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsEncryptFinal failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, 0); @@ -2298,6 +2320,11 @@ static int km_AesXtsEncrypt(struct skcipher_request *req) req->cryptlen); #endif /* WOLFKM_DEBUG_AES */ +out: + + if (err && walk.nbytes) + (void)skcipher_walk_done(&walk, err); + return err; } @@ -2331,7 +2358,8 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsDecrypt failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, 0); @@ -2365,7 +2393,8 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsDecryptInit failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } while ((nbytes = walk.nbytes) != 0) { @@ -2387,7 +2416,8 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsDecryptUpdate failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, walk.nbytes - nbytes); @@ -2421,7 +2451,8 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: wc_AesXtsDecryptFinal failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return -EINVAL; + err = -EINVAL; + goto out; } err = skcipher_walk_done(&walk, 0); @@ -2435,6 +2466,11 @@ static int km_AesXtsDecrypt(struct skcipher_request *req) req->cryptlen); #endif /* WOLFKM_DEBUG_AES */ +out: + + if (err && walk.nbytes) + (void)skcipher_walk_done(&walk, err); + return err; } @@ -2494,13 +2530,10 @@ static int km_AesCtrEncrypt(struct skcipher_request *req) return err; } - /* Copy the cipher state to mitigate races on Aes.reg and Aes.tmp. */ - aes_copy = (struct Aes *)malloc(sizeof(Aes)); - if (aes_copy == NULL) { - err = -ENOMEM; + err = km_AesGet(ctx, 0 /* decrypt_p */, 1 /* copy_p */, &aes_copy); + if (unlikely(err)) { goto out; } - XMEMCPY(aes_copy, ctx->aes_encrypt, sizeof(Aes)); err = wc_AesSetIV(aes_copy, walk.iv); @@ -2527,7 +2560,7 @@ static int km_AesCtrEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: skcipher_walk_done failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return err; + goto out; } } @@ -2568,16 +2601,11 @@ static int km_AesCtrDecrypt(struct skcipher_request *req) return err; } - /* Copy the cipher state to mitigate races on Aes.reg and Aes.tmp. */ - aes_copy = (struct Aes *)malloc(sizeof(Aes)); - if (aes_copy == NULL) { - err = -ENOMEM; + /* CTR uses the same schedule for encrypt and decrypt. */ + err = km_AesGet(ctx, 0 /* decrypt_p */, 1 /* copy_p */, &aes_copy); + if (unlikely(err)) { goto out; } - XMEMCPY(aes_copy, ctx->aes_encrypt, sizeof(Aes)); /* CTR uses the same - * schedule for encrypt - * and decrypt. - */ err = wc_AesSetIV(aes_copy, walk.iv); @@ -2682,13 +2710,10 @@ static int km_AesOfbEncrypt(struct skcipher_request *req) return err; } - /* Copy the cipher state to mitigate races on Aes.reg and Aes.tmp. */ - aes_copy = (struct Aes *)malloc(sizeof(Aes)); - if (aes_copy == NULL) { - err = -ENOMEM; + err = km_AesGet(ctx, 0 /* decrypt_p */, 1 /* copy_p */, &aes_copy); + if (unlikely(err)) { goto out; } - XMEMCPY(aes_copy, ctx->aes_encrypt, sizeof(Aes)); err = wc_AesSetIV(aes_copy, walk.iv); @@ -2715,7 +2740,7 @@ static int km_AesOfbEncrypt(struct skcipher_request *req) if (unlikely(err)) { pr_err("%s: skcipher_walk_done failed: %d\n", crypto_tfm_alg_driver_name(crypto_skcipher_tfm(tfm)), err); - return err; + goto out; } } @@ -2756,16 +2781,11 @@ static int km_AesOfbDecrypt(struct skcipher_request *req) return err; } - /* Copy the cipher state to mitigate races on Aes.reg and Aes.tmp. */ - aes_copy = (struct Aes *)malloc(sizeof(Aes)); - if (aes_copy == NULL) { - err = -ENOMEM; + /* OFB uses the same schedule for encrypt and decrypt. */ + err = km_AesGet(ctx, 0 /* decrypt_p */, 1 /* copy_p */, &aes_copy); + if (unlikely(err)) { goto out; } - XMEMCPY(aes_copy, ctx->aes_encrypt, sizeof(Aes)); /* OFB uses the same - * schedule for encrypt - * and decrypt. - */ err = wc_AesSetIV(aes_copy, walk.iv); @@ -3118,10 +3138,10 @@ static int linuxkm_test_aescbc(void) } req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES skcipher request %s failed\n", WOLFKM_AESCBC_DRIVER); - req = NULL; goto test_cbc_end; } @@ -3320,10 +3340,10 @@ static int linuxkm_test_aescfb(void) } req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES skcipher request %s failed\n", WOLFKM_AESCFB_DRIVER); - req = NULL; goto test_cfb_end; } @@ -3586,10 +3606,10 @@ static int linuxkm_test_aesgcm(void) } req = aead_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES aead request %s failed: %ld\n", WOLFKM_AESCBC_DRIVER, PTR_ERR(req)); - req = NULL; goto test_gcm_end; } @@ -4209,11 +4229,10 @@ static int aes_xts_128_test(void) } req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { - ret = PTR_ERR(req); + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES skcipher request %s failed: %d\n", WOLFKM_AESXTS_DRIVER, ret); - req = NULL; goto test_xts_end; } @@ -4690,11 +4709,10 @@ static int aes_xts_256_test(void) } req = skcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { - ret = PTR_ERR(req); + if (! req) { + ret = -ENOMEM; pr_err("error: allocating AES skcipher request %s failed: %d\n", WOLFKM_AESXTS_DRIVER, ret); - req = NULL; goto test_xts_end; } diff --git a/linuxkm/lkcapi_dh_glue.c b/linuxkm/lkcapi_dh_glue.c index 581776b230..cc4dc8781e 100644 --- a/linuxkm/lkcapi_dh_glue.c +++ b/linuxkm/lkcapi_dh_glue.c @@ -356,6 +356,14 @@ static int km_dh_decode_secret(const u8 * buf, unsigned int len, return -EINVAL; } + if (len != expected_len) { + #ifdef WOLFKM_DEBUG_DH + pr_err("%s: km_dh_decode_secret: caller passed %u, expected %zu\n", + WOLFKM_DH_DRIVER, len, expected_len); + #endif /* WOLFKM_DEBUG_DH */ + return -EINVAL; + } + /* The rest of the fields are optional depending on how much data * was passed, and whether it's ffdhe or dh. */ if (params->key_size) { @@ -779,6 +787,7 @@ 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; @@ -2878,14 +2887,10 @@ static int linuxkm_test_kpp_driver(const char * driver, } req = kpp_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + test_rc = -ENOMEM; pr_err("error: allocating kpp request %s failed\n", driver); - if (PTR_ERR(req) == -ENOMEM) - test_rc = MEMORY_E; - else - test_rc = BAD_FUNC_ARG; - req = NULL; goto test_kpp_end; } diff --git a/linuxkm/lkcapi_ecdh_glue.c b/linuxkm/lkcapi_ecdh_glue.c index 24755917a5..be1186b060 100644 --- a/linuxkm/lkcapi_ecdh_glue.c +++ b/linuxkm/lkcapi_ecdh_glue.c @@ -210,6 +210,14 @@ static int km_ecdh_decode_secret(const u8 * buf, unsigned int len, return -EINVAL; } + if (len != expected_len) { + #ifdef WOLFKM_DEBUG_ECDH + pr_err("%s: km_ecdh_decode_secret: caller passed %u, expected %zu\n", + WOLFKM_ECDH_DRIVER, len, expected_len); + #endif /* WOLFKM_DEBUG_ECDH */ + return -EINVAL; + } + /* Only set the key if it was provided. */ if (params->key_size) { params->key = (void *)ptr; @@ -415,6 +423,7 @@ static int km_ecdh_init(struct crypto_kpp *tfm, int curve_id) #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; @@ -492,6 +501,7 @@ static int km_ecdh_gen_pub(struct kpp_request *req) pr_err("error: dst_len too small: %d\n", req->dst_len); #endif /* WOLFKM_DEBUG_ECDH */ err = -EOVERFLOW; + req->dst_len = raw_pub_len; goto ecdh_gen_pub_end; } @@ -649,6 +659,7 @@ static int km_ecdh_compute_shared_secret(struct kpp_request *req) if (req->dst_len < shared_secret_len) { err = -EOVERFLOW; + req->dst_len = shared_secret_len; goto ecdh_shared_secret_end; } @@ -905,14 +916,10 @@ static int linuxkm_test_ecdh_nist_driver(const char * driver, } req = kpp_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + test_rc = -ENOMEM; pr_err("error: allocating kpp request %s failed\n", driver); - if (PTR_ERR(req) == -ENOMEM) - test_rc = MEMORY_E; - else - test_rc = BAD_FUNC_ARG; - req = NULL; goto test_ecdh_nist_end; } diff --git a/linuxkm/lkcapi_ecdsa_glue.c b/linuxkm/lkcapi_ecdsa_glue.c index 13a0e90be5..62e2eca120 100644 --- a/linuxkm/lkcapi_ecdsa_glue.c +++ b/linuxkm/lkcapi_ecdsa_glue.c @@ -763,14 +763,10 @@ static int linuxkm_test_ecdsa_nist_driver(const char * driver, } req = akcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + test_rc = -ENOMEM; pr_err("error: allocating akcipher request %s failed\n", driver); - if (PTR_ERR(req) == -ENOMEM) - test_rc = MEMORY_E; - else - test_rc = BAD_FUNC_ARG; - req = NULL; goto test_ecdsa_nist_end; } diff --git a/linuxkm/lkcapi_rsa_glue.c b/linuxkm/lkcapi_rsa_glue.c index ac7f8ff5c7..4fb126605d 100644 --- a/linuxkm/lkcapi_rsa_glue.c +++ b/linuxkm/lkcapi_rsa_glue.c @@ -792,8 +792,12 @@ static int km_direct_rsa_dec(struct akcipher_request *req) goto rsa_dec_out; } - if (req->dst_len <= 0 || req->dst_len > (unsigned int) ctx->key_len) { - err = -EINVAL; + if (req->dst_len != (unsigned int)ctx->key_len) { + if ((req->dst_len > 0) && (req->dst_len < (unsigned int)ctx->key_len)) + err = -EOVERFLOW; + else + err = -EINVAL; + req->dst_len = ctx->key_len; goto rsa_dec_out; } @@ -832,6 +836,7 @@ static int km_direct_rsa_dec(struct akcipher_request *req) if (out_len > req->dst_len) { err = -EOVERFLOW; + req->dst_len = out_len; goto rsa_dec_out; } @@ -1121,6 +1126,7 @@ static int km_pkcs1pad_sign(struct akcipher_request *req) if (req->dst_len < ctx->key_len) { err = -EOVERFLOW; + req->dst_len = ctx->key_len; goto pkcs1pad_sign_out; } @@ -1276,7 +1282,7 @@ static int km_pkcs1pad_verify(struct akcipher_request *req) goto pkcs1pad_verify_out; } - n_diff = memcmp(sig, msg, dec_len); + n_diff = ConstantCompare(sig, msg, dec_len); if (unlikely(n_diff != 0)) { err = -EKEYREJECTED; goto pkcs1pad_verify_out; @@ -1523,7 +1529,7 @@ static int km_pkcs1_verify(struct crypto_sig *tfm, goto pkcs1_verify_out; } - n_diff = memcmp(enc_digest, msg, enc_msg_len); + n_diff = ConstantCompare(enc_digest, msg, enc_msg_len); if (unlikely(n_diff != 0)) { #ifdef WOLFKM_DEBUG_RSA pr_err("error: %s: recovered msg did not match digest: %d\n", @@ -1688,6 +1694,7 @@ static int km_pkcs1pad_enc(struct akcipher_request *req) if (req->dst_len < ctx->key_len) { err = -EOVERFLOW; + req->dst_len = ctx->key_len; goto pkcs1_enc_out; } @@ -1806,6 +1813,7 @@ static int km_pkcs1pad_dec(struct akcipher_request *req) if (dec_len > req->dst_len) { err = -EOVERFLOW; + req->dst_len = dec_len; goto pkcs1_dec_out; } @@ -2267,10 +2275,10 @@ static int linuxkm_test_rsa_driver(const char * driver, int nbits) } req = akcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + ret = -ENOMEM; pr_err("error: allocating akcipher request %s failed\n", driver); - req = NULL; goto test_rsa_end; } @@ -2694,14 +2702,10 @@ static int linuxkm_test_pkcs1pad_driver(const char * driver, int nbits, } req = akcipher_request_alloc(tfm, GFP_KERNEL); - if (IS_ERR(req)) { + if (! req) { + test_rc = -ENOMEM; pr_err("error: allocating akcipher request %s failed\n", driver); - if (PTR_ERR(req) == -ENOMEM) - test_rc = MEMORY_E; - else - test_rc = BAD_FUNC_ARG; - req = NULL; goto test_pkcs1_end; }