summaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'crypto')
-rw-r--r--crypto/Kconfig2
-rw-r--r--crypto/algapi.c123
-rw-r--r--crypto/api.c50
-rw-r--r--crypto/crypto_engine.c26
-rw-r--r--crypto/drbg.c2
-rw-r--r--crypto/ecc.c14
-rw-r--r--crypto/ecc.h245
-rw-r--r--crypto/ecdh.c2
-rw-r--r--crypto/ecdsa.c2
-rw-r--r--crypto/ecrdsa.c2
-rw-r--r--crypto/ecrdsa_defs.h2
-rw-r--r--crypto/internal.h10
-rw-r--r--crypto/jitterentropy.c24
-rw-r--r--crypto/pcrypt.c12
-rw-r--r--crypto/tcrypt.c5
-rw-r--r--crypto/testmgr.c4
-rw-r--r--crypto/testmgr.h2
17 files changed, 205 insertions, 322 deletions
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
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 43f999dba4dc..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;
@@ -389,29 +404,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 +417,16 @@ 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);
+ 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);
- crypto_wait_for_test(larval);
+ if (test_started)
+ crypto_wait_for_test(larval);
return 0;
}
EXPORT_SYMBOL_GPL(crypto_register_alg);
@@ -632,6 +632,8 @@ int crypto_register_instance(struct crypto_template *tmpl,
larval = __crypto_register_alg(&inst->alg);
if (IS_ERR(larval))
goto unlock;
+ else if (larval)
+ larval->test_started = true;
hlist_add_head(&inst->list, &tmpl->instances);
inst->tmpl = tmpl;
@@ -640,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);
@@ -1261,9 +1263,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 +1313,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..cf0869dd130b 100644
--- a/crypto/api.c
+++ b/crypto/api.c
@@ -12,6 +12,7 @@
#include <linux/err.h>
#include <linux/errno.h>
+#include <linux/jump_label.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/module.h>
@@ -30,6 +31,9 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem);
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);
struct crypto_alg *crypto_mod_get(struct crypto_alg *alg)
@@ -47,11 +51,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 +162,52 @@ 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 (WARN_ON_ONCE(err != NOTIFY_STOP))
+ goto out;
+
+ 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/crypto_engine.c b/crypto/crypto_engine.c
index cff21f4e03e3..fb07da9920ee 100644
--- a/crypto/crypto_engine.c
+++ b/crypto/crypto_engine.c
@@ -328,6 +328,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
* @engine: the hardware engine
@@ -383,6 +396,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
* @engine: the hardware engine
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;
diff --git a/crypto/ecc.c b/crypto/ecc.c
index afc6cefdc1d9..7315217c8f73 100644
--- a/crypto/ecc.c
+++ b/crypto/ecc.c
@@ -32,10 +32,10 @@
#include <linux/fips.h>
#include <crypto/ecdh.h>
#include <crypto/rng.h>
+#include <crypto/internal/ecc.h>
#include <asm/unaligned.h>
#include <linux/ratelimit.h>
-#include "ecc.h"
#include "ecc_curve_defs.h"
typedef struct {
@@ -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/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 <crypto/ecc_curve.h>
-#include <asm/unaligned.h>
-
-/* 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 <linux/module.h>
+#include <crypto/internal/ecc.h>
#include <crypto/internal/kpp.h>
#include <crypto/kpp.h>
#include <crypto/ecdh.h>
#include <linux/scatterlist.h>
-#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 <linux/module.h>
#include <crypto/internal/akcipher.h>
+#include <crypto/internal/ecc.h>
#include <crypto/akcipher.h>
#include <crypto/ecdh.h>
#include <linux/asn1_decoder.h>
#include <linux/scatterlist.h>
-#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 <linux/crypto.h>
#include <crypto/streebog.h>
#include <crypto/internal/akcipher.h>
+#include <crypto/internal/ecc.h>
#include <crypto/akcipher.h>
#include <linux/oid_registry.h>
#include <linux/scatterlist.h>
#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 <crypto/internal/ecc.h>
#define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8)
#define ECRDSA_MAX_DIGITS (512 / 64)
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 <crypto/algapi.h>
#include <linux/completion.h>
+#include <linux/jump_label.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/notifier.h>
@@ -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 */
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<<min));
}
-/**
+/*
* CPU Jitter noise source -- this is the noise source based on the CPU
* execution time jitter
*
@@ -435,7 +435,7 @@ static void jent_lfsr_time(struct rand_data *ec, __u64 time, __u64 loop_cnt,
ec->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
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);
}
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) {
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();
}
/*
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"