Merge pull request #10658 from douzzer/20260608-linuxkm-fenrir

20260608-linuxkm-fenrir
This commit is contained in:
philljj
2026-06-11 11:19:46 -05:00
committed by GitHub
7 changed files with 114 additions and 84 deletions
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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)
+69 -51
View File
@@ -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;
}
+11 -6
View File
@@ -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;
}
+13 -6
View File
@@ -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;
}
+2 -6
View File
@@ -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;
}
+16 -12
View File
@@ -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;
}