diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-03 11:28:38 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2025-12-03 11:28:38 -0800 |
| commit | a619fe35ab41fded440d3762d4fbad84ff86a4d4 (patch) | |
| tree | 2cc42a8bb9ec80f7850059c5cab383233c804957 /crypto | |
| parent | c8321831480d80af01ce001bd6626fc130fd13b1 (diff) | |
| parent | 48bc9da3c97c15f1ea24934bcb3b736acd30163d (diff) | |
Merge tag 'v6.19-p1' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto updates from Herbert Xu:
"API:
- Rewrite memcpy_sglist from scratch
- Add on-stack AEAD request allocation
- Fix partial block processing in ahash
Algorithms:
- Remove ansi_cprng
- Remove tcrypt tests for poly1305
- Fix EINPROGRESS processing in authenc
- Fix double-free in zstd
Drivers:
- Use drbg ctr helper when reseeding xilinx-trng
- Add support for PCI device 0x115A to ccp
- Add support of paes in caam
- Add support for aes-xts in dthev2
Others:
- Use likely in rhashtable lookup
- Fix lockdep false-positive in padata by removing a helper"
* tag 'v6.19-p1' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (71 commits)
crypto: zstd - fix double-free in per-CPU stream cleanup
crypto: ahash - Zero positive err value in ahash_update_finish
crypto: ahash - Fix crypto_ahash_import with partial block data
crypto: lib/mpi - use min() instead of min_t()
crypto: ccp - use min() instead of min_t()
hwrng: core - use min3() instead of nested min_t()
crypto: aesni - ctr_crypt() use min() instead of min_t()
crypto: drbg - Delete unused ctx from struct sdesc
crypto: testmgr - Add missing DES weak and semi-weak key tests
Revert "crypto: scatterwalk - Move skcipher walk and use it for memcpy_sglist"
crypto: scatterwalk - Fix memcpy_sglist() to always succeed
crypto: iaa - Request to add Kanchana P Sridhar to Maintainers.
crypto: tcrypt - Remove unused poly1305 support
crypto: ansi_cprng - Remove unused ansi_cprng algorithm
crypto: asymmetric_keys - fix uninitialized pointers with free attribute
KEYS: Avoid -Wflex-array-member-not-at-end warning
crypto: ccree - Correctly handle return of sg_nents_for_len
crypto: starfive - Correctly handle return of sg_nents_for_len
crypto: iaa - Fix incorrect return value in save_iaa_wq()
crypto: zstd - Remove unnecessary size_t cast
...
Diffstat (limited to 'crypto')
| -rw-r--r-- | crypto/Kconfig | 21 | ||||
| -rw-r--r-- | crypto/Makefile | 3 | ||||
| -rw-r--r-- | crypto/aead.c | 20 | ||||
| -rw-r--r-- | crypto/af_alg.c | 5 | ||||
| -rw-r--r-- | crypto/ahash.c | 18 | ||||
| -rw-r--r-- | crypto/algif_hash.c | 3 | ||||
| -rw-r--r-- | crypto/algif_rng.c | 3 | ||||
| -rw-r--r-- | crypto/ansi_cprng.c | 474 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/asymmetric_type.c | 14 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/restrict.c | 7 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/x509_cert_parser.c | 2 | ||||
| -rw-r--r-- | crypto/asymmetric_keys/x509_public_key.c | 2 | ||||
| -rw-r--r-- | crypto/authenc.c | 75 | ||||
| -rw-r--r-- | crypto/deflate.c | 3 | ||||
| -rw-r--r-- | crypto/df_sp80090a.c | 232 | ||||
| -rw-r--r-- | crypto/drbg.c | 266 | ||||
| -rw-r--r-- | crypto/fips.c | 5 | ||||
| -rw-r--r-- | crypto/scatterwalk.c | 345 | ||||
| -rw-r--r-- | crypto/skcipher.c | 261 | ||||
| -rw-r--r-- | crypto/tcrypt.c | 8 | ||||
| -rw-r--r-- | crypto/tcrypt.h | 18 | ||||
| -rw-r--r-- | crypto/testmgr.c | 97 | ||||
| -rw-r--r-- | crypto/testmgr.h | 226 | ||||
| -rw-r--r-- | crypto/zstd.c | 17 |
24 files changed, 832 insertions, 1293 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index bf8b8a60a0c0..2e5b195b1b06 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -25,7 +25,7 @@ menu "Crypto core or helper" config CRYPTO_FIPS bool "FIPS 200 compliance" - depends on (CRYPTO_ANSI_CPRNG || CRYPTO_DRBG) && CRYPTO_SELFTESTS + depends on CRYPTO_DRBG && CRYPTO_SELFTESTS depends on (MODULE_SIG || !MODULES) help This option enables the fips boot option which is @@ -1161,17 +1161,6 @@ endmenu menu "Random number generation" -config CRYPTO_ANSI_CPRNG - tristate "ANSI PRNG (Pseudo Random Number Generator)" - select CRYPTO_AES - select CRYPTO_RNG - help - Pseudo RNG (random number generator) (ANSI X9.31 Appendix A.2.4) - - This uses the AES cipher algorithm. - - Note that this option must be enabled if CRYPTO_FIPS is selected - menuconfig CRYPTO_DRBG_MENU tristate "NIST SP800-90A DRBG (Deterministic Random Bit Generator)" help @@ -1197,8 +1186,7 @@ config CRYPTO_DRBG_HASH config CRYPTO_DRBG_CTR bool "CTR_DRBG" - select CRYPTO_AES - select CRYPTO_CTR + select CRYPTO_DF80090A help CTR_DRBG variant as defined in NIST SP800-90A. @@ -1334,6 +1322,11 @@ config CRYPTO_KDF800108_CTR select CRYPTO_HMAC select CRYPTO_SHA256 +config CRYPTO_DF80090A + tristate + select CRYPTO_AES + select CRYPTO_CTR + endmenu menu "Userspace interface" diff --git a/crypto/Makefile b/crypto/Makefile index 093c56a45d3f..16a35649dd91 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -162,7 +162,6 @@ obj-$(CONFIG_CRYPTO_LZ4HC) += lz4hc.o obj-$(CONFIG_CRYPTO_XXHASH) += xxhash_generic.o obj-$(CONFIG_CRYPTO_842) += 842.o obj-$(CONFIG_CRYPTO_RNG2) += rng.o -obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o obj-$(CONFIG_CRYPTO_DRBG) += drbg.o obj-$(CONFIG_CRYPTO_JITTERENTROPY) += jitterentropy_rng.o CFLAGS_jitterentropy.o = -O0 @@ -207,4 +206,6 @@ obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o # obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o +obj-$(CONFIG_CRYPTO_DF80090A) += df_sp80090a.o + obj-$(CONFIG_CRYPTO_KRB5) += krb5/ diff --git a/crypto/aead.c b/crypto/aead.c index 5d14b775036e..08d44c5e5c33 100644 --- a/crypto/aead.c +++ b/crypto/aead.c @@ -120,6 +120,7 @@ static int crypto_aead_init_tfm(struct crypto_tfm *tfm) struct aead_alg *alg = crypto_aead_alg(aead); crypto_aead_set_flags(aead, CRYPTO_TFM_NEED_KEY); + crypto_aead_set_reqsize(aead, crypto_tfm_alg_reqsize(tfm)); aead->authsize = alg->maxauthsize; @@ -204,6 +205,25 @@ struct crypto_aead *crypto_alloc_aead(const char *alg_name, u32 type, u32 mask) } EXPORT_SYMBOL_GPL(crypto_alloc_aead); +struct crypto_sync_aead *crypto_alloc_sync_aead(const char *alg_name, u32 type, u32 mask) +{ + struct crypto_aead *tfm; + + /* Only sync algorithms are allowed. */ + mask |= CRYPTO_ALG_ASYNC; + type &= ~(CRYPTO_ALG_ASYNC); + + tfm = crypto_alloc_tfm(alg_name, &crypto_aead_type, type, mask); + + if (!IS_ERR(tfm) && WARN_ON(crypto_aead_reqsize(tfm) > MAX_SYNC_AEAD_REQSIZE)) { + crypto_free_aead(tfm); + return ERR_PTR(-EINVAL); + } + + return (struct crypto_sync_aead *)tfm; +} +EXPORT_SYMBOL_GPL(crypto_alloc_sync_aead); + int crypto_has_aead(const char *alg_name, u32 type, u32 mask) { return crypto_type_has_alg(alg_name, &crypto_aead_type, type, mask); diff --git a/crypto/af_alg.c b/crypto/af_alg.c index ca6fdcc6c54a..6c271e55f44d 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -1212,15 +1212,14 @@ struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, if (unlikely(!areq)) return ERR_PTR(-ENOMEM); + memset(areq, 0, areqlen); + ctx->inflight = true; areq->areqlen = areqlen; areq->sk = sk; areq->first_rsgl.sgl.sgt.sgl = areq->first_rsgl.sgl.sgl; - areq->last_rsgl = NULL; INIT_LIST_HEAD(&areq->rsgl_list); - areq->tsgl = NULL; - areq->tsgl_entries = 0; return areq; } diff --git a/crypto/ahash.c b/crypto/ahash.c index dfb4f5476428..66492ae75fcf 100644 --- a/crypto/ahash.c +++ b/crypto/ahash.c @@ -423,7 +423,11 @@ static int ahash_update_finish(struct ahash_request *req, int err) req->nbytes += nonzero - blen; - blen = err < 0 ? 0 : err + nonzero; + blen = 0; + if (err >= 0) { + blen = err + nonzero; + err = 0; + } if (ahash_request_isvirt(req)) memcpy(buf, req->svirt + req->nbytes - blen, blen); else @@ -661,6 +665,12 @@ int crypto_ahash_import_core(struct ahash_request *req, const void *in) in); if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) return -ENOKEY; + if (crypto_ahash_block_only(tfm)) { + unsigned int reqsize = crypto_ahash_reqsize(tfm); + u8 *buf = ahash_request_ctx(req); + + buf[reqsize - 1] = 0; + } return crypto_ahash_alg(tfm)->import_core(req, in); } EXPORT_SYMBOL_GPL(crypto_ahash_import_core); @@ -674,10 +684,14 @@ int crypto_ahash_import(struct ahash_request *req, const void *in) if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) return -ENOKEY; if (crypto_ahash_block_only(tfm)) { + unsigned int plen = crypto_ahash_blocksize(tfm) + 1; unsigned int reqsize = crypto_ahash_reqsize(tfm); + unsigned int ss = crypto_ahash_statesize(tfm); u8 *buf = ahash_request_ctx(req); - buf[reqsize - 1] = 0; + memcpy(buf + reqsize - plen, in + ss - plen, plen); + if (buf[reqsize - 1] >= plen) + return -EOVERFLOW; } return crypto_ahash_alg(tfm)->import(req, in); } diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index e3f1a4852737..4d3dfc60a16a 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -416,9 +416,8 @@ static int hash_accept_parent_nokey(void *private, struct sock *sk) if (!ctx) return -ENOMEM; - ctx->result = NULL; + memset(ctx, 0, len); ctx->len = len; - ctx->more = false; crypto_init_wait(&ctx->wait); ask->private = ctx; diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c index 10c41adac3b1..1a86e40c8372 100644 --- a/crypto/algif_rng.c +++ b/crypto/algif_rng.c @@ -248,9 +248,8 @@ static int rng_accept_parent(void *private, struct sock *sk) if (!ctx) return -ENOMEM; + memset(ctx, 0, len); ctx->len = len; - ctx->addtl = NULL; - ctx->addtl_len = 0; /* * No seeding done at that point -- if multiple accepts are diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c deleted file mode 100644 index 153523ce6076..000000000000 --- a/crypto/ansi_cprng.c +++ /dev/null @@ -1,474 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * PRNG: Pseudo Random Number Generator - * Based on NIST Recommended PRNG From ANSI X9.31 Appendix A.2.4 using - * AES 128 cipher - * - * (C) Neil Horman <nhorman@tuxdriver.com> - */ - -#include <crypto/internal/cipher.h> -#include <crypto/internal/rng.h> -#include <linux/err.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/string.h> - -#define DEFAULT_PRNG_KEY "0123456789abcdef" -#define DEFAULT_PRNG_KSZ 16 -#define DEFAULT_BLK_SZ 16 -#define DEFAULT_V_SEED "zaybxcwdveuftgsh" - -/* - * Flags for the prng_context flags field - */ - -#define PRNG_FIXED_SIZE 0x1 -#define PRNG_NEED_RESET 0x2 - -/* - * Note: DT is our counter value - * I is our intermediate value - * V is our seed vector - * See http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf - * for implementation details - */ - - -struct prng_context { - spinlock_t prng_lock; - unsigned char rand_data[DEFAULT_BLK_SZ]; - unsigned char last_rand_data[DEFAULT_BLK_SZ]; - unsigned char DT[DEFAULT_BLK_SZ]; - unsigned char I[DEFAULT_BLK_SZ]; - unsigned char V[DEFAULT_BLK_SZ]; - u32 rand_data_valid; - struct crypto_cipher *tfm; - u32 flags; -}; - -static int dbg; - -static void hexdump(char *note, unsigned char *buf, unsigned int len) -{ - if (dbg) { - printk(KERN_CRIT "%s", note); - print_hex_dump(KERN_CONT, "", DUMP_PREFIX_OFFSET, - 16, 1, - buf, len, false); - } -} - -#define dbgprint(format, args...) do {\ -if (dbg)\ - printk(format, ##args);\ -} while (0) - -static void xor_vectors(unsigned char *in1, unsigned char *in2, - unsigned char *out, unsigned int size) -{ - int i; - - for (i = 0; i < size; i++) - out[i] = in1[i] ^ in2[i]; - -} -/* - * Returns DEFAULT_BLK_SZ bytes of random data per call - * returns 0 if generation succeeded, <0 if something went wrong - */ -static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test) -{ - int i; - unsigned char tmp[DEFAULT_BLK_SZ]; - unsigned char *output = NULL; - - - dbgprint(KERN_CRIT "Calling _get_more_prng_bytes for context %p\n", - ctx); - - hexdump("Input DT: ", ctx->DT, DEFAULT_BLK_SZ); - hexdump("Input I: ", ctx->I, DEFAULT_BLK_SZ); - hexdump("Input V: ", ctx->V, DEFAULT_BLK_SZ); - - /* - * This algorithm is a 3 stage state machine - */ - for (i = 0; i < 3; i++) { - - switch (i) { - case 0: - /* - * Start by encrypting the counter value - * This gives us an intermediate value I - */ - memcpy(tmp, ctx->DT, DEFAULT_BLK_SZ); - output = ctx->I; - hexdump("tmp stage 0: ", tmp, DEFAULT_BLK_SZ); - break; - case 1: - - /* - * Next xor I with our secret vector V - * encrypt that result to obtain our - * pseudo random data which we output - */ - xor_vectors(ctx->I, ctx->V, tmp, DEFAULT_BLK_SZ); - hexdump("tmp stage 1: ", tmp, DEFAULT_BLK_SZ); - output = ctx->rand_data; - break; - case 2: - /* - * First check that we didn't produce the same - * random data that we did last time around through this - */ - if (!memcmp(ctx->rand_data, ctx->last_rand_data, - DEFAULT_BLK_SZ)) { - if (cont_test) { - panic("cprng %p Failed repetition check!\n", - ctx); - } - - printk(KERN_ERR - "ctx %p Failed repetition check!\n", - ctx); - - ctx->flags |= PRNG_NEED_RESET; - return -EINVAL; - } - memcpy(ctx->last_rand_data, ctx->rand_data, - DEFAULT_BLK_SZ); - - /* - * Lastly xor the random data with I - * and encrypt that to obtain a new secret vector V - */ - xor_vectors(ctx->rand_data, ctx->I, tmp, - DEFAULT_BLK_SZ); - output = ctx->V; - hexdump("tmp stage 2: ", tmp, DEFAULT_BLK_SZ); - break; - } - - - /* do the encryption */ - crypto_cipher_encrypt_one(ctx->tfm, output, tmp); - - } - - /* - * Now update our DT value - */ - for (i = DEFAULT_BLK_SZ - 1; i >= 0; i--) { - ctx->DT[i] += 1; - if (ctx->DT[i] != 0) - break; - } - - dbgprint("Returning new block for context %p\n", ctx); - ctx->rand_data_valid = 0; - - hexdump("Output DT: ", ctx->DT, DEFAULT_BLK_SZ); - hexdump("Output I: ", ctx->I, DEFAULT_BLK_SZ); - hexdump("Output V: ", ctx->V, DEFAULT_BLK_SZ); - hexdump("New Random Data: ", ctx->rand_data, DEFAULT_BLK_SZ); - - return 0; -} - -/* Our exported functions */ -static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx, - int do_cont_test) -{ - unsigned char *ptr = buf; - unsigned int byte_count = (unsigned int)nbytes; - int err; - - - spin_lock_bh(&ctx->prng_lock); - - err = -EINVAL; - if (ctx->flags & PRNG_NEED_RESET) - goto done; - - /* - * If the FIXED_SIZE flag is on, only return whole blocks of - * pseudo random data - */ - err = -EINVAL; - if (ctx->flags & PRNG_FIXED_SIZE) { - if (nbytes < DEFAULT_BLK_SZ) - goto done; - byte_count = DEFAULT_BLK_SZ; - } - - /* - * Return 0 in case of success as mandated by the kernel - * crypto API interface definition. - */ - err = 0; - - dbgprint(KERN_CRIT "getting %d random bytes for context %p\n", - byte_count, ctx); - - -remainder: - if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { - if (_get_more_prng_bytes(ctx, do_cont_test) < 0) { - memset(buf, 0, nbytes); - err = -EINVAL; - goto done; - } - } - - /* - * Copy any data less than an entire block - */ - if (byte_count < DEFAULT_BLK_SZ) { -empty_rbuf: - while (ctx->rand_data_valid < DEFAULT_BLK_SZ) { - *ptr = ctx->rand_data[ctx->rand_data_valid]; - ptr++; - byte_count--; - ctx->rand_data_valid++; - if (byte_count == 0) - goto done; - } - } - - /* - * Now copy whole blocks - */ - for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) { - if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { - if (_get_more_prng_bytes(ctx, do_cont_test) < 0) { - memset(buf, 0, nbytes); - err = -EINVAL; - goto done; - } - } - if (ctx->rand_data_valid > 0) - goto empty_rbuf; - memcpy(ptr, ctx->rand_data, DEFAULT_BLK_SZ); - ctx->rand_data_valid += DEFAULT_BLK_SZ; - ptr += DEFAULT_BLK_SZ; - } - - /* - * Now go back and get any remaining partial block - */ - if (byte_count) - goto remainder; - -done: - spin_unlock_bh(&ctx->prng_lock); - dbgprint(KERN_CRIT "returning %d from get_prng_bytes in context %p\n", - err, ctx); - return err; -} - -static void free_prng_context(struct prng_context *ctx) -{ - crypto_free_cipher(ctx->tfm); -} - -static int reset_prng_context(struct prng_context *ctx, - const unsigned char *key, size_t klen, - const unsigned char *V, const unsigned char *DT) -{ - int ret; - const unsigned char *prng_key; - - spin_lock_bh(&ctx->prng_lock); - ctx->flags |= PRNG_NEED_RESET; - - prng_key = (key != NULL) ? key : (unsigned char *)DEFAULT_PRNG_KEY; - - if (!key) - klen = DEFAULT_PRNG_KSZ; - - if (V) - memcpy(ctx->V, V, DEFAULT_BLK_SZ); - else - memcpy(ctx->V, DEFAULT_V_SEED, DEFAULT_BLK_SZ); - - if (DT) - memcpy(ctx->DT, DT, DEFAULT_BLK_SZ); - else - memset(ctx->DT, 0, DEFAULT_BLK_SZ); - - memset(ctx->rand_data, 0, DEFAULT_BLK_SZ); - memset(ctx->last_rand_data, 0, DEFAULT_BLK_SZ); - - ctx->rand_data_valid = DEFAULT_BLK_SZ; - - ret = crypto_cipher_setkey(ctx->tfm, prng_key, klen); - if (ret) { - dbgprint(KERN_CRIT "PRNG: setkey() failed flags=%x\n", - crypto_cipher_get_flags(ctx->tfm)); - goto out; - } - - ret = 0; - ctx->flags &= ~PRNG_NEED_RESET; -out: - spin_unlock_bh(&ctx->prng_lock); - return ret; -} - -static int cprng_init(struct crypto_tfm *tfm) -{ - struct prng_context *ctx = crypto_tfm_ctx(tfm); - - spin_lock_init(&ctx->prng_lock); - ctx->tfm = crypto_alloc_cipher("aes", 0, 0); - if (IS_ERR(ctx->tfm)) { - dbgprint(KERN_CRIT "Failed to alloc tfm for context %p\n", - ctx); - return PTR_ERR(ctx->tfm); - } - - if (reset_prng_context(ctx, NULL, DEFAULT_PRNG_KSZ, NULL, NULL) < 0) - return -EINVAL; - - /* - * after allocation, we should always force the user to reset - * so they don't inadvertently use the insecure default values - * without specifying them intentially - */ - ctx->flags |= PRNG_NEED_RESET; - return 0; -} - -static void cprng_exit(struct crypto_tfm *tfm) -{ - free_prng_context(crypto_tfm_ctx(tfm)); -} - -static int cprng_get_random(struct crypto_rng *tfm, - const u8 *src, unsigned int slen, - u8 *rdata, unsigned int dlen) -{ - struct prng_context *prng = crypto_rng_ctx(tfm); - - return get_prng_bytes(rdata, dlen, prng, 0); -} - -/* - * This is the cprng_registered reset method the seed value is - * interpreted as the tuple { V KEY DT} - * V and KEY are required during reset, and DT is optional, detected - * as being present by testing the length of the seed - */ -static int cprng_reset(struct crypto_rng *tfm, - const u8 *seed, unsigned int slen) -{ - struct prng_context *prng = crypto_rng_ctx(tfm); - const u8 *key = seed + DEFAULT_BLK_SZ; - const u8 *dt = NULL; - - if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ) - return -EINVAL; - - if (slen >= (2 * DEFAULT_BLK_SZ + DEFAULT_PRNG_KSZ)) - dt = key + DEFAULT_PRNG_KSZ; - - reset_prng_context(prng, key, DEFAULT_PRNG_KSZ, seed, dt); - - if (prng->flags & PRNG_NEED_RESET) - return -EINVAL; - return 0; -} - -#ifdef CONFIG_CRYPTO_FIPS -static int fips_cprng_get_random(struct crypto_rng *tfm, - const u8 *src, unsigned int slen, - u8 *rdata, unsigned int dlen) -{ - struct prng_context *prng = crypto_rng_ctx(tfm); - - return get_prng_bytes(rdata, dlen, prng, 1); -} - -static int fips_cprng_reset(struct crypto_rng *tfm, - const u8 *seed, unsigned int slen) -{ - u8 rdata[DEFAULT_BLK_SZ]; - const u8 *key = seed + DEFAULT_BLK_SZ; - int rc; - - struct prng_context *prng = crypto_rng_ctx(tfm); - - if (slen < DEFAULT_PRNG_KSZ + DEFAULT_BLK_SZ) - return -EINVAL; - - /* fips strictly requires seed != key */ - if (!memcmp(seed, key, DEFAULT_PRNG_KSZ)) - return -EINVAL; - - rc = cprng_reset(tfm, seed, slen); - - if (!rc) - goto out; - - /* this primes our continuity test */ - rc = get_prng_bytes(rdata, DEFAULT_BLK_SZ, prng, 0); - prng->rand_data_valid = DEFAULT_BLK_SZ; - -out: - return rc; -} -#endif - -static struct rng_alg rng_algs[] = { { - .generate = cprng_get_random, - .seed = cprng_reset, - .seedsize = DEFAULT_PRNG_KSZ + 2 * DEFAULT_BLK_SZ, - .base = { - .cra_name = "stdrng", - .cra_driver_name = "ansi_cprng", - .cra_priority = 100, - .cra_ctxsize = sizeof(struct prng_context), - .cra_module = THIS_MODULE, - .cra_init = cprng_init, - .cra_exit = cprng_exit, - } -#ifdef CONFIG_CRYPTO_FIPS -}, { - .generate = fips_cprng_get_random, - .seed = fips_cprng_reset, - .seedsize = DEFAULT_PRNG_KSZ + 2 * DEFAULT_BLK_SZ, - .base = { - .cra_name = "fips(ansi_cprng)", - .cra_driver_name = "fips_ansi_cprng", - .cra_priority = 300, - .cra_ctxsize = sizeof(struct prng_context), - .cra_module = THIS_MODULE, - .cra_init = cprng_init, - .cra_exit = cprng_exit, - } -#endif -} }; - -/* Module initalization */ -static int __init prng_mod_init(void) -{ - return crypto_register_rngs(rng_algs, ARRAY_SIZE(rng_algs)); -} - -static void __exit prng_mod_fini(void) -{ - crypto_unregister_rngs(rng_algs, ARRAY_SIZE(rng_algs)); -} - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Software Pseudo Random Number Generator"); -MODULE_AUTHOR("Neil Horman <nhorman@tuxdriver.com>"); -module_param(dbg, int, 0); -MODULE_PARM_DESC(dbg, "Boolean to enable debugging (0/1 == off/on)"); -module_init(prng_mod_init); -module_exit(prng_mod_fini); -MODULE_ALIAS_CRYPTO("stdrng"); -MODULE_ALIAS_CRYPTO("ansi_cprng"); -MODULE_IMPORT_NS("CRYPTO_INTERNAL"); diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c index ba2d9d1ea235..348966ea2175 100644 --- a/crypto/asymmetric_keys/asymmetric_type.c +++ b/crypto/asymmetric_keys/asymmetric_type.c @@ -11,6 +11,7 @@ #include <crypto/public_key.h> #include <linux/seq_file.h> #include <linux/module.h> +#include <linux/overflow.h> #include <linux/slab.h> #include <linux/ctype.h> #include <keys/system_keyring.h> @@ -141,12 +142,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, size_t len_2) { struct asymmetric_key_id *kid; - - kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, - GFP_KERNEL); + size_t kid_sz; + size_t len; + + if (check_add_overflow(len_1, len_2, &len)) + return ERR_PTR(-EOVERFLOW); + if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) + return ERR_PTR(-EOVERFLOW); + kid = kmalloc(kid_sz, GFP_KERNEL); if (!kid) return ERR_PTR(-ENOMEM); - kid->len = len_1 + len_2; + kid->len = len; memcpy(kid->data, val_1, len_1); memcpy(kid->data + len_1, val_2, len_2); return kid; diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c index afcd4d101ac5..86292965f493 100644 --- a/crypto/asymmetric_keys/restrict.c +++ b/crypto/asymmetric_keys/restrict.c @@ -17,9 +17,12 @@ static struct asymmetric_key_id *ca_keyid; #ifndef MODULE static struct { - struct asymmetric_key_id id; - unsigned char data[10]; + /* Must be last as it ends in a flexible-array member. */ + TRAILING_OVERLAP(struct asymmetric_key_id, id, data, + unsigned char data[10]; + ); } cakey; +static_assert(offsetof(typeof(cakey), id.data) == offsetof(typeof(cakey), data)); static int __init ca_keys_setup(char *str) { diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c index 8df3fa60a44f..b37cae914987 100644 --- a/crypto/asymmetric_keys/x509_cert_parser.c +++ b/crypto/asymmetric_keys/x509_cert_parser.c @@ -60,7 +60,7 @@ EXPORT_SYMBOL_GPL(x509_free_certificate); */ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen) { - struct x509_certificate *cert __free(x509_free_certificate); + struct x509_certificate *cert __free(x509_free_certificate) = NULL; struct x509_parse_context *ctx __free(kfree) = NULL; struct asymmetric_key_id *kid; long ret; diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 8409d7d36cb4..12e3341e806b 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -148,7 +148,7 @@ not_self_signed: */ static int x509_key_preparse(struct key_preparsed_payload *prep) { - struct x509_certificate *cert __free(x509_free_certificate); + struct x509_certificate *cert __free(x509_free_certificate) = NULL; struct asymmetric_key_ids *kids __free(kfree) = NULL; char *p, *desc __free(kfree) = NULL; const char *q; diff --git a/crypto/authenc.c b/crypto/authenc.c index a723769c8777..ac679ce2cb95 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -37,7 +37,7 @@ struct authenc_request_ctx { static void authenc_request_complete(struct aead_request *req, int err) { - if (err != -EINPROGRESS) + if (err != -EINPROGRESS && err != -EBUSY) aead_request_complete(req, err); } @@ -107,27 +107,42 @@ out: return err; } -static void authenc_geniv_ahash_done(void *data, int err) +static void authenc_geniv_ahash_finish(struct aead_request *req) { - struct aead_request *req = data; struct crypto_aead *authenc = crypto_aead_reqtfm(req); struct aead_instance *inst = aead_alg_instance(authenc); struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); - if (err) - goto out; - scatterwalk_map_and_copy(ahreq->result, req->dst, req->assoclen + req->cryptlen, crypto_aead_authsize(authenc), 1); +} -out: +static void authenc_geniv_ahash_done(void *data, int err) +{ + struct aead_request *req = data; + + if (!err) + authenc_geniv_ahash_finish(req); aead_request_complete(req, err); } -static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) +/* + * Used when the ahash request was invoked in the async callback context + * of the previous skcipher request. Eat any EINPROGRESS notifications. + */ +static void authenc_geniv_ahash_done2(void *data, int err) +{ + struct aead_request *req = data; + + if (!err) + authenc_geniv_ahash_finish(req); + authenc_request_complete(req, err); +} + +static int crypto_authenc_genicv(struct aead_request *req, unsigned int mask) { struct crypto_aead *authenc = crypto_aead_reqtfm(req); struct aead_instance *inst = aead_alg_instance(authenc); @@ -136,6 +151,7 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) struct crypto_ahash *auth = ctx->auth; struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); + unsigned int flags = aead_request_flags(req) & ~mask; u8 *hash = areq_ctx->tail; int err; @@ -143,7 +159,8 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) ahash_request_set_crypt(ahreq, req->dst, hash, req->assoclen + req->cryptlen); ahash_request_set_callback(ahreq, flags, - authenc_geniv_ahash_done, req); + mask ? authenc_geniv_ahash_done2 : + authenc_geniv_ahash_done, req); err = crypto_ahash_digest(ahreq); if (err) @@ -159,12 +176,11 @@ static void crypto_authenc_encrypt_done(void *data, int err) { struct aead_request *areq = data; - if (err) - goto out; - - err = crypto_authenc_genicv(areq, 0); - -out: + if (err) { + aead_request_complete(areq, err); + return; + } + err = crypto_authenc_genicv(areq, CRYPTO_TFM_REQ_MAY_SLEEP); authenc_request_complete(areq, err); } @@ -199,11 +215,18 @@ static int crypto_authenc_encrypt(struct aead_request *req) if (err) return err; - return crypto_authenc_genicv(req, aead_request_flags(req)); + return crypto_authenc_genicv(req, 0); +} + +static void authenc_decrypt_tail_done(void *data, int err) +{ + struct aead_request *req = data; + + authenc_request_complete(req, err); } static int crypto_authenc_decrypt_tail(struct aead_request *req, - unsigned int flags) + unsigned int mask) { struct crypto_aead *authenc = crypto_aead_reqtfm(req); struct aead_instance *inst = aead_alg_instance(authenc); @@ -214,6 +237,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, struct skcipher_request *skreq = (void *)(areq_ctx->tail + ictx->reqoff); unsigned int authsize = crypto_aead_authsize(authenc); + unsigned int flags = aead_req |
