From 04cb788ecee8369c11edb7104775f30ed6247a26 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 24 Aug 2021 14:05:13 -0700 Subject: crypto: jitter - drop kernel-doc notation Drop "begin kernel-doc (/**)" entries in jitterentropy.c since they are not in kernel-doc format and they cause many complaints (warnings) from scripts/kernel-doc. Signed-off-by: Randy Dunlap Cc: Stephan Mueller Cc: Herbert Xu Cc: "David S. Miller" Cc: linux-crypto@vger.kernel.org Signed-off-by: Herbert Xu --- crypto/jitterentropy.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'crypto') diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c index a11b3208760f..4dc2261cdeef 100644 --- a/crypto/jitterentropy.c +++ b/crypto/jitterentropy.c @@ -125,7 +125,7 @@ struct rand_data { * This test complies with SP800-90B section 4.4.2. ***************************************************************************/ -/** +/* * Reset the APT counter * * @ec [in] Reference to entropy collector @@ -138,7 +138,7 @@ static void jent_apt_reset(struct rand_data *ec, unsigned int delta_masked) ec->apt_observations = 0; } -/** +/* * Insert a new entropy event into APT * * @ec [in] Reference to entropy collector @@ -182,7 +182,7 @@ static void jent_apt_insert(struct rand_data *ec, unsigned int delta_masked) * the end. The caller of the Jitter RNG is informed with an error code. ***************************************************************************/ -/** +/* * Repetition Count Test as defined in SP800-90B section 4.4.1 * * @ec [in] Reference to entropy collector @@ -223,7 +223,7 @@ static void jent_rct_insert(struct rand_data *ec, int stuck) } } -/** +/* * Is there an RCT health test failure? * * @ec [in] Reference to entropy collector @@ -246,7 +246,7 @@ static inline __u64 jent_delta(__u64 prev, __u64 next) (JENT_UINT64_MAX - prev + 1 + next); } -/** +/* * Stuck test by checking the: * 1st derivative of the jitter measurement (time delta) * 2nd derivative of the jitter measurement (delta of time deltas) @@ -288,7 +288,7 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta) return 0; } -/** +/* * Report any health test failures * * @ec [in] Reference to entropy collector @@ -310,7 +310,7 @@ static int jent_health_failure(struct rand_data *ec) * Noise sources ***************************************************************************/ -/** +/* * Update of the loop count used for the next round of * an entropy collection. * @@ -353,7 +353,7 @@ static __u64 jent_loop_shuffle(struct rand_data *ec, return (shuffle + (1<data = new; } -/** +/* * Memory Access noise source -- this is a noise source based on variations in * memory access times * @@ -500,7 +500,7 @@ static void jent_memaccess(struct rand_data *ec, __u64 loop_cnt) /*************************************************************************** * Start of entropy processing logic ***************************************************************************/ -/** +/* * This is the heart of the entropy generation: calculate time deltas and * use the CPU jitter in the time deltas. The jitter is injected into the * entropy pool. @@ -539,7 +539,7 @@ static int jent_measure_jitter(struct rand_data *ec) return stuck; } -/** +/* * Generator of one 64 bit random number * Function fills rand_data->data * @@ -566,7 +566,7 @@ static void jent_gen_entropy(struct rand_data *ec) } } -/** +/* * Entry function: Obtain entropy for the caller. * * This function invokes the entropy gathering logic as often to generate -- cgit v1.3-18-gd494 From 81f53028dfbc79844f727a7c13d337ba827a471c Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Fri, 10 Sep 2021 13:01:17 -0600 Subject: crypto: drbg - Fix unused value warning in drbg_healthcheck_sanity() Coverity warns uf an unused value: CID 44865 (#2 of 2): Unused value (UNUSED_VALUE) assigned_value: Assigning value -14 to ret here, but that stored value is overwritten before it can be used. 2006 int ret = -EFAULT; ... value_overwrite: Overwriting previous write to ret with value from drbg_seed(drbg, &addtl, false). 2052 ret = drbg_seed(drbg, &addtl, false); Fix this by removing the variable initializer. Cc: Herbert Xu Cc: "David S. Miller" Cc: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Tim Gardner Signed-off-by: Herbert Xu --- crypto/drbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crypto') diff --git a/crypto/drbg.c b/crypto/drbg.c index ea85d4a0fe9e..f72f340a1321 100644 --- a/crypto/drbg.c +++ b/crypto/drbg.c @@ -2003,7 +2003,7 @@ static inline int __init drbg_healthcheck_sanity(void) #define OUTBUFLEN 16 unsigned char buf[OUTBUFLEN]; struct drbg_state *drbg = NULL; - int ret = -EFAULT; + int ret; int rc = -EFAULT; bool pr = false; int coreref = 0; -- cgit v1.3-18-gd494 From adad556efcdd42a1d9e060cbe5f6161cccf1fa28 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 17 Sep 2021 08:26:19 +0800 Subject: crypto: api - Fix built-in testing dependency failures When complex algorithms that depend on other algorithms are built into the kernel, the order of registration must be done such that the underlying algorithms are ready before the ones on top are registered. As otherwise they would fail during the self-test which is required during registration. In the past we have used subsystem initialisation ordering to guarantee this. The number of such precedence levels are limited and they may cause ripple effects in other subsystems. This patch solves this problem by delaying all self-tests during boot-up for built-in algorithms. They will be tested either when something else in the kernel requests for them, or when we have finished registering all built-in algorithms, whichever comes earlier. Reported-by: Vladis Dronov Signed-off-by: Herbert Xu --- crypto/algapi.c | 73 ++++++++++++++++++++++++++++++++++++++----------------- crypto/api.c | 52 +++++++++++++++++++++++++++++++++++---- crypto/internal.h | 10 ++++++++ 3 files changed, 108 insertions(+), 27 deletions(-) (limited to 'crypto') diff --git a/crypto/algapi.c b/crypto/algapi.c index 43f999dba4dc..422bdca214e1 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -389,29 +389,10 @@ void crypto_remove_final(struct list_head *list) } EXPORT_SYMBOL_GPL(crypto_remove_final); -static void crypto_wait_for_test(struct crypto_larval *larval) -{ - int err; - - err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult); - if (err != NOTIFY_STOP) { - if (WARN_ON(err != NOTIFY_DONE)) - goto out; - crypto_alg_tested(larval->alg.cra_driver_name, 0); - } - - err = wait_for_completion_killable(&larval->completion); - WARN_ON(err); - if (!err) - crypto_notify(CRYPTO_MSG_ALG_LOADED, larval); - -out: - crypto_larval_kill(&larval->alg); -} - int crypto_register_alg(struct crypto_alg *alg) { struct crypto_larval *larval; + bool test_started; int err; alg->cra_flags &= ~CRYPTO_ALG_DEAD; @@ -421,12 +402,15 @@ int crypto_register_alg(struct crypto_alg *alg) down_write(&crypto_alg_sem); larval = __crypto_register_alg(alg); + test_started = static_key_enabled(&crypto_boot_test_finished); + larval->test_started = test_started; up_write(&crypto_alg_sem); if (IS_ERR(larval)) return PTR_ERR(larval); - crypto_wait_for_test(larval); + if (test_started) + crypto_wait_for_test(larval); return 0; } EXPORT_SYMBOL_GPL(crypto_register_alg); @@ -633,6 +617,8 @@ int crypto_register_instance(struct crypto_template *tmpl, if (IS_ERR(larval)) goto unlock; + larval->test_started = true; + hlist_add_head(&inst->list, &tmpl->instances); inst->tmpl = tmpl; @@ -1261,9 +1247,48 @@ void crypto_stats_skcipher_decrypt(unsigned int cryptlen, int ret, EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt); #endif +static void __init crypto_start_tests(void) +{ + for (;;) { + struct crypto_larval *larval = NULL; + struct crypto_alg *q; + + down_write(&crypto_alg_sem); + + list_for_each_entry(q, &crypto_alg_list, cra_list) { + struct crypto_larval *l; + + if (!crypto_is_larval(q)) + continue; + + l = (void *)q; + + if (!crypto_is_test_larval(l)) + continue; + + if (l->test_started) + continue; + + l->test_started = true; + larval = l; + break; + } + + up_write(&crypto_alg_sem); + + if (!larval) + break; + + crypto_wait_for_test(larval); + } + + static_branch_enable(&crypto_boot_test_finished); +} + static int __init crypto_algapi_init(void) { crypto_init_proc(); + crypto_start_tests(); return 0; } @@ -1272,7 +1297,11 @@ static void __exit crypto_algapi_exit(void) crypto_exit_proc(); } -module_init(crypto_algapi_init); +/* + * We run this at late_initcall so that all the built-in algorithms + * have had a chance to register themselves first. + */ +late_initcall(crypto_algapi_init); module_exit(crypto_algapi_exit); MODULE_LICENSE("GPL"); diff --git a/crypto/api.c b/crypto/api.c index c4eda56cff89..1cf1f03347cc 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -30,6 +31,8 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem); BLOCKING_NOTIFIER_HEAD(crypto_chain); EXPORT_SYMBOL_GPL(crypto_chain); +DEFINE_STATIC_KEY_FALSE(crypto_boot_test_finished); + static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg); struct crypto_alg *crypto_mod_get(struct crypto_alg *alg) @@ -47,11 +50,6 @@ void crypto_mod_put(struct crypto_alg *alg) } EXPORT_SYMBOL_GPL(crypto_mod_put); -static inline int crypto_is_test_larval(struct crypto_larval *larval) -{ - return larval->alg.cra_driver_name[0]; -} - static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type, u32 mask) { @@ -163,11 +161,55 @@ void crypto_larval_kill(struct crypto_alg *alg) } EXPORT_SYMBOL_GPL(crypto_larval_kill); +void crypto_wait_for_test(struct crypto_larval *larval) +{ + int err; + + err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult); + if (err != NOTIFY_STOP) { + if (WARN_ON(err != NOTIFY_DONE)) + goto out; + crypto_alg_tested(larval->alg.cra_driver_name, 0); + } + + err = wait_for_completion_killable(&larval->completion); + WARN_ON(err); + if (!err) + crypto_notify(CRYPTO_MSG_ALG_LOADED, larval); + +out: + crypto_larval_kill(&larval->alg); +} +EXPORT_SYMBOL_GPL(crypto_wait_for_test); + +static void crypto_start_test(struct crypto_larval *larval) +{ + if (!crypto_is_test_larval(larval)) + return; + + if (larval->test_started) + return; + + down_write(&crypto_alg_sem); + if (larval->test_started) { + up_write(&crypto_alg_sem); + return; + } + + larval->test_started = true; + up_write(&crypto_alg_sem); + + crypto_wait_for_test(larval); +} + static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg) { struct crypto_larval *larval = (void *)alg; long timeout; + if (!static_branch_likely(&crypto_boot_test_finished)) + crypto_start_test(larval); + timeout = wait_for_completion_killable_timeout( &larval->completion, 60 * HZ); diff --git a/crypto/internal.h b/crypto/internal.h index f00869af689f..c08385571853 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,7 @@ struct crypto_larval { struct crypto_alg *adult; struct completion completion; u32 mask; + bool test_started; }; enum { @@ -45,6 +47,8 @@ extern struct list_head crypto_alg_list; extern struct rw_semaphore crypto_alg_sem; extern struct blocking_notifier_head crypto_chain; +DECLARE_STATIC_KEY_FALSE(crypto_boot_test_finished); + #ifdef CONFIG_PROC_FS void __init crypto_init_proc(void); void __exit crypto_exit_proc(void); @@ -70,6 +74,7 @@ struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask); struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask); void crypto_larval_kill(struct crypto_alg *alg); +void crypto_wait_for_test(struct crypto_larval *larval); void crypto_alg_tested(const char *name, int err); void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, @@ -156,5 +161,10 @@ static inline void crypto_yield(u32 flags) cond_resched(); } +static inline int crypto_is_test_larval(struct crypto_larval *larval) +{ + return larval->alg.cra_driver_name[0]; +} + #endif /* _CRYPTO_INTERNAL_H */ -- cgit v1.3-18-gd494 From 38aa192a05f22f9778f9420e630f0322525ef12e Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Mon, 20 Sep 2021 12:05:35 +0200 Subject: crypto: ecc - fix CRYPTO_DEFAULT_RNG dependency The ecc.c file started out as part of the ECDH algorithm but got moved out into a standalone module later. It does not build without CRYPTO_DEFAULT_RNG, so now that other modules are using it as well we can run into this link error: aarch64-linux-ld: ecc.c:(.text+0xfc8): undefined reference to `crypto_default_rng' aarch64-linux-ld: ecc.c:(.text+0xff4): undefined reference to `crypto_put_default_rng' Move the 'select CRYPTO_DEFAULT_RNG' statement into the correct symbol. Fixes: 0d7a78643f69 ("crypto: ecrdsa - add EC-RDSA (GOST 34.10) algorithm") Fixes: 4e6602916bc6 ("crypto: ecdsa - Add support for ECDSA signature verification") Signed-off-by: Arnd Bergmann Reviewed-by: Stefan Berger Signed-off-by: Herbert Xu --- crypto/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crypto') diff --git a/crypto/Kconfig b/crypto/Kconfig index 536df4b6b825..285f82647d2b 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -233,12 +233,12 @@ config CRYPTO_DH config CRYPTO_ECC tristate + select CRYPTO_RNG_DEFAULT config CRYPTO_ECDH tristate "ECDH algorithm" select CRYPTO_ECC select CRYPTO_KPP - select CRYPTO_RNG_DEFAULT help Generic implementation of the ECDH algorithm -- cgit v1.3-18-gd494 From e42dff467ee688fe6b5a083f1837d06e3b27d8c0 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 27 Sep 2021 19:23:42 +0800 Subject: crypto: api - Export crypto_boot_test_finished We need to export crypto_boot_test_finished in case api.c is built-in while algapi.c is built as a module. Fixes: adad556efcdd ("crypto: api - Fix built-in testing dependency failures") Reported-by: Stephen Rothwell Signed-off-by: Herbert Xu Tested-by: Stephen Rothwell # ppc32 build Signed-off-by: Herbert Xu --- crypto/api.c | 1 + 1 file changed, 1 insertion(+) (limited to 'crypto') diff --git a/crypto/api.c b/crypto/api.c index 1cf1f03347cc..ee5991fe11f8 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -32,6 +32,7 @@ BLOCKING_NOTIFIER_HEAD(crypto_chain); EXPORT_SYMBOL_GPL(crypto_chain); DEFINE_STATIC_KEY_FALSE(crypto_boot_test_finished); +EXPORT_SYMBOL_GPL(crypto_boot_test_finished); static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg); -- cgit v1.3-18-gd494 From 82e269ad8afe1c73aa6c28dca3c23fecc6c8b616 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 28 Sep 2021 13:54:01 +0200 Subject: crypto: testmgr - Only disable migration in crypto_disable_simd_for_test() crypto_disable_simd_for_test() disables preemption in order to receive a stable per-CPU variable which it needs to modify in order to alter crypto_simd_usable() results. This can also be achived by migrate_disable() which forbidds CPU migrations but allows the task to be preempted. The latter is important for PREEMPT_RT since operation like skcipher_walk_first() may allocate memory which must not happen with disabled preemption on PREEMPT_RT. Use migrate_disable() in crypto_disable_simd_for_test() to achieve a stable per-CPU pointer. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Herbert Xu --- crypto/testmgr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crypto') diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 70f69f0910c9..58eee8eab4bf 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -1061,14 +1061,14 @@ static void generate_random_testvec_config(struct testvec_config *cfg, static void crypto_disable_simd_for_test(void) { - preempt_disable(); + migrate_disable(); __this_cpu_write(crypto_simd_disabled_for_test, true); } static void crypto_reenable_simd_for_test(void) { __this_cpu_write(crypto_simd_disabled_for_test, false); - preempt_enable(); + migrate_enable(); } /* -- cgit v1.3-18-gd494 From 3ae88f676aa63366ffa9eebb8ae787c7e19f0c57 Mon Sep 17 00:00:00 2001 From: Horia Geantă Date: Fri, 15 Oct 2021 10:39:18 +0300 Subject: crypto: tcrypt - fix skcipher multi-buffer tests for 1420B blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit ad6d66bcac77e ("crypto: tcrypt - include 1420 byte blocks in aead and skcipher benchmarks") mentions: > power-of-2 block size. So let's add 1420 bytes explicitly, and round > it up to the next blocksize multiple of the algo in question if it > does not support 1420 byte blocks. but misses updating skcipher multi-buffer tests. Fix this by using the proper (rounded) input size. Fixes: ad6d66bcac77e ("crypto: tcrypt - include 1420 byte blocks in aead and skcipher benchmarks") Signed-off-by: Horia Geantă Signed-off-by: Herbert Xu --- crypto/tcrypt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'crypto') diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 82b0400985a5..00149657a4bc 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -1333,7 +1333,7 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs, if (bs > XBUFSIZE * PAGE_SIZE) { pr_err("template (%u) too big for buffer (%lu)\n", - *b_size, XBUFSIZE * PAGE_SIZE); + bs, XBUFSIZE * PAGE_SIZE); goto out; } @@ -1386,8 +1386,7 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs, memset(cur->xbuf[p], 0xff, k); skcipher_request_set_crypt(cur->req, cur->sg, - cur->sg, *b_size, - iv); + cur->sg, bs, iv); } if (secs) { -- cgit v1.3-18-gd494 From cad439fc040efe5f4381e3a7d583c5c200dbc186 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 19 Oct 2021 21:28:02 +0800 Subject: crypto: api - Do not create test larvals if manager is disabled The delayed boot-time testing patch created a dependency loop between api.c and algapi.c because it added a crypto_alg_tested call to the former when the crypto manager is disabled. We could instead avoid creating the test larvals if the crypto manager is disabled. This avoids the dependency loop as well as saving some unnecessary work, albeit in a very unlikely case. Reported-by: Nathan Chancellor Reported-by: Naresh Kamboju Reported-by: kernel test robot Fixes: adad556efcdd ("crypto: api - Fix built-in testing dependency failures") Signed-off-by: Herbert Xu --- crypto/algapi.c | 56 ++++++++++++++++++++++++++++++++++++-------------------- crypto/api.c | 7 ++----- 2 files changed, 38 insertions(+), 25 deletions(-) (limited to 'crypto') diff --git a/crypto/algapi.c b/crypto/algapi.c index 422bdca214e1..d379fd91fb7b 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -216,6 +216,32 @@ void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, } EXPORT_SYMBOL_GPL(crypto_remove_spawns); +static struct crypto_larval *crypto_alloc_test_larval(struct crypto_alg *alg) +{ + struct crypto_larval *larval; + + if (!IS_ENABLED(CONFIG_CRYPTO_MANAGER)) + return NULL; + + larval = crypto_larval_alloc(alg->cra_name, + alg->cra_flags | CRYPTO_ALG_TESTED, 0); + if (IS_ERR(larval)) + return larval; + + larval->adult = crypto_mod_get(alg); + if (!larval->adult) { + kfree(larval); + return ERR_PTR(-ENOENT); + } + + refcount_set(&larval->alg.cra_refcnt, 1); + memcpy(larval->alg.cra_driver_name, alg->cra_driver_name, + CRYPTO_MAX_ALG_NAME); + larval->alg.cra_priority = alg->cra_priority; + + return larval; +} + static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg) { struct crypto_alg *q; @@ -250,31 +276,20 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg) goto err; } - larval = crypto_larval_alloc(alg->cra_name, - alg->cra_flags | CRYPTO_ALG_TESTED, 0); + larval = crypto_alloc_test_larval(alg); if (IS_ERR(larval)) goto out; - ret = -ENOENT; - larval->adult = crypto_mod_get(alg); - if (!larval->adult) - goto free_larval; - - refcount_set(&larval->alg.cra_refcnt, 1); - memcpy(larval->alg.cra_driver_name, alg->cra_driver_name, - CRYPTO_MAX_ALG_NAME); - larval->alg.cra_priority = alg->cra_priority; - list_add(&alg->cra_list, &crypto_alg_list); - list_add(&larval->alg.cra_list, &crypto_alg_list); + + if (larval) + list_add(&larval->alg.cra_list, &crypto_alg_list); crypto_stats_init(alg); out: return larval; -free_larval: - kfree(larval); err: larval = ERR_PTR(ret); goto out; @@ -403,10 +418,11 @@ int crypto_register_alg(struct crypto_alg *alg) down_write(&crypto_alg_sem); larval = __crypto_register_alg(alg); test_started = static_key_enabled(&crypto_boot_test_finished); - larval->test_started = test_started; + if (!IS_ERR_OR_NULL(larval)) + larval->test_started = test_started; up_write(&crypto_alg_sem); - if (IS_ERR(larval)) + if (IS_ERR_OR_NULL(larval)) return PTR_ERR(larval); if (test_started) @@ -616,8 +632,8 @@ int crypto_register_instance(struct crypto_template *tmpl, larval = __crypto_register_alg(&inst->alg); if (IS_ERR(larval)) goto unlock; - - larval->test_started = true; + else if (larval) + larval->test_started = true; hlist_add_head(&inst->list, &tmpl->instances); inst->tmpl = tmpl; @@ -626,7 +642,7 @@ unlock: up_write(&crypto_alg_sem); err = PTR_ERR(larval); - if (IS_ERR(larval)) + if (IS_ERR_OR_NULL(larval)) goto err; crypto_wait_for_test(larval); diff --git a/crypto/api.c b/crypto/api.c index ee5991fe11f8..cf0869dd130b 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -167,11 +167,8 @@ void crypto_wait_for_test(struct crypto_larval *larval) int err; err = crypto_probing_notify(CRYPTO_MSG_ALG_REGISTER, larval->adult); - if (err != NOTIFY_STOP) { - if (WARN_ON(err != NOTIFY_DONE)) - goto out; - crypto_alg_tested(larval->alg.cra_driver_name, 0); - } + if (WARN_ON_ONCE(err != NOTIFY_STOP)) + goto out; err = wait_for_completion_killable(&larval->completion); WARN_ON(err); -- cgit v1.3-18-gd494 From 1730c5aa3b158b15af567eb3aae84f5cf6ca66f2 Mon Sep 17 00:00:00 2001 From: Prabhjot Khurana Date: Wed, 20 Oct 2021 11:35:34 +0100 Subject: crypto: engine - Add KPP Support to Crypto Engine Add KPP support to the crypto engine queue manager, so that it can be used to simplify the logic of KPP device drivers as done for other crypto drivers. Signed-off-by: Prabhjot Khurana Signed-off-by: Daniele Alessandrelli Signed-off-by: Herbert Xu --- Documentation/crypto/crypto_engine.rst | 4 ++++ crypto/crypto_engine.c | 26 ++++++++++++++++++++++++++ include/crypto/engine.h | 5 +++++ 3 files changed, 35 insertions(+) (limited to 'crypto') diff --git a/Documentation/crypto/crypto_engine.rst b/Documentation/crypto/crypto_engine.rst index 25cf9836c336..d562ea17d994 100644 --- a/Documentation/crypto/crypto_engine.rst +++ b/Documentation/crypto/crypto_engine.rst @@ -69,6 +69,8 @@ the crypto engine via one of: * crypto_transfer_hash_request_to_engine() +* crypto_transfer_kpp_request_to_engine() + * crypto_transfer_skcipher_request_to_engine() At the end of the request process, a call to one of the following functions is needed: @@ -79,4 +81,6 @@ At the end of the request process, a call to one of the following functions is n * crypto_finalize_hash_request() +* crypto_finalize_kpp_request() + * crypto_finalize_skcipher_request() diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c index cff21f4e03e3..fb07da9920ee 100644 --- a/crypto/crypto_engine.c +++ b/crypto/crypto_engine.c @@ -327,6 +327,19 @@ int crypto_transfer_hash_request_to_engine(struct crypto_engine *engine, } EXPORT_SYMBOL_GPL(crypto_transfer_hash_request_to_engine); +/** + * crypto_transfer_kpp_request_to_engine - transfer one kpp_request to list + * into the engine queue + * @engine: the hardware engine + * @req: the request need to be listed into the engine queue + */ +int crypto_transfer_kpp_request_to_engine(struct crypto_engine *engine, + struct kpp_request *req) +{ + return crypto_transfer_request_to_engine(engine, &req->base); +} +EXPORT_SYMBOL_GPL(crypto_transfer_kpp_request_to_engine); + /** * crypto_transfer_skcipher_request_to_engine - transfer one skcipher_request * to list into the engine queue @@ -382,6 +395,19 @@ void crypto_finalize_hash_request(struct crypto_engine *engine, } EXPORT_SYMBOL_GPL(crypto_finalize_hash_request); +/** + * crypto_finalize_kpp_request - finalize one kpp_request if the request is done + * @engine: the hardware engine + * @req: the request need to be finalized + * @err: error number + */ +void crypto_finalize_kpp_request(struct crypto_engine *engine, + struct kpp_request *req, int err) +{ + return crypto_finalize_request(engine, &req->base, err); +} +EXPORT_SYMBOL_GPL(crypto_finalize_kpp_request); + /** * crypto_finalize_skcipher_request - finalize one skcipher_request if * the request is done diff --git a/include/crypto/engine.h b/include/crypto/engine.h index 26cac19b0f46..fd4f2fa23f51 100644 --- a/include/crypto/engine.h +++ b/include/crypto/engine.h @@ -16,6 +16,7 @@ #include #include #include +#include #define ENGINE_NAME_LEN 30 /* @@ -96,6 +97,8 @@ int crypto_transfer_akcipher_request_to_engine(struct crypto_engine *engine, struct akcipher_request *req); int crypto_transfer_hash_request_to_engine(struct crypto_engine *engine, struct ahash_request *req); +int crypto_transfer_kpp_request_to_engine(struct crypto_engine *engine, + struct kpp_request *req); int crypto_transfer_skcipher_request_to_engine(struct crypto_engine *engine, struct skcipher_request *req); void crypto_finalize_aead_request(struct crypto_engine *engine, @@ -104,6 +107,8 @@ void crypto_finalize_akcipher_request(struct crypto_engine *engine, struct akcipher_request *req, int err); void crypto_finalize_hash_request(struct crypto_engine *engine, struct ahash_request *req, int err); +void crypto_finalize_kpp_request(struct crypto_engine *engine, + struct kpp_request *req, int err); void crypto_finalize_skcipher_request(struct crypto_engine *engine, struct skcipher_request *req, int err); int crypto_engine_start(struct crypto_engine *engine); -- cgit v1.3-18-gd494 From a745d3ace3fd65ada44d61dafa64a2a69679ac35 Mon Sep 17 00:00:00 2001 From: Daniele Alessandrelli Date: Wed, 20 Oct 2021 11:35:35 +0100 Subject: crypto: ecc - Move ecc.h to include/crypto/internal Move ecc.h header file to 'include/crypto/internal' so that it can be easily imported from everywhere in the kernel tree. This change is done to allow crypto device drivers to re-use the symbols exported by 'crypto/ecc.c', thus avoiding code duplication. Signed-off-by: Daniele Alessandrelli Signed-off-by: Herbert Xu --- crypto/ecc.c | 2 +- crypto/ecc.h | 245 ------------------------------------------ crypto/ecdh.c | 2 +- crypto/ecdsa.c | 2 +- crypto/ecrdsa.c | 2 +- crypto/ecrdsa_defs.h | 2 +- include/crypto/internal/ecc.h | 245 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 250 insertions(+), 250 deletions(-) delete mode 100644 crypto/ecc.h create mode 100644 include/crypto/internal/ecc.h (limited to 'crypto') diff --git a/crypto/ecc.c b/crypto/ecc.c index afc6cefdc1d9..80efc9b4eb69 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -32,10 +32,10 @@ #include #include #include +#include #include #include -#include "ecc.h" #include "ecc_curve_defs.h" typedef struct { diff --git a/crypto/ecc.h b/crypto/ecc.h deleted file mode 100644 index 1350e8eb6ac2..000000000000 --- a/crypto/ecc.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (c) 2013, Kenneth MacKay - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef _CRYPTO_ECC_H -#define _CRYPTO_ECC_H - -#include -#include - -/* One digit is u64 qword. */ -#define ECC_CURVE_NIST_P192_DIGITS 3 -#define ECC_CURVE_NIST_P256_DIGITS 4 -#define ECC_CURVE_NIST_P384_DIGITS 6 -#define ECC_MAX_DIGITS (512 / 64) /* due to ecrdsa */ - -#define ECC_DIGITS_TO_BYTES_SHIFT 3 - -#define ECC_MAX_BYTES (ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT) - -#define ECC_POINT_INIT(x, y, ndigits) (struct ecc_point) { x, y, ndigits } - -/** - * ecc_swap_digits() - Copy ndigits from big endian array to native array - * @in: Input array - * @out: Output array - * @ndigits: Number of digits to copy - */ -static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigits) -{ - const __be64 *src = (__force __be64 *)in; - int i; - - for (i = 0; i < ndigits; i++) - out[i] = get_unaligned_be64(&src[ndigits - 1 - i]); -} - -/** - * ecc_is_key_valid() - Validate a given ECDH private key - * - * @curve_id: id representing the curve to use - * @ndigits: curve's number of digits - * @private_key: private key to be used for the given curve - * @private_key_len: private key length - * - * Returns 0 if the key is acceptable, a negative value otherwise - */ -int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, - const u64 *private_key, unsigned int private_key_len); - -/** - * ecc_gen_privkey() - Generates an ECC private key. - * The private key is a random integer in the range 0 < random < n, where n is a - * prime that is the order of the cyclic subgroup generated by the distinguished - * point G. - * @curve_id: id representing the curve to use - * @ndigits: curve number of digits - * @private_key: buffer for storing the generated private key - * - * Returns 0 if the private key was generated successfully, a negative value - * if an error occurred. - */ -int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey); - -/** - * ecc_make_pub_key() - Compute an ECC public key - * - * @curve_id: id representing the curve to use - * @ndigits: curve's number of digits - * @private_key: pregenerated private key for the given curve - * @public_key: buffer for storing the generated public key - * - * Returns 0 if the public key was generated successfully, a negative value - * if an error occurred. - */ -int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits, - const u64 *private_key, u64 *public_key); - -/** - * crypto_ecdh_shared_secret() - Compute a shared secret - * - * @curve_id: id representing the curve to use - * @ndigits: curve's number of digits - * @private_key: private key of part A - * @public_key: public key of counterpart B - * @secret: buffer for storing the calculated shared secret - * - * Note: It is recommended that you hash the result of crypto_ecdh_shared_secret - * before using it for symmetric encryption or HMAC. - * - * Returns 0 if the shared secret was generated successfully, a negative value - * if an error occurred. - */ -int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, - const u64 *private_key, const u64 *public_key, - u64 *secret); - -/** - * ecc_is_pubkey_valid_partial() - Partial public key validation - * - * @curve: elliptic curve domain parameters - * @pk: public key as a point - * - * Valdiate public key according to SP800-56A section 5.6.2.3.4 ECC Partial - * Public-Key Validation Routine. - * - * Note: There is no check that the public key is in the correct elliptic curve - * subgroup. - * - * Return: 0 if validation is successful, -EINVAL if validation is failed. - */ -int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve, - struct ecc_point *pk); - -/** - * ecc_is_pubkey_valid_full() - Full public key validation - * - * @curve: elliptic curve domain parameters - * @pk: public key as a point - * - * Valdiate public key according to SP800-56A section 5.6.2.3.3 ECC Full - * Public-Key Validation Routine. - * - * Return: 0 if validation is successful, -EINVAL if validation is failed. - */ -int ecc_is_pubkey_valid_full(const struct ecc_curve *curve, - struct ecc_point *pk); - -/** - * vli_is_zero() - Determine is vli is zero - * - * @vli: vli to check. - * @ndigits: length of the @vli - */ -bool vli_is_zero(const u64 *vli, unsigned int ndigits); - -/** - * vli_cmp() - compare left and right vlis - * - * @left: vli - * @right: vli - * @ndigits: length of both vlis - * - * Returns sign of @left - @right, i.e. -1 if @left < @right, - * 0 if @left == @right, 1 if @left > @right. - */ -int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits); - -/** - * vli_sub() - Subtracts right from left - * - * @result: where to write result - * @left: vli - * @right vli - * @ndigits: length of all vlis - * - * Note: can modify in-place. - * - * Return: carry bit. - */ -u64 vli_sub(u64 *result, const u64 *left, const u64 *right, - unsigned int ndigits); - -/** - * vli_from_be64() - Load vli from big-endian u64 array - * - * @dest: destination vli - * @src: source array of u64 BE values - * @ndigits: length of both vli and array - */ -void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits); - -/** - * vli_from_le64() - Load vli from little-endian u64 array - * - * @dest: destination vli - * @src: source array of u64 LE values - * @ndigits: length of both vli and array - */ -void vli_from_le64(u64 *dest, const void *src, unsigned int ndigits); - -/** - * vli_mod_inv() - Modular inversion - * - * @result: where to write vli number - * @input: vli value to operate on - * @mod: modulus - * @ndigits: length of all vlis - */ -void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod, - unsigned int ndigits); - -/** - * vli_mod_mult_slow() - Modular multiplication - * - * @result: where to write result value - * @left: vli number to multiply with @right - * @right: vli number to multiply with @left - * @mod: modulus - * @ndigits: length of all vlis - * - * Note: Assumes that mod is big enough curve order. - */ -void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right, - const u64 *mod, unsigned int ndigits); - -/** - * ecc_point_mult_shamir() - Add two points multiplied by scalars - * - * @result: resulting point - * @x: scalar to multiply with @p - * @p: point to multiply with @x - * @y: scalar to multiply with @q - * @q: point to multiply with @y - * @curve: curve - * - * Returns result = x * p + x * q over the curve. - * This works faster than two multiplications and addition. - */ -void ecc_point_mult_shamir(const struct ecc_point *result, - const u64 *x, const struct ecc_point *p, - const u64 *y, const struct ecc_point *q, - const struct ecc_curve *curve); -#endif diff --git a/crypto/ecdh.c b/crypto/ecdh.c index c6f61c2211dc..e4857d534344 100644 --- a/crypto/ecdh.c +++ b/crypto/ecdh.c @@ -6,11 +6,11 @@ */ #include +#include #include #include #include #include -#include "ecc.h" struct ecdh_ctx { unsigned int curve_id; diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c index 1e7b15009bf6..b3a8a6b572ba 100644 --- a/crypto/ecdsa.c +++ b/crypto/ecdsa.c @@ -5,12 +5,12 @@ #include #include +#include #include #include #include #include -#include "ecc.h" #include "ecdsasignature.asn1.h" struct ecc_ctx { diff --git a/crypto/ecrdsa.c b/crypto/ecrdsa.c index 6a3fd09057d0..b32ffcaad9ad 100644 --- a/crypto/ecrdsa.c +++ b/crypto/ecrdsa.c @@ -20,12 +20,12 @@ #include #include #include +#include #include #include #include #include "ecrdsa_params.asn1.h" #include "ecrdsa_pub_key.asn1.h" -#include "ecc.h" #include "ecrdsa_defs.h" #define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8) diff --git a/crypto/ecrdsa_defs.h b/crypto/ecrdsa_defs.h index 170baf039007..0056335b9d03 100644 --- a/crypto/ecrdsa_defs.h +++ b/crypto/ecrdsa_defs.h @@ -13,7 +13,7 @@ #ifndef _CRYTO_ECRDSA_DEFS_H #define _CRYTO_ECRDSA_DEFS_H -#include "ecc.h" +#include #define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8) #define ECRDSA_MAX_DIGITS (512 / 64) diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h new file mode 100644 index 000000000000..1350e8eb6ac2 --- /dev/null +++ b/include/crypto/internal/ecc.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2013, Kenneth MacKay + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _CRYPTO_ECC_H +#define _CRYPTO_ECC_H + +#include +#include + +/* One digit is u64 qword. */ +#define ECC_CURVE_NIST_P192_DIGITS 3 +#define ECC_CURVE_NIST_P256_DIGITS 4 +#define ECC_CURVE_NIST_P384_DIGITS 6 +#define ECC_MAX_DIGITS (512 / 64) /* due to ecrdsa */ + +#define ECC_DIGITS_TO_BYTES_SHIFT 3 + +#define ECC_MAX_BYTES (ECC_MAX_DIGITS << ECC_DIGITS_TO_BYTES_SHIFT) + +#define ECC_POINT_INIT(x, y, ndigits) (struct ecc_point) { x, y, ndigits } + +/** + * ecc_swap_digits() - Copy ndigits from big endian array to native array + * @in: Input array + * @out: Output array + * @ndigits: Number of digits to copy + */ +static inline void ecc_swap_digits(const void *in, u64 *out, unsigned int ndigits) +{ + const __be64 *src = (__force __be64 *)in; + int i; + + for (i = 0; i < ndigits; i++) + out[i] = get_unaligned_be64(&src[ndigits - 1 - i]); +} + +/** + * ecc_is_key_valid() - Validate a given ECDH private key + * + * @curve_id: id representing the curve to use + * @ndigits: curve's number of digits + * @private_key: private key to be used for the given curve + * @private_key_len: private key length + * + * Returns 0 if the key is acceptable, a negative value otherwise + */ +int ecc_is_key_valid(unsigned int curve_id, unsigned int ndigits, + const u64 *private_key, unsigned int private_key_len); + +/** + * ecc_gen_privkey() - Generates an ECC private key. + * The private key is a random integer in the range 0 < random < n, where n is a + * prime that is the order of the cyclic subgroup generated by the distinguished + * point G. + * @curve_id: id representing the curve to use + * @ndigits: curve number of digits + * @private_key: buffer for storing the generated private key + * + * Returns 0 if the private key was generated successfully, a negative value + * if an error occurred. + */ +int ecc_gen_privkey(unsigned int curve_id, unsigned int ndigits, u64 *privkey); + +/** + * ecc_make_pub_key() - Compute an ECC public key + * + * @curve_id: id representing the curve to use + * @ndigits: curve's number of digits + * @private_key: pregenerated private key for the given curve + * @public_key: buffer for storing the generated public key + * + * Returns 0 if the public key was generated successfully, a negative value + * if an error occurred. + */ +int ecc_make_pub_key(const unsigned int curve_id, unsigned int ndigits, + const u64 *private_key, u64 *public_key); + +/** + * crypto_ecdh_shared_secret() - Compute a shared secret + * + * @curve_id: id representing the curve to use + * @ndigits: curve's number of digits + * @private_key: private key of part A + * @public_key: public key of counterpart B + * @secret: buffer for storing the calculated shared secret + * + * Note: It is recommended that you hash the result of crypto_ecdh_shared_secret + * before using it for symmetric encryption or HMAC. + * + * Returns 0 if the shared secret was generated successfully, a negative value + * if an error occurred. + */ +int crypto_ecdh_shared_secret(unsigned int curve_id, unsigned int ndigits, + const u64 *private_key, const u64 *public_key, + u64 *secret); + +/** + * ecc_is_pubkey_valid_partial() - Partial public key validation + * + * @curve: elliptic curve domain parameters + * @pk: public key as a point + * + * Valdiate public key according to SP800-56A section 5.6.2.3.4 ECC Partial + * Public-Key Validation Routine. + * + * Note: There is no check that the public key is in the correct elliptic curve + * subgroup. + * + * Return: 0 if validation is successful, -EINVAL if validation is failed. + */ +int ecc_is_pubkey_valid_partial(const struct ecc_curve *curve, + struct ecc_point *pk); + +/** + * ecc_is_pubkey_valid_full() - Full public key validation + * + * @curve: elliptic curve domain parameters + * @pk: public key as a point + * + * Valdiate public key according to SP800-56A section 5.6.2.3.3 ECC Full + * Public-Key Validation Routine. + * + * Return: 0 if validation is successful, -EINVAL if validation is failed. + */ +int ecc_is_pubkey_valid_full(const struct ecc_curve *curve, + struct ecc_point *pk); + +/** + * vli_is_zero() - Determine is vli is zero + * + * @vli: vli to check. + * @ndigits: length of the @vli + */ +bool vli_is_zero(const u64 *vli, unsigned int ndigits); + +/** + * vli_cmp() - compare left and right vlis + * + * @left: vli + * @right: vli + * @ndigits: length of both vlis + * + * Returns sign of @left - @right, i.e. -1 if @left < @right, + * 0 if @left == @right, 1 if @left > @right. + */ +int vli_cmp(const u64 *left, const u64 *right, unsigned int ndigits); + +/** + * vli_sub() - Subtracts right from left + * + * @result: where to write result + * @left: vli + * @right vli + * @ndigits: length of all vlis + * + * Note: can modify in-place. + * + * Return: carry bit. + */ +u64 vli_sub(u64 *result, const u64 *left, const u64 *right, + unsigned int ndigits); + +/** + * vli_from_be64() - Load vli from big-endian u64 array + * + * @dest: destination vli + * @src: source array of u64 BE values + * @ndigits: length of both vli and array + */ +void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits); + +/** + * vli_from_le64() - Load vli from little-endian u64 array + * + * @dest: destination vli + * @src: source array of u64 LE values + * @ndigits: length of both vli and array + */ +void vli_from_le64(u64 *dest, const void *src, unsigned int ndigits); + +/** + * vli_mod_inv() - Modular inversion + * + * @result: where to write vli number + * @input: vli value to operate on + * @mod: modulus + * @ndigits: length of all vlis + */ +void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod, + unsigned int ndigits); + +/** + * vli_mod_mult_slow() - Modular multiplication + * + * @result: where to write result value + * @left: vli number to multiply with @right + * @right: vli number to multiply with @left + * @mod: modulus + * @ndigits: length of all vlis + * + * Note: Assumes that mod is big enough curve order. + */ +void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right, + const u64 *mod, unsigned int ndigits); + +/** + * ecc_point_mult_shamir() - Add two points multiplied by scalars + * + * @result: resulting point + * @x: scalar to multiply with @p + * @p: point to multiply with @x + * @y: scalar to multiply with @q + * @q: point to multiply with @y + * @curve: curve + * + * Returns result = x * p + x * q over the curve. + * This works faster than two multiplications and addition. + */ +void ecc_point_mult_shamir(const struct ecc_point *result, + const u64 *x, const struct ecc_point *p, + const u64 *y, const struct ecc_point *q, + const struct ecc_curve *curve); +#endif -- cgit v1.3-18-gd494 From eaffe377e168d25c52091cf31f5a7a6511897857 Mon Sep 17 00:00:00 2001 From: Daniele Alessandrelli Date: Wed, 20 Oct 2021 11:35:36 +0100 Subject: crypto: ecc - Export additional helper functions Export the following additional ECC helper functions: - ecc_alloc_point() - ecc_free_point() - vli_num_bits() - ecc_point_is_zero() This is done to allow future ECC device drivers to re-use existing code, thus simplifying their implementation. Functions are exported using EXPORT_SYMBOL() (instead of EXPORT_SYMBOL_GPL()) to be consistent with the functions already exported by crypto/ecc.c. Exported functions are documented in include/crypto/internal/ecc.h. Signed-off-by: Daniele Alessandrelli Signed-off-by: Herbert Xu --- crypto/ecc.c | 12 ++++++++---- include/crypto/internal/ecc.h | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) (limited to 'crypto') diff --git a/crypto/ecc.c b/crypto/ecc.c index 80efc9b4eb69..7315217c8f73 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -81,7 +81,7 @@ static void ecc_free_digits_space(u64 *space) kfree_sensitive(space); } -static struct ecc_point *ecc_alloc_point(unsigned int ndigits) +struct ecc_point *ecc_alloc_point(unsigned int ndigits) { struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL); @@ -106,8 +106,9 @@ err_alloc_x: kfree(p); return NULL; } +EXPORT_SYMBOL(ecc_alloc_point); -static void ecc_free_point(struct ecc_point *p) +void ecc_free_point(struct ecc_point *p) { if (!p) return; @@ -116,6 +117,7 @@ static void ecc_free_point(struct ecc_point *p) kfree_sensitive(p->y); kfree_sensitive(p); } +EXPORT_SYMBOL(ecc_free_point); static void vli_clear(u64 *vli, unsigned int ndigits) { @@ -165,7 +167,7 @@ static unsigned int vli_num_digits(const u64 *vli, unsigned int ndigits) } /* Counts the number of bits required for vli. */ -static unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits) +unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits) { unsigned int i, num_digits; u64 digit; @@ -180,6 +182,7 @@ static unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits) return ((num_digits - 1) * 64 + i); } +EXPORT_SYMBOL(vli_num_bits); /* Set dest from unaligned bit string src. */ void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits) @@ -1062,11 +1065,12 @@ EXPORT_SYMBOL(vli_mod_inv); /* ------ Point operations ------ */ /* Returns true if p_point is the point at infinity, false otherwise. */ -static bool ecc_point_is_zero(const struct ecc_point *point) +bool ecc_point_is_zero(const struct ecc_point *point) { return (vli_is_zero(point->x, point->ndigits) && vli_is_zero(point->y, point->ndigits)); } +EXPORT_SYMBOL(ecc_point_is_zero); /* Point multiplication algorithm using Montgomery's ladder with co-Z * coordinates. From https://eprint.iacr.org/2011/338.pdf diff --git a/include/crypto/internal/ecc.h b/include/crypto/internal/ecc.h index 1350e8eb6ac2..4f6c1a68882f 100644 --- a/include/crypto/internal/ecc.h +++ b/include/crypto/internal/ecc.h @@ -225,6 +225,41 @@ void vli_mod_inv(u64 *result, const u64 *input, const u64 *mod, void vli_mod_mult_slow(u64 *result, const u64 *left, const u64 *right, const u64 *mod, unsigned int ndigits); +/** + * vli_num_bits() - Counts the number of bits required for vli. + * + * @vli: vli to check. + * @ndigits: Length of the @vli + * + * Return: The number of bits required to represent @vli. + */ +unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits); + +/** + * ecc_aloc_point() - Allocate ECC point. + * + * @ndigits: Length of vlis in u64 qwords. + * + * Return: Pointer to the allocated point or NULL if allocation failed. + */ +struct ecc_point *ecc_alloc_point(unsigned int ndigits); + +/** + * ecc_free_point() - Free ECC point. + * + * @p: The point to free. + */ +void ecc_free_point(struct ecc_point *p); + +/** + * ecc_point_is_zero() - Check if point is zero. + * + * @p: Point to check for zero. + * + * Return: true if point is the point at infinity, false otherwise. + */ +bool ecc_point_is_zero(const struct ecc_point *point); + /** * ecc_point_mult_shamir() - Add two points multiplied by scalars * @@ -242,4 +277,5 @@ void ecc_point_mult_shamir(const struct ecc_point *result, const u64 *x, const struct ecc_point *p, const u64 *y, const struct ecc_point *q, const struct ecc_curve *curve); + #endif -- cgit v1.3-18-gd494 From 68b6dea802cea0dbdd8bd7ccc60716b5a32a5d8a Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Thu, 21 Oct 2021 14:30:28 -0400 Subject: crypto: pcrypt - Delay write to padata->info These three events can race when pcrypt is used multiple times in a template ("pcrypt(pcrypt(...))"): 1. [taskA] The caller makes the crypto request via crypto_aead_encrypt() 2. [kworkerB] padata serializes the inner pcrypt request 3. [kworkerC] padata serializes the outer pcrypt request 3 might finish before the call to crypto_aead_encrypt() returns in 1, resulting in two possible issues. First, a use-after-free of the crypto request's memory when, for example, taskA writes to the outer pcrypt request's padata->info in pcrypt_aead_enc() after kworkerC completes the request. Second, the outer pcrypt request overwrites the inner pcrypt request's return code with -EINPROGRESS, making a successful request appear to fail. For instance, kworkerB writes the outer pcrypt request's padata->info in pcrypt_aead_done() and then taskA overwrites it in pcrypt_aead_enc(). Avoid both situations by delaying the write of padata->info until after the inner crypto request's return code is checked. This prevents the use-after-free by not touching the crypto request's memory after the next-inner crypto request is made, and stops padata->info from being overwritten. Fixes: 5068c7a883d16 ("crypto: pcrypt - Add pcrypt crypto parallelization wrapper") Reported-by: syzbot+b187b77c8474f9648fae@syzkaller.appspotmail.com Signed-off-by: Daniel Jordan Signed-off-by: Herbert Xu --- crypto/pcrypt.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'crypto') diff --git a/crypto/pcrypt.c b/crypto/pcrypt.c index d569c7ed6c80..9d10b846ccf7 100644 --- a/crypto/pcrypt.c +++ b/crypto/pcrypt.c @@ -78,12 +78,14 @@ static void pcrypt_aead_enc(struct padata_priv *padata) { struct pcrypt_request *preq = pcrypt_padata_request(padata); struct aead_request *req = pcrypt_request_ctx(preq); + int ret; - padata->info = crypto_aead_encrypt(req); + ret = crypto_aead_encrypt(req); - if (padata->info == -EINPROGRESS) + if (ret == -EINPROGRESS) return; + padata->info = ret; padata_do_serial(padata); } @@ -123,12 +125,14 @@ static void pcrypt_aead_dec(struct padata_priv *padata) { struct pcrypt_request *preq = pcrypt_padata_request(padata); struct aead_request *req = pcrypt_request_ctx(preq); + int ret; - padata->info = crypto_aead_decrypt(req); + ret = crypto_aead_decrypt(req); - if (padata->info == -EINPROGRESS) + if (ret == -EINPROGRESS) return; + padata->info = ret; padata_do_serial(padata); } -- cgit v1.3-18-gd494 From 39ef08517082a424b5b65c3dbaa6c0fa9d3303b9 Mon Sep 17 00:00:00 2001 From: Lei He Date: Fri, 22 Oct 2021 20:44:43 +0800 Subject: crypto: testmgr - fix wrong key length for pkcs1pad Fix wrong test data at testmgr.h, it seems to be caused by ignoring the last '\0' when calling sizeof. Signed-off-by: Lei He Signed-off-by: Herbert Xu --- crypto/testmgr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crypto') diff --git a/crypto/testmgr.h b/crypto/testmgr.h index e6fca34b5b25..779720bf9364 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -1201,7 +1201,7 @@ static const struct akcipher_testvec pkcs1pad_rsa_tv_template[] = { "\xd1\x86\x48\x55\xce\x83\xee\x8e\x51\xc7\xde\x32\x12\x47\x7d\x46" "\xb8\x35\xdf\x41\x02\x01\x00\x02\x01\x00\x02\x01\x00\x02\x01\x00" "\x02\x01\x00", - .key_len = 804, + .key_len = 803, /* * m is SHA256 hash of following message: * "\x49\x41\xbe\x0a\x0c\xc9\xf6\x35\x51\xe4\x27\x56\x13\x71\x4b\xd0" -- cgit v1.3-18-gd494