diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-11 10:21:35 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-11 10:21:35 -0800 |
commit | 5c947d0dbae8038ec1c8b538891f6475350542ee (patch) | |
tree | bd81b14e0cd2212bf885b835d9da39db51a33d43 /crypto | |
parent | 6f38be8f2ccd9babf04b9b23539108542a59fcb8 (diff) | |
parent | 5f21d7d283dd82865bdb0123795b3accf0d42b67 (diff) | |
download | linux-5c947d0dbae8038ec1c8b538891f6475350542ee.tar.gz linux-5c947d0dbae8038ec1c8b538891f6475350542ee.tar.bz2 linux-5c947d0dbae8038ec1c8b538891f6475350542ee.zip |
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto updates from Herbert Xu:
"Algorithms:
- Drop alignment requirement for data in aesni
- Use synchronous seeding from the /dev/random in DRBG
- Reseed nopr DRBGs every 5 minutes from /dev/random
- Add KDF algorithms currently used by security/DH
- Fix lack of entropy on some AMD CPUs with jitter RNG
Drivers:
- Add support for the D1 variant in sun8i-ce
- Add SEV_INIT_EX support in ccp
- PFVF support for GEN4 host driver in qat
- Compression support for GEN4 devices in qat
- Add cn10k random number generator support"
* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (145 commits)
crypto: af_alg - rewrite NULL pointer check
lib/mpi: Add the return value check of kcalloc()
crypto: qat - fix definition of ring reset results
crypto: hisilicon - cleanup warning in qm_get_qos_value()
crypto: kdf - select SHA-256 required for self-test
crypto: x86/aesni - don't require alignment of data
crypto: ccp - remove unneeded semicolon
crypto: stm32/crc32 - Fix kernel BUG triggered in probe()
crypto: s390/sha512 - Use macros instead of direct IV numbers
crypto: sparc/sha - remove duplicate hash init function
crypto: powerpc/sha - remove duplicate hash init function
crypto: mips/sha - remove duplicate hash init function
crypto: sha256 - remove duplicate generic hash init function
crypto: jitter - add oversampling of noise source
MAINTAINERS: update SEC2 driver maintainers list
crypto: ux500 - Use platform_get_irq() to get the interrupt
crypto: hisilicon/qm - disable qm clock-gating
crypto: omap-aes - Fix broken pm_runtime_and_get() usage
MAINTAINERS: update caam crypto driver maintainers list
crypto: octeontx2 - prevent underflow in get_cores_bmap()
...
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/Kconfig | 4 | ||||
-rw-r--r-- | crypto/Makefile | 5 | ||||
-rw-r--r-- | crypto/af_alg.c | 7 | ||||
-rw-r--r-- | crypto/dh.c | 5 | ||||
-rw-r--r-- | crypto/drbg.c | 150 | ||||
-rw-r--r-- | crypto/jitterentropy-kcapi.c | 6 | ||||
-rw-r--r-- | crypto/jitterentropy.c | 32 | ||||
-rw-r--r-- | crypto/jitterentropy.h | 1 | ||||
-rw-r--r-- | crypto/kdf_sp800108.c | 153 | ||||
-rw-r--r-- | crypto/rsa.c | 4 | ||||
-rw-r--r-- | crypto/sha256_generic.c | 16 | ||||
-rw-r--r-- | crypto/testmgr.c | 9 | ||||
-rw-r--r-- | crypto/testmgr.h | 6 |
13 files changed, 280 insertions, 118 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig index 55718de56137..94bfa32cc6a1 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1845,6 +1845,10 @@ config CRYPTO_JITTERENTROPY random numbers. This Jitterentropy RNG registers with the kernel crypto API and can be used by any caller. +config CRYPTO_KDF800108_CTR + tristate + select CRYPTO_SHA256 + config CRYPTO_USER_API tristate diff --git a/crypto/Makefile b/crypto/Makefile index 429c4d57458c..d76bff8d0ffd 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -200,3 +200,8 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/ obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o crypto_simd-y := simd.o obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o + +# +# Key derivation function +# +obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 3dd5a773c320..e1ea18536a5f 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -931,16 +931,19 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size, sg_unmark_end(sg + sgl->cur - 1); do { + struct page *pg; unsigned int i = sgl->cur; plen = min_t(size_t, len, PAGE_SIZE); - sg_assign_page(sg + i, alloc_page(GFP_KERNEL)); - if (!sg_page(sg + i)) { + pg = alloc_page(GFP_KERNEL); + if (!pg) { err = -ENOMEM; goto unlock; } + sg_assign_page(sg + i, pg); + err = memcpy_from_msg(page_address(sg_page(sg + i)), msg, plen); if (err) { diff --git a/crypto/dh.c b/crypto/dh.c index cd4f32092e5c..27e62a2a8027 100644 --- a/crypto/dh.c +++ b/crypto/dh.c @@ -5,11 +5,11 @@ * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com> */ +#include <linux/fips.h> #include <linux/module.h> #include <crypto/internal/kpp.h> #include <crypto/kpp.h> #include <crypto/dh.h> -#include <linux/fips.h> #include <linux/mpi.h> struct dh_ctx { @@ -47,6 +47,9 @@ static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm) static int dh_check_params_length(unsigned int p_len) { + if (fips_enabled) + return (p_len < 2048) ? -EINVAL : 0; + return (p_len < 1536) ? -EINVAL : 0; } diff --git a/crypto/drbg.c b/crypto/drbg.c index f72f340a1321..177983b6ae38 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -100,6 +100,7 @@ #include <crypto/drbg.h> #include <crypto/internal/cipher.h> #include <linux/kernel.h> +#include <linux/jiffies.h> /*************************************************************** * Backend cipher definitions available to DRBG @@ -1036,17 +1037,39 @@ static const struct drbg_state_ops drbg_hash_ops = { ******************************************************************/ static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed, - int reseed) + int reseed, enum drbg_seed_state new_seed_state) { int ret = drbg->d_ops->update(drbg, seed, reseed); if (ret) return ret; - drbg->seeded = true; + drbg->seeded = new_seed_state; + drbg->last_seed_time = jiffies; /* 10.1.1.2 / 10.1.1.3 step 5 */ drbg->reseed_ctr = 1; + switch (drbg->seeded) { + case DRBG_SEED_STATE_UNSEEDED: + /* Impossible, but handle it to silence compiler warnings. */ + fallthrough; + case DRBG_SEED_STATE_PARTIAL: + /* + * Require frequent reseeds until the seed source is + * fully initialized. + */ + drbg->reseed_threshold = 50; + break; + + case DRBG_SEED_STATE_FULL: + /* + * Seed source has become fully initialized, frequent + * reseeds no longer required. + */ + drbg->reseed_threshold = drbg_max_requests(drbg); + break; + } + return ret; } @@ -1066,12 +1089,10 @@ static inline int drbg_get_random_bytes(struct drbg_state *drbg, return 0; } -static void drbg_async_seed(struct work_struct *work) +static int drbg_seed_from_random(struct drbg_state *drbg) { struct drbg_string data; LIST_HEAD(seedlist); - struct drbg_state *drbg = container_of(work, struct drbg_state, - seed_work); unsigned int entropylen = drbg_sec_strength(drbg->core->flags); unsigned char entropy[32]; int ret; @@ -1082,26 +1103,35 @@ static void drbg_async_seed(struct work_struct *work) drbg_string_fill(&data, entropy, entropylen); list_add_tail(&data.list, &seedlist); - mutex_lock(&drbg->drbg_mutex); - ret = drbg_get_random_bytes(drbg, entropy, entropylen); if (ret) - goto unlock; + goto out; - /* Set seeded to false so that if __drbg_seed fails the - * next generate call will trigger a reseed. - */ - drbg->seeded = false; + ret = __drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL); - __drbg_seed(drbg, &seedlist, true); +out: + memzero_explicit(entropy, entropylen); + return ret; +} - if (drbg->seeded) - drbg->reseed_threshold = drbg_max_requests(drbg); +static bool drbg_nopr_reseed_interval_elapsed(struct drbg_state *drbg) +{ + unsigned long next_reseed; -unlock: - mutex_unlock(&drbg->drbg_mutex); + /* Don't ever reseed from get_random_bytes() in test mode. */ + if (list_empty(&drbg->test_data.list)) + return false; - memzero_explicit(entropy, entropylen); + /* + * Obtain fresh entropy for the nopr DRBGs after 300s have + * elapsed in order to still achieve sort of partial + * prediction resistance over the time domain at least. Note + * that the period of 300s has been chosen to match the + * CRNG_RESEED_INTERVAL of the get_random_bytes()' chacha + * rngs. + */ + next_reseed = drbg->last_seed_time + 300 * HZ; + return time_after(jiffies, next_reseed); } /* @@ -1123,6 +1153,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, unsigned int entropylen = drbg_sec_strength(drbg->core->flags); struct drbg_string data1; LIST_HEAD(seedlist); + enum drbg_seed_state new_seed_state = DRBG_SEED_STATE_FULL; /* 9.1 / 9.2 / 9.3.1 step 3 */ if (pers && pers->len > (drbg_max_addtl(drbg))) { @@ -1150,6 +1181,9 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, BUG_ON((entropylen * 2) > sizeof(entropy)); /* Get seed from in-kernel /dev/urandom */ + if (!rng_is_initialized()) + new_seed_state = DRBG_SEED_STATE_PARTIAL; + ret = drbg_get_random_bytes(drbg, entropy, entropylen); if (ret) goto out; @@ -1159,11 +1193,14 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, pr_devel("DRBG: (re)seeding with %u bytes of entropy\n", entropylen); } else { - /* Get seed from Jitter RNG */ + /* + * Get seed from Jitter RNG, failures are + * fatal only in FIPS mode. + */ ret = crypto_rng_get_bytes(drbg->jent, entropy + entropylen, entropylen); - if (ret) { + if (fips_enabled && ret) { pr_devel("DRBG: jent failed with %d\n", ret); /* @@ -1206,7 +1243,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers, memset(drbg->C, 0, drbg_statelen(drbg)); } - ret = __drbg_seed(drbg, &seedlist, reseed); + ret = __drbg_seed(drbg, &seedlist, reseed, new_seed_state); out: memzero_explicit(entropy, entropylen * 2); @@ -1386,19 +1423,26 @@ static int drbg_generate(struct drbg_state *drbg, * here. The spec is a bit convoluted here, we make it simpler. */ if (drbg->reseed_threshold < drbg->reseed_ctr) - drbg->seeded = false; + drbg->seeded = DRBG_SEED_STATE_UNSEEDED; - if (drbg->pr || !drbg->seeded) { + if (drbg->pr || drbg->seeded == DRBG_SEED_STATE_UNSEEDED) { pr_devel("DRBG: reseeding before generation (prediction " "resistance: %s, state %s)\n", drbg->pr ? "true" : "false", - drbg->seeded ? "seeded" : "unseeded"); + (drbg->seeded == DRBG_SEED_STATE_FULL ? + "seeded" : "unseeded")); /* 9.3.1 steps 7.1 through 7.3 */ len = drbg_seed(drbg, addtl, true); if (len) goto err; /* 9.3.1 step 7.4 */ addtl = NULL; + } else if (rng_is_initialized() && + (drbg->seeded == DRBG_SEED_STATE_PARTIAL || + drbg_nopr_reseed_interval_elapsed(drbg))) { + len = drbg_seed_from_random(drbg); + if (len) + goto err; } if (addtl && 0 < addtl->len) @@ -1491,51 +1535,23 @@ static int drbg_generate_long(struct drbg_state *drbg, return 0; } -static void drbg_schedule_async_seed(struct random_ready_callback *rdy) -{ - struct drbg_state *drbg = container_of(rdy, struct drbg_state, - random_ready); - - schedule_work(&drbg->seed_work); -} - static int drbg_prepare_hrng(struct drbg_state *drbg) { - int err; - /* We do not need an HRNG in test mode. */ if (list_empty(&drbg->test_data.list)) return 0; drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0); + if (IS_ERR(drbg->jent)) { + const int err = PTR_ERR(drbg->jent); - INIT_WORK(&drbg->seed_work, drbg_async_seed); - - drbg->random_ready.owner = THIS_MODULE; - drbg->random_ready.func = drbg_schedule_async_seed; - - err = add_random_ready_callback(&drbg->random_ready); - - switch (err) { - case 0: - break; - - case -EALREADY: - err = 0; - fallthrough; - - default: - drbg->random_ready.func = NULL; - return err; + drbg->jent = NULL; + if (fips_enabled || err != -ENOENT) + return err; + pr_info("DRBG: Continuing without Jitter RNG\n"); } - /* - * Require frequent reseeds until the seed source is fully - * initialized. - */ - drbg->reseed_threshold = 50; - - return err; + return 0; } /* @@ -1578,7 +1594,8 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers, if (!drbg->core) { drbg->core = &drbg_cores[coreref]; drbg->pr = pr; - drbg->seeded = false; + drbg->seeded = DRBG_SEED_STATE_UNSEEDED; + drbg->last_seed_time = 0; drbg->reseed_threshold = drbg_max_requests(drbg); ret = drbg_alloc_state(drbg); @@ -1589,14 +1606,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers, if (ret) goto free_everything; - if (IS_ERR(drbg->jent)) { - ret = PTR_ERR(drbg->jent); - drbg->jent = NULL; - if (fips_enabled || ret != -ENOENT) - goto free_everything; - pr_info("DRBG: Continuing without Jitter RNG\n"); - } - reseed = false; } @@ -1629,11 +1638,6 @@ free_everything: */ static int drbg_uninstantiate(struct drbg_state *drbg) { - if (drbg->random_ready.func) { - del_random_ready_callback(&drbg->random_ready); - cancel_work_sync(&drbg->seed_work); - } - if (!IS_ERR_OR_NULL(drbg->jent)) crypto_free_rng(drbg->jent); drbg->jent = NULL; diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c index e8a4165a1874..2d115bec15ae 100644 --- a/crypto/jitterentropy-kcapi.c +++ b/crypto/jitterentropy-kcapi.c @@ -40,7 +40,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/fips.h> #include <linux/time.h> #include <crypto/internal/rng.h> @@ -60,11 +59,6 @@ void jent_zfree(void *ptr) kfree_sensitive(ptr); } -int jent_fips_enabled(void) -{ - return fips_enabled; -} - void jent_panic(char *s) { panic("%s", s); diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c index 4dc2261cdeef..93bff3213823 100644 --- a/crypto/jitterentropy.c +++ b/crypto/jitterentropy.c @@ -117,6 +117,22 @@ struct rand_data { #define JENT_EHEALTH 9 /* Health test failed during initialization */ #define JENT_ERCT 10 /* RCT failed during initialization */ +/* + * The output n bits can receive more than n bits of min entropy, of course, + * but the fixed output of the conditioning function can only asymptotically + * approach the output size bits of min entropy, not attain that bound. Random + * maps will tend to have output collisions, which reduces the creditable + * output entropy (that is what SP 800-90B Section 3.1.5.1.2 attempts to bound). + * + * The value "64" is justified in Appendix A.4 of the current 90C draft, + * and aligns with NIST's in "epsilon" definition in this document, which is + * that a string can be considered "full entropy" if you can bound the min + * entropy in each bit of output to at least 1-epsilon, where epsilon is + * required to be <= 2^(-32). + */ +#define JENT_ENTROPY_SAFETY_FACTOR 64 + +#include <linux/fips.h> #include "jitterentropy.h" /*************************************************************************** @@ -265,7 +281,6 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta) { __u64 delta2 = jent_delta(ec->last_delta, current_delta); __u64 delta3 = jent_delta(ec->last_delta2, delta2); - unsigned int delta_masked = current_delta & JENT_APT_WORD_MASK; ec->last_delta = current_delta; ec->last_delta2 = delta2; @@ -274,7 +289,7 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta) * Insert the result of the comparison of two back-to-back time * deltas. */ - jent_apt_insert(ec, delta_masked); + jent_apt_insert(ec, current_delta); if (!current_delta || !delta2 || !delta3) { /* RCT with a stuck bit */ @@ -299,10 +314,6 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta) */ static int jent_health_failure(struct rand_data *ec) { - /* Test is only enabled in FIPS mode */ - if (!jent_fips_enabled()) - return 0; - return ec->health_failure; } @@ -547,12 +558,15 @@ static int jent_measure_jitter(struct rand_data *ec) */ static void jent_gen_entropy(struct rand_data *ec) { - unsigned int k = 0; + unsigned int k = 0, safety_factor = 0; + + if (fips_enabled) + safety_factor = JENT_ENTROPY_SAFETY_FACTOR; /* priming of the ->prev_time value */ jent_measure_jitter(ec); - while (1) { + while (!jent_health_failure(ec)) { /* If a stuck measurement is received, repeat measurement */ if (jent_measure_jitter(ec)) continue; @@ -561,7 +575,7 @@ static void jent_gen_entropy(struct rand_data *ec) * We multiply the loop value with ->osr to obtain the * oversampling rate requested by the caller */ - if (++k >= (DATA_SIZE_BITS * ec->osr)) + if (++k >= ((DATA_SIZE_BITS + safety_factor) * ec->osr)) break; } } diff --git a/crypto/jitterentropy.h b/crypto/jitterentropy.h index c83fff32d130..b7397b617ef0 100644 --- a/crypto/jitterentropy.h +++ b/crypto/jitterentropy.h @@ -2,7 +2,6 @@ extern void *jent_zalloc(unsigned int len); extern void jent_zfree(void *ptr); -extern int jent_fips_enabled(void); extern void jent_panic(char *s); extern void jent_memcpy(void *dest, const void *src, unsigned int n); extern void jent_get_nstime(__u64 *out); diff --git a/crypto/kdf_sp800108.c b/crypto/kdf_sp800108.c new file mode 100644 index 000000000000..58edf7797abf --- /dev/null +++ b/crypto/kdf_sp800108.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * SP800-108 Key-derivation function + * + * Copyright (C) 2021, Stephan Mueller <smueller@chronox.de> + */ + +#include <linux/fips.h> +#include <linux/module.h> +#include <crypto/kdf_sp800108.h> +#include <crypto/internal/kdf_selftest.h> + +/* + * SP800-108 CTR KDF implementation + */ +int crypto_kdf108_ctr_generate(struct crypto_shash *kmd, + const struct kvec *info, unsigned int info_nvec, + u8 *dst, unsigned int dlen) +{ + SHASH_DESC_ON_STACK(desc, kmd); + __be32 counter = cpu_to_be32(1); + const unsigned int h = crypto_shash_digestsize(kmd), dlen_orig = dlen; + unsigned int i; + int err = 0; + u8 *dst_orig = dst; + + desc->tfm = kmd; + + while (dlen) { + err = crypto_shash_init(desc); + if (err) + goto out; + + err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32)); + if (err) + goto out; + + for (i = 0; i < info_nvec; i++) { + err = crypto_shash_update(desc, info[i].iov_base, + info[i].iov_len); + if (err) + goto out; + } + + if (dlen < h) { + u8 tmpbuffer[HASH_MAX_DIGESTSIZE]; + + err = crypto_shash_final(desc, tmpbuffer); + if (err) + goto out; + memcpy(dst, tmpbuffer, dlen); + memzero_explicit(tmpbuffer, h); + goto out; + } + + err = crypto_shash_final(desc, dst); + if (err) + goto out; + + dlen -= h; + dst += h; + counter = cpu_to_be32(be32_to_cpu(counter) + 1); + } + +out: + if (err) + memzero_explicit(dst_orig, dlen_orig); + shash_desc_zero(desc); + return err; +} +EXPORT_SYMBOL(crypto_kdf108_ctr_generate); + +/* + * The seeding of the KDF + */ +int crypto_kdf108_setkey(struct crypto_shash *kmd, + const u8 *key, size_t keylen, + const u8 *ikm, size_t ikmlen) +{ + unsigned int ds = crypto_shash_digestsize(kmd); + + /* SP800-108 does not support IKM */ + if (ikm || ikmlen) + return -EINVAL; + + /* Check according to SP800-108 section 7.2 */ + if (ds > keylen) + return -EINVAL; + + /* Set the key for the MAC used for the KDF. */ + return crypto_shash_setkey(kmd, key, keylen); +} +EXPORT_SYMBOL(crypto_kdf108_setkey); + +/* + * Test vector obtained from + * http://csrc.nist.gov/groups/STM/cavp/documents/KBKDF800-108/CounterMode.zip + */ +static const struct kdf_testvec kdf_ctr_hmac_sha256_tv_template[] = { + { + .key = "\xdd\x1d\x91\xb7\xd9\x0b\x2b\xd3" + "\x13\x85\x33\xce\x92\xb2\x72\xfb" + "\xf8\xa3\x69\x31\x6a\xef\xe2\x42" + "\xe6\x59\xcc\x0a\xe2\x38\xaf\xe0", + .keylen = 32, + .ikm = NULL, + .ikmlen = 0, + .info = { + .iov_base = "\x01\x32\x2b\x96\xb3\x0a\xcd\x19" + "\x79\x79\x44\x4e\x46\x8e\x1c\x5c" + "\x68\x59\xbf\x1b\x1c\xf9\x51\xb7" + "\xe7\x25\x30\x3e\x23\x7e\x46\xb8" + "\x64\xa1\x45\xfa\xb2\x5e\x51\x7b" + "\x08\xf8\x68\x3d\x03\x15\xbb\x29" + "\x11\xd8\x0a\x0e\x8a\xba\x17\xf3" + "\xb4\x13\xfa\xac", + .iov_len = 60 + }, + .expected = "\x10\x62\x13\x42\xbf\xb0\xfd\x40" + "\x04\x6c\x0e\x29\xf2\xcf\xdb\xf0", + .expectedlen = 16 + } +}; + +static int __init crypto_kdf108_init(void) +{ + int ret = kdf_test(&kdf_ctr_hmac_sha256_tv_template[0], "hmac(sha256)", + crypto_kdf108_setkey, crypto_kdf108_ctr_generate); + + if (ret) { + if (fips_enabled) + panic("alg: self-tests for CTR-KDF (hmac(sha256)) failed (rc=%d)\n", + ret); + + WARN(1, + "alg: self-tests for CTR-KDF (hmac(sha256)) failed (rc=%d)\n", + ret); + } else { + pr_info("alg: self-tests for CTR-KDF (hmac(sha256)) passed\n"); + } + + return ret; +} + +static void __exit crypto_kdf108_exit(void) { } + +module_init(crypto_kdf108_init); +module_exit(crypto_kdf108_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Stephan Mueller <smueller@chronox.de>"); +MODULE_DESCRIPTION("Key Derivation Function conformant to SP800-108"); diff --git a/crypto/rsa.c b/crypto/rsa.c index 4cdbec95d077..39e04176b04b 100644 --- a/crypto/rsa.c +++ b/crypto/rsa.c @@ -5,6 +5,7 @@ * Authors: Tadeusz Struk <tadeusz.struk@intel.com> */ +#include <linux/fips.h> #include <linux/module.h> #include <linux/mpi.h> #include <crypto/internal/rsa.h> @@ -144,6 +145,9 @@ static int rsa_check_key_length(unsigned int len) case 512: case 1024: case 1536: + if (fips_enabled) + return -EINVAL; + fallthrough; case 2048: case 3072: case 4096: diff --git a/crypto/sha256_generic.c b/crypto/sha256_generic.c index 3b377197236e..bf147b01e313 100644 --- a/crypto/sha256_generic.c +++ b/crypto/sha256_generic.c @@ -33,18 +33,6 @@ const u8 sha256_zero_message_hash[SHA256_DIGEST_SIZE] = { }; EXPORT_SYMBOL_GPL(sha256_zero_message_hash); -static int crypto_sha256_init(struct shash_desc *desc) -{ - sha256_init(shash_desc_ctx(desc)); - return 0; -} - -static int crypto_sha224_init(struct shash_desc *desc) -{ - sha224_init(shash_desc_ctx(desc)); - return 0; -} - int crypto_sha256_update(struct shash_desc *desc, const u8 *data, unsigned int len) { @@ -72,7 +60,7 @@ EXPORT_SYMBOL(crypto_sha256_finup); static struct shash_alg sha256_algs[2] = { { .digestsize = SHA256_DIGEST_SIZE, - .init = crypto_sha256_init, + .init = sha256_base_init, .update = crypto_sha256_update, .final = crypto_sha256_final, .finup = crypto_sha256_finup, @@ -86,7 +74,7 @@ static struct shash_alg sha256_algs[2] = { { } }, { .digestsize = SHA224_DIGEST_SIZE, - .init = crypto_sha224_init, + .init = sha224_base_init, .update = crypto_sha256_update, .final = crypto_sha256_final, .finup = crypto_sha256_finup, diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 58eee8eab4bf..5831d4bbc64f 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -4193,7 +4193,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha1),cbc(des3_ede))", .test = alg_test_aead, - .fips_allowed = 1, .suite = { .aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp) } @@ -4220,7 +4219,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha224),cbc(des3_ede))", .test = alg_test_aead, - .fips_allowed = 1, .suite = { .aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp) } @@ -4240,7 +4238,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha256),cbc(des3_ede))", .test = alg_test_aead, - .fips_allowed = 1, .suite = { .aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp) } @@ -4261,7 +4258,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha384),cbc(des3_ede))", .test = alg_test_aead, - .fips_allowed = 1, .suite = { .aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp) } @@ -4289,7 +4285,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "authenc(hmac(sha512),cbc(des3_ede))", .test = alg_test_aead, - .fips_allowed = 1, .suite = { .aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp) } @@ -4399,7 +4394,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "cbc(des3_ede)", .test = alg_test_skcipher, - .fips_allowed = 1, .suite = { .cipher = __VECS(des3_ede_cbc_tv_template) }, @@ -4505,7 +4499,6 @@ static const struct alg_test_desc alg_test_descs[] = { } }, { .alg = "cmac(des3_ede)", - .fips_allowed = 1, .test = alg_test_hash, .suite = { .hash = __VECS(des3_ede_cmac64_tv_template) @@ -4580,7 +4573,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "ctr(des3_ede)", .test = alg_test_skcipher, - .fips_allowed = 1, .suite = { .cipher = __VECS(des3_ede_ctr_tv_template) } @@ -4846,7 +4838,6 @@ static const struct alg_test_desc alg_test_descs[] = { }, { .alg = "ecb(des3_ede)", .test = alg_test_skcipher, - .fips_allowed = 1, .suite = { .cipher = __VECS(des3_ede_tv_template) } diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 779720bf9364..a253d66ba1c1 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -257,9 +257,9 @@ static const struct akcipher_testvec rsa_tv_template[] = { }, { #endif .key = - "\x30\x82\x02\x1F" /* sequence of 543 bytes */ + "\x30\x82\x02\x20" /* sequence of 544 bytes */ "\x02\x01\x01" /* version - integer of 1 byte */ - "\x02\x82\x01\x00" /* modulus - integer of 256 bytes */ + "\x02\x82\x01\x01\x00" /* modulus - integer of 256 bytes */ "\xDB\x10\x1A\xC2\xA3\xF1\xDC\xFF\x13\x6B\xED\x44\xDF\xF0\x02\x6D" "\x13\xC7\x88\xDA\x70\x6B\x54\xF1\xE8\x27\xDC\xC3\x0F\x99\x6A\xFA" "\xC6\x67\xFF\x1D\x1E\x3C\x1D\xC1\xB5\x5F\x6C\xC0\xB2\x07\x3A\x6D" @@ -299,7 +299,7 @@ static const struct akcipher_testvec rsa_tv_template[] = { "\x02\x01\x00" /* exponent1 - integer of 1 byte */ "\x02\x01\x00" /* exponent2 - integer of 1 byte */ "\x02\x01\x00", /* coefficient - integer of 1 byte */ - .key_len = 547, + .key_len = 548, .m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a", .c = "\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe" |