3
0
mirror of https://github.com/Qortal/Brooklyn.git synced 2025-01-30 23:02:18 +00:00
This commit is contained in:
Raziel K. Crowe 2022-04-02 17:26:00 +05:00
parent a80f575781
commit a9d5e6067d
29 changed files with 441 additions and 245 deletions

View File

@ -1845,6 +1845,10 @@ config CRYPTO_JITTERENTROPY
random numbers. This Jitterentropy RNG registers with random numbers. This Jitterentropy RNG registers with
the kernel crypto API and can be used by any caller. the kernel crypto API and can be used by any caller.
config CRYPTO_KDF800108_CTR
tristate
select CRYPTO_SHA256
config CRYPTO_USER_API config CRYPTO_USER_API
tristate tristate
@ -1919,7 +1923,6 @@ config CRYPTO_STATS
config CRYPTO_HASH_INFO config CRYPTO_HASH_INFO
bool bool
source "lib/crypto/Kconfig"
source "drivers/crypto/Kconfig" source "drivers/crypto/Kconfig"
source "crypto/asymmetric_keys/Kconfig" source "crypto/asymmetric_keys/Kconfig"
source "certs/Kconfig" source "certs/Kconfig"

View File

@ -119,6 +119,8 @@ CFLAGS_aegis128-neon-inner.o += $(aegis128-cflags-y)
CFLAGS_REMOVE_aegis128-neon-inner.o += -mgeneral-regs-only CFLAGS_REMOVE_aegis128-neon-inner.o += -mgeneral-regs-only
aegis128-$(CONFIG_CRYPTO_AEGIS128_SIMD) += aegis128-neon.o aegis128-neon-inner.o aegis128-$(CONFIG_CRYPTO_AEGIS128_SIMD) += aegis128-neon.o aegis128-neon-inner.o
endif endif
# Enable <arm_neon.h>
CFLAGS_aegis128-neon-inner.o += -isystem $(shell $(CC) -print-file-name=include)
obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
@ -198,3 +200,8 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o
crypto_simd-y := simd.o crypto_simd-y := simd.o
obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o
#
# Key derivation function
#
obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o

View File

@ -25,12 +25,9 @@ struct alg_type_list {
struct list_head list; struct list_head list;
}; };
static atomic_long_t alg_memory_allocated;
static struct proto alg_proto = { static struct proto alg_proto = {
.name = "ALG", .name = "ALG",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.memory_allocated = &alg_memory_allocated,
.obj_size = sizeof(struct alg_sock), .obj_size = sizeof(struct alg_sock),
}; };
@ -931,16 +928,19 @@ int af_alg_sendmsg(struct socket *sock, struct msghdr *msg, size_t size,
sg_unmark_end(sg + sgl->cur - 1); sg_unmark_end(sg + sgl->cur - 1);
do { do {
struct page *pg;
unsigned int i = sgl->cur; unsigned int i = sgl->cur;
plen = min_t(size_t, len, PAGE_SIZE); plen = min_t(size_t, len, PAGE_SIZE);
sg_assign_page(sg + i, alloc_page(GFP_KERNEL)); pg = alloc_page(GFP_KERNEL);
if (!sg_page(sg + i)) { if (!pg) {
err = -ENOMEM; err = -ENOMEM;
goto unlock; goto unlock;
} }
sg_assign_page(sg + i, pg);
err = memcpy_from_msg(page_address(sg_page(sg + i)), err = memcpy_from_msg(page_address(sg_page(sg + i)),
msg, plen); msg, plen);
if (err) { if (err) {
@ -1076,7 +1076,7 @@ void af_alg_async_cb(struct crypto_async_request *_req, int err)
af_alg_free_resources(areq); af_alg_free_resources(areq);
sock_put(sk); sock_put(sk);
iocb->ki_complete(iocb, err ? err : (int)resultlen, 0); iocb->ki_complete(iocb, err ? err : (int)resultlen);
} }
EXPORT_SYMBOL_GPL(af_alg_async_cb); EXPORT_SYMBOL_GPL(af_alg_async_cb);

View File

@ -216,6 +216,32 @@ void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
} }
EXPORT_SYMBOL_GPL(crypto_remove_spawns); 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) static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
{ {
struct crypto_alg *q; struct crypto_alg *q;
@ -250,31 +276,22 @@ static struct crypto_larval *__crypto_register_alg(struct crypto_alg *alg)
goto err; goto err;
} }
larval = crypto_larval_alloc(alg->cra_name, larval = crypto_alloc_test_larval(alg);
alg->cra_flags | CRYPTO_ALG_TESTED, 0);
if (IS_ERR(larval)) if (IS_ERR(larval))
goto out; 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(&alg->cra_list, &crypto_alg_list);
if (larval)
list_add(&larval->alg.cra_list, &crypto_alg_list); list_add(&larval->alg.cra_list, &crypto_alg_list);
else
alg->cra_flags |= CRYPTO_ALG_TESTED;
crypto_stats_init(alg); crypto_stats_init(alg);
out: out:
return larval; return larval;
free_larval:
kfree(larval);
err: err:
larval = ERR_PTR(ret); larval = ERR_PTR(ret);
goto out; goto out;
@ -389,29 +406,10 @@ void crypto_remove_final(struct list_head *list)
} }
EXPORT_SYMBOL_GPL(crypto_remove_final); 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) int crypto_register_alg(struct crypto_alg *alg)
{ {
struct crypto_larval *larval; struct crypto_larval *larval;
bool test_started;
int err; int err;
alg->cra_flags &= ~CRYPTO_ALG_DEAD; alg->cra_flags &= ~CRYPTO_ALG_DEAD;
@ -421,11 +419,15 @@ int crypto_register_alg(struct crypto_alg *alg)
down_write(&crypto_alg_sem); down_write(&crypto_alg_sem);
larval = __crypto_register_alg(alg); 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); up_write(&crypto_alg_sem);
if (IS_ERR(larval)) if (IS_ERR_OR_NULL(larval))
return PTR_ERR(larval); return PTR_ERR(larval);
if (test_started)
crypto_wait_for_test(larval); crypto_wait_for_test(larval);
return 0; return 0;
} }
@ -632,6 +634,8 @@ int crypto_register_instance(struct crypto_template *tmpl,
larval = __crypto_register_alg(&inst->alg); larval = __crypto_register_alg(&inst->alg);
if (IS_ERR(larval)) if (IS_ERR(larval))
goto unlock; goto unlock;
else if (larval)
larval->test_started = true;
hlist_add_head(&inst->list, &tmpl->instances); hlist_add_head(&inst->list, &tmpl->instances);
inst->tmpl = tmpl; inst->tmpl = tmpl;
@ -640,7 +644,7 @@ int crypto_register_instance(struct crypto_template *tmpl,
up_write(&crypto_alg_sem); up_write(&crypto_alg_sem);
err = PTR_ERR(larval); err = PTR_ERR(larval);
if (IS_ERR(larval)) if (IS_ERR_OR_NULL(larval))
goto err; goto err;
crypto_wait_for_test(larval); crypto_wait_for_test(larval);
@ -1261,9 +1265,48 @@ void crypto_stats_skcipher_decrypt(unsigned int cryptlen, int ret,
EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt); EXPORT_SYMBOL_GPL(crypto_stats_skcipher_decrypt);
#endif #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) static int __init crypto_algapi_init(void)
{ {
crypto_init_proc(); crypto_init_proc();
crypto_start_tests();
return 0; return 0;
} }
@ -1272,7 +1315,11 @@ static void __exit crypto_algapi_exit(void)
crypto_exit_proc(); 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_exit(crypto_algapi_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");

View File

@ -67,7 +67,7 @@ static int cryptomgr_probe(void *data)
complete_all(&param->larval->completion); complete_all(&param->larval->completion);
crypto_alg_put(&param->larval->alg); crypto_alg_put(&param->larval->alg);
kfree(param); kfree(param);
module_put_and_exit(0); module_put_and_kthread_exit(0);
} }
static int cryptomgr_schedule_probe(struct crypto_larval *larval) static int cryptomgr_schedule_probe(struct crypto_larval *larval)
@ -190,7 +190,7 @@ static int cryptomgr_test(void *data)
crypto_alg_tested(param->driver, err); crypto_alg_tested(param->driver, err);
kfree(param); kfree(param);
module_put_and_exit(0); module_put_and_kthread_exit(0);
} }
static int cryptomgr_schedule_test(struct crypto_alg *alg) static int cryptomgr_schedule_test(struct crypto_alg *alg)

View File

@ -12,6 +12,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/jump_label.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/module.h> #include <linux/module.h>
@ -30,6 +31,9 @@ EXPORT_SYMBOL_GPL(crypto_alg_sem);
BLOCKING_NOTIFIER_HEAD(crypto_chain); BLOCKING_NOTIFIER_HEAD(crypto_chain);
EXPORT_SYMBOL_GPL(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); static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg);
struct crypto_alg *crypto_mod_get(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); 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, static struct crypto_alg *__crypto_alg_lookup(const char *name, u32 type,
u32 mask) u32 mask)
{ {
@ -163,11 +162,52 @@ void crypto_larval_kill(struct crypto_alg *alg)
} }
EXPORT_SYMBOL_GPL(crypto_larval_kill); 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) static struct crypto_alg *crypto_larval_wait(struct crypto_alg *alg)
{ {
struct crypto_larval *larval = (void *)alg; struct crypto_larval *larval = (void *)alg;
long timeout; long timeout;
if (!static_branch_likely(&crypto_boot_test_finished))
crypto_start_test(larval);
timeout = wait_for_completion_killable_timeout( timeout = wait_for_completion_killable_timeout(
&larval->completion, 60 * HZ); &larval->completion, 60 * HZ);

View File

@ -36,16 +36,23 @@ static DECLARE_RWSEM(asymmetric_key_parsers_sem);
* find_asymmetric_key - Find a key by ID. * find_asymmetric_key - Find a key by ID.
* @keyring: The keys to search. * @keyring: The keys to search.
* @id_0: The first ID to look for or NULL. * @id_0: The first ID to look for or NULL.
* @id_1: The second ID to look for or NULL. * @id_1: The second ID to look for or NULL, matched together with @id_0
* @partial: Use partial match if true, exact if false. * against @keyring keys' id[0] and id[1].
* @id_2: The fallback ID to match against @keyring keys' id[2] if both of the
* other IDs are NULL.
* @partial: Use partial match for @id_0 and @id_1 if true, exact if false.
* *
* Find a key in the given keyring by identifier. The preferred identifier is * Find a key in the given keyring by identifier. The preferred identifier is
* the id_0 and the fallback identifier is the id_1. If both are given, the * the id_0 and the fallback identifier is the id_1. If both are given, the
* lookup is by the former, but the latter must also match. * former is matched (exactly or partially) against either of the sought key's
* identifiers and the latter must match the found key's second identifier
* exactly. If both are missing, id_2 must match the sought key's third
* identifier exactly.
*/ */
struct key *find_asymmetric_key(struct key *keyring, struct key *find_asymmetric_key(struct key *keyring,
const struct asymmetric_key_id *id_0, const struct asymmetric_key_id *id_0,
const struct asymmetric_key_id *id_1, const struct asymmetric_key_id *id_1,
const struct asymmetric_key_id *id_2,
bool partial) bool partial)
{ {
struct key *key; struct key *key;
@ -54,14 +61,17 @@ struct key *find_asymmetric_key(struct key *keyring,
char *req, *p; char *req, *p;
int len; int len;
BUG_ON(!id_0 && !id_1); WARN_ON(!id_0 && !id_1 && !id_2);
if (id_0) { if (id_0) {
lookup = id_0->data; lookup = id_0->data;
len = id_0->len; len = id_0->len;
} else { } else if (id_1) {
lookup = id_1->data; lookup = id_1->data;
len = id_1->len; len = id_1->len;
} else {
lookup = id_2->data;
len = id_2->len;
} }
/* Construct an identifier "id:<keyid>". */ /* Construct an identifier "id:<keyid>". */
@ -69,7 +79,10 @@ struct key *find_asymmetric_key(struct key *keyring,
if (!req) if (!req)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
if (partial) { if (!id_0 && !id_1) {
*p++ = 'd';
*p++ = 'n';
} else if (partial) {
*p++ = 'i'; *p++ = 'i';
*p++ = 'd'; *p++ = 'd';
} else { } else {
@ -185,8 +198,8 @@ bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
EXPORT_SYMBOL_GPL(asymmetric_key_id_partial); EXPORT_SYMBOL_GPL(asymmetric_key_id_partial);
/** /**
* asymmetric_match_key_ids - Search asymmetric key IDs * asymmetric_match_key_ids - Search asymmetric key IDs 1 & 2
* @kids: The list of key IDs to check * @kids: The pair of key IDs to check
* @match_id: The key ID we're looking for * @match_id: The key ID we're looking for
* @match: The match function to use * @match: The match function to use
*/ */
@ -200,7 +213,7 @@ static bool asymmetric_match_key_ids(
if (!kids || !match_id) if (!kids || !match_id)
return false; return false;
for (i = 0; i < ARRAY_SIZE(kids->id); i++) for (i = 0; i < 2; i++)
if (match(kids->id[i], match_id)) if (match(kids->id[i], match_id))
return true; return true;
return false; return false;
@ -244,7 +257,7 @@ struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
} }
/* /*
* Match asymmetric keys by an exact match on an ID. * Match asymmetric keys by an exact match on one of the first two IDs.
*/ */
static bool asymmetric_key_cmp(const struct key *key, static bool asymmetric_key_cmp(const struct key *key,
const struct key_match_data *match_data) const struct key_match_data *match_data)
@ -257,7 +270,7 @@ static bool asymmetric_key_cmp(const struct key *key,
} }
/* /*
* Match asymmetric keys by a partial match on an IDs. * Match asymmetric keys by a partial match on one of the first two IDs.
*/ */
static bool asymmetric_key_cmp_partial(const struct key *key, static bool asymmetric_key_cmp_partial(const struct key *key,
const struct key_match_data *match_data) const struct key_match_data *match_data)
@ -269,6 +282,18 @@ static bool asymmetric_key_cmp_partial(const struct key *key,
asymmetric_key_id_partial); asymmetric_key_id_partial);
} }
/*
* Match asymmetric keys by an exact match on the third IDs.
*/
static bool asymmetric_key_cmp_name(const struct key *key,
const struct key_match_data *match_data)
{
const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
const struct asymmetric_key_id *match_id = match_data->preparsed;
return kids && asymmetric_key_id_same(kids->id[2], match_id);
}
/* /*
* Preparse the match criterion. If we don't set lookup_type and cmp, * Preparse the match criterion. If we don't set lookup_type and cmp,
* the default will be an exact match on the key description. * the default will be an exact match on the key description.
@ -276,8 +301,9 @@ static bool asymmetric_key_cmp_partial(const struct key *key,
* There are some specifiers for matching key IDs rather than by the key * There are some specifiers for matching key IDs rather than by the key
* description: * description:
* *
* "id:<id>" - find a key by partial match on any available ID * "id:<id>" - find a key by partial match on one of the first two IDs
* "ex:<id>" - find a key by exact match on any available ID * "ex:<id>" - find a key by exact match on one of the first two IDs
* "dn:<id>" - find a key by exact match on the third ID
* *
* These have to be searched by iteration rather than by direct lookup because * These have to be searched by iteration rather than by direct lookup because
* the key is hashed according to its description. * the key is hashed according to its description.
@ -301,6 +327,11 @@ static int asymmetric_key_match_preparse(struct key_match_data *match_data)
spec[1] == 'x' && spec[1] == 'x' &&
spec[2] == ':') { spec[2] == ':') {
id = spec + 3; id = spec + 3;
} else if (spec[0] == 'd' &&
spec[1] == 'n' &&
spec[2] == ':') {
id = spec + 3;
cmp = asymmetric_key_cmp_name;
} else { } else {
goto default_match; goto default_match;
} }

View File

@ -48,7 +48,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
* keys. * keys.
*/ */
key = find_asymmetric_key(trust_keyring, key = find_asymmetric_key(trust_keyring,
x509->id, x509->skid, false); x509->id, x509->skid, NULL, false);
if (!IS_ERR(key)) { if (!IS_ERR(key)) {
/* One of the X.509 certificates in the PKCS#7 message /* One of the X.509 certificates in the PKCS#7 message
* is apparently the same as one we already trust. * is apparently the same as one we already trust.
@ -82,7 +82,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
key = find_asymmetric_key(trust_keyring, key = find_asymmetric_key(trust_keyring,
last->sig->auth_ids[0], last->sig->auth_ids[0],
last->sig->auth_ids[1], last->sig->auth_ids[1],
false); NULL, false);
if (!IS_ERR(key)) { if (!IS_ERR(key)) {
x509 = last; x509 = last;
pr_devel("sinfo %u: Root cert %u signer is key %x\n", pr_devel("sinfo %u: Root cert %u signer is key %x\n",
@ -97,7 +97,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
* the signed info directly. * the signed info directly.
*/ */
key = find_asymmetric_key(trust_keyring, key = find_asymmetric_key(trust_keyring,
sinfo->sig->auth_ids[0], NULL, false); sinfo->sig->auth_ids[0], NULL, NULL, false);
if (!IS_ERR(key)) { if (!IS_ERR(key)) {
pr_devel("sinfo %u: Direct signer is key %x\n", pr_devel("sinfo %u: Direct signer is key %x\n",
sinfo->index, key_serial(key)); sinfo->index, key_serial(key));

View File

@ -87,7 +87,7 @@ int restrict_link_by_signature(struct key *dest_keyring,
sig = payload->data[asym_auth]; sig = payload->data[asym_auth];
if (!sig) if (!sig)
return -ENOPKG; return -ENOPKG;
if (!sig->auth_ids[0] && !sig->auth_ids[1]) if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
return -ENOKEY; return -ENOKEY;
if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid)) if (ca_keyid && !asymmetric_key_id_partial(sig->auth_ids[1], ca_keyid))
@ -96,7 +96,7 @@ int restrict_link_by_signature(struct key *dest_keyring,
/* See if we have a key that signed this one. */ /* See if we have a key that signed this one. */
key = find_asymmetric_key(trust_keyring, key = find_asymmetric_key(trust_keyring,
sig->auth_ids[0], sig->auth_ids[1], sig->auth_ids[0], sig->auth_ids[1],
false); sig->auth_ids[2], false);
if (IS_ERR(key)) if (IS_ERR(key))
return -ENOKEY; return -ENOKEY;
@ -108,11 +108,11 @@ int restrict_link_by_signature(struct key *dest_keyring,
return ret; return ret;
} }
static bool match_either_id(const struct asymmetric_key_ids *pair, static bool match_either_id(const struct asymmetric_key_id **pair,
const struct asymmetric_key_id *single) const struct asymmetric_key_id *single)
{ {
return (asymmetric_key_id_same(pair->id[0], single) || return (asymmetric_key_id_same(pair[0], single) ||
asymmetric_key_id_same(pair->id[1], single)); asymmetric_key_id_same(pair[1], single));
} }
static int key_or_keyring_common(struct key *dest_keyring, static int key_or_keyring_common(struct key *dest_keyring,
@ -140,20 +140,22 @@ static int key_or_keyring_common(struct key *dest_keyring,
sig = payload->data[asym_auth]; sig = payload->data[asym_auth];
if (!sig) if (!sig)
return -ENOPKG; return -ENOPKG;
if (!sig->auth_ids[0] && !sig->auth_ids[1]) if (!sig->auth_ids[0] && !sig->auth_ids[1] && !sig->auth_ids[2])
return -ENOKEY; return -ENOKEY;
if (trusted) { if (trusted) {
if (trusted->type == &key_type_keyring) { if (trusted->type == &key_type_keyring) {
/* See if we have a key that signed this one. */ /* See if we have a key that signed this one. */
key = find_asymmetric_key(trusted, sig->auth_ids[0], key = find_asymmetric_key(trusted, sig->auth_ids[0],
sig->auth_ids[1], false); sig->auth_ids[1],
sig->auth_ids[2], false);
if (IS_ERR(key)) if (IS_ERR(key))
key = NULL; key = NULL;
} else if (trusted->type == &key_type_asymmetric) { } else if (trusted->type == &key_type_asymmetric) {
const struct asymmetric_key_ids *signer_ids; const struct asymmetric_key_id **signer_ids;
signer_ids = asymmetric_key_ids(trusted); signer_ids = (const struct asymmetric_key_id **)
asymmetric_key_ids(trusted)->id;
/* /*
* The auth_ids come from the candidate key (the * The auth_ids come from the candidate key (the
@ -164,22 +166,29 @@ static int key_or_keyring_common(struct key *dest_keyring,
* The signer_ids are identifiers for the * The signer_ids are identifiers for the
* signing key specified for dest_keyring. * signing key specified for dest_keyring.
* *
* The first auth_id is the preferred id, and * The first auth_id is the preferred id, 2nd and
* the second is the fallback. If only one * 3rd are the fallbacks. If exactly one of
* auth_id is present, it may match against * auth_ids[0] and auth_ids[1] is present, it may
* either signer_id. If two auth_ids are * match either signer_ids[0] or signed_ids[1].
* present, the first auth_id must match one * If both are present the first one may match
* signer_id and the second auth_id must match * either signed_id but the second one must match
* the second signer_id. * the second signer_id. If neither of them is
* available, auth_ids[2] is matched against
* signer_ids[2] as a fallback.
*/ */
if (!sig->auth_ids[0] || !sig->auth_ids[1]) { if (!sig->auth_ids[0] && !sig->auth_ids[1]) {
if (asymmetric_key_id_same(signer_ids[2],
sig->auth_ids[2]))
key = __key_get(trusted);
} else if (!sig->auth_ids[0] || !sig->auth_ids[1]) {
const struct asymmetric_key_id *auth_id; const struct asymmetric_key_id *auth_id;
auth_id = sig->auth_ids[0] ?: sig->auth_ids[1]; auth_id = sig->auth_ids[0] ?: sig->auth_ids[1];
if (match_either_id(signer_ids, auth_id)) if (match_either_id(signer_ids, auth_id))
key = __key_get(trusted); key = __key_get(trusted);
} else if (asymmetric_key_id_same(signer_ids->id[1], } else if (asymmetric_key_id_same(signer_ids[1],
sig->auth_ids[1]) && sig->auth_ids[1]) &&
match_either_id(signer_ids, match_either_id(signer_ids,
sig->auth_ids[0])) { sig->auth_ids[0])) {
@ -193,7 +202,8 @@ static int key_or_keyring_common(struct key *dest_keyring,
if (check_dest && !key) { if (check_dest && !key) {
/* See if the destination has a key that signed this one. */ /* See if the destination has a key that signed this one. */
key = find_asymmetric_key(dest_keyring, sig->auth_ids[0], key = find_asymmetric_key(dest_keyring, sig->auth_ids[0],
sig->auth_ids[1], false); sig->auth_ids[1], sig->auth_ids[2],
false);
if (IS_ERR(key)) if (IS_ERR(key))
key = NULL; key = NULL;
} }

View File

@ -441,8 +441,18 @@ int x509_note_issuer(void *context, size_t hdrlen,
const void *value, size_t vlen) const void *value, size_t vlen)
{ {
struct x509_parse_context *ctx = context; struct x509_parse_context *ctx = context;
struct asymmetric_key_id *kid;
ctx->cert->raw_issuer = value; ctx->cert->raw_issuer = value;
ctx->cert->raw_issuer_size = vlen; ctx->cert->raw_issuer_size = vlen;
if (!ctx->cert->sig->auth_ids[2]) {
kid = asymmetric_key_generate_id(value, vlen, "", 0);
if (IS_ERR(kid))
return PTR_ERR(kid);
ctx->cert->sig->auth_ids[2] = kid;
}
return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen); return x509_fabricate_name(ctx, hdrlen, tag, &ctx->cert->issuer, vlen);
} }

View File

@ -223,6 +223,13 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
goto error_free_desc; goto error_free_desc;
kids->id[0] = cert->id; kids->id[0] = cert->id;
kids->id[1] = cert->skid; kids->id[1] = cert->skid;
kids->id[2] = asymmetric_key_generate_id(cert->raw_subject,
cert->raw_subject_size,
"", 0);
if (IS_ERR(kids->id[2])) {
ret = PTR_ERR(kids->id[2]);
goto error_free_kids;
}
/* We're pinning the module by being linked against it */ /* We're pinning the module by being linked against it */
__module_get(public_key_subtype.owner); __module_get(public_key_subtype.owner);
@ -239,8 +246,11 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
cert->skid = NULL; cert->skid = NULL;
cert->sig = NULL; cert->sig = NULL;
desc = NULL; desc = NULL;
kids = NULL;
ret = 0; ret = 0;
error_free_kids:
kfree(kids);
error_free_desc: error_free_desc:
kfree(desc); kfree(desc);
error_free_cert: error_free_cert:

View File

@ -15,12 +15,12 @@
static int crypto_blake2s_update_generic(struct shash_desc *desc, static int crypto_blake2s_update_generic(struct shash_desc *desc,
const u8 *in, unsigned int inlen) const u8 *in, unsigned int inlen)
{ {
return crypto_blake2s_update(desc, in, inlen, blake2s_compress_generic); return crypto_blake2s_update(desc, in, inlen, true);
} }
static int crypto_blake2s_final_generic(struct shash_desc *desc, u8 *out) static int crypto_blake2s_final_generic(struct shash_desc *desc, u8 *out)
{ {
return crypto_blake2s_final(desc, out, blake2s_compress_generic); return crypto_blake2s_final(desc, out, true);
} }
#define BLAKE2S_ALG(name, driver_name, digest_size) \ #define BLAKE2S_ALG(name, driver_name, digest_size) \

View File

@ -327,6 +327,19 @@ int crypto_transfer_hash_request_to_engine(struct crypto_engine *engine,
} }
EXPORT_SYMBOL_GPL(crypto_transfer_hash_request_to_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 * crypto_transfer_skcipher_request_to_engine - transfer one skcipher_request
* to list into the engine queue * 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); 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 * crypto_finalize_skcipher_request - finalize one skcipher_request if
* the request is done * the request is done

View File

@ -5,11 +5,11 @@
* Authors: Salvatore Benedetto <salvatore.benedetto@intel.com> * Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
*/ */
#include <linux/fips.h>
#include <linux/module.h> #include <linux/module.h>
#include <crypto/internal/kpp.h> #include <crypto/internal/kpp.h>
#include <crypto/kpp.h> #include <crypto/kpp.h>
#include <crypto/dh.h> #include <crypto/dh.h>
#include <linux/fips.h>
#include <linux/mpi.h> #include <linux/mpi.h>
struct dh_ctx { 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) 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; return (p_len < 1536) ? -EINVAL : 0;
} }

View File

@ -100,6 +100,7 @@
#include <crypto/drbg.h> #include <crypto/drbg.h>
#include <crypto/internal/cipher.h> #include <crypto/internal/cipher.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/jiffies.h>
/*************************************************************** /***************************************************************
* Backend cipher definitions available to DRBG * 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, 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); int ret = drbg->d_ops->update(drbg, seed, reseed);
if (ret) if (ret)
return 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 */ /* 10.1.1.2 / 10.1.1.3 step 5 */
drbg->reseed_ctr = 1; 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; return ret;
} }
@ -1066,12 +1089,10 @@ static inline int drbg_get_random_bytes(struct drbg_state *drbg,
return 0; 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; struct drbg_string data;
LIST_HEAD(seedlist); 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 int entropylen = drbg_sec_strength(drbg->core->flags);
unsigned char entropy[32]; unsigned char entropy[32];
int ret; int ret;
@ -1082,26 +1103,35 @@ static void drbg_async_seed(struct work_struct *work)
drbg_string_fill(&data, entropy, entropylen); drbg_string_fill(&data, entropy, entropylen);
list_add_tail(&data.list, &seedlist); list_add_tail(&data.list, &seedlist);
mutex_lock(&drbg->drbg_mutex);
ret = drbg_get_random_bytes(drbg, entropy, entropylen); ret = drbg_get_random_bytes(drbg, entropy, entropylen);
if (ret) if (ret)
goto unlock; goto out;
/* Set seeded to false so that if __drbg_seed fails the ret = __drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
* next generate call will trigger a reseed.
*/
drbg->seeded = false;
__drbg_seed(drbg, &seedlist, true);
if (drbg->seeded)
drbg->reseed_threshold = drbg_max_requests(drbg);
unlock:
mutex_unlock(&drbg->drbg_mutex);
out:
memzero_explicit(entropy, entropylen); memzero_explicit(entropy, entropylen);
return ret;
}
static bool drbg_nopr_reseed_interval_elapsed(struct drbg_state *drbg)
{
unsigned long next_reseed;
/* Don't ever reseed from get_random_bytes() in test mode. */
if (list_empty(&drbg->test_data.list))
return false;
/*
* 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); unsigned int entropylen = drbg_sec_strength(drbg->core->flags);
struct drbg_string data1; struct drbg_string data1;
LIST_HEAD(seedlist); LIST_HEAD(seedlist);
enum drbg_seed_state new_seed_state = DRBG_SEED_STATE_FULL;
/* 9.1 / 9.2 / 9.3.1 step 3 */ /* 9.1 / 9.2 / 9.3.1 step 3 */
if (pers && pers->len > (drbg_max_addtl(drbg))) { 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)); BUG_ON((entropylen * 2) > sizeof(entropy));
/* Get seed from in-kernel /dev/urandom */ /* 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); ret = drbg_get_random_bytes(drbg, entropy, entropylen);
if (ret) if (ret)
goto out; 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", pr_devel("DRBG: (re)seeding with %u bytes of entropy\n",
entropylen); entropylen);
} else { } 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, ret = crypto_rng_get_bytes(drbg->jent,
entropy + entropylen, entropy + entropylen,
entropylen); entropylen);
if (ret) { if (fips_enabled && ret) {
pr_devel("DRBG: jent failed with %d\n", 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)); memset(drbg->C, 0, drbg_statelen(drbg));
} }
ret = __drbg_seed(drbg, &seedlist, reseed); ret = __drbg_seed(drbg, &seedlist, reseed, new_seed_state);
out: out:
memzero_explicit(entropy, entropylen * 2); 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. * here. The spec is a bit convoluted here, we make it simpler.
*/ */
if (drbg->reseed_threshold < drbg->reseed_ctr) 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 " pr_devel("DRBG: reseeding before generation (prediction "
"resistance: %s, state %s)\n", "resistance: %s, state %s)\n",
drbg->pr ? "true" : "false", 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 */ /* 9.3.1 steps 7.1 through 7.3 */
len = drbg_seed(drbg, addtl, true); len = drbg_seed(drbg, addtl, true);
if (len) if (len)
goto err; goto err;
/* 9.3.1 step 7.4 */ /* 9.3.1 step 7.4 */
addtl = NULL; 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) if (addtl && 0 < addtl->len)
@ -1491,51 +1535,23 @@ static int drbg_generate_long(struct drbg_state *drbg,
return 0; 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) static int drbg_prepare_hrng(struct drbg_state *drbg)
{ {
int err;
/* We do not need an HRNG in test mode. */ /* We do not need an HRNG in test mode. */
if (list_empty(&drbg->test_data.list)) if (list_empty(&drbg->test_data.list))
return 0; return 0;
drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 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->jent = NULL;
if (fips_enabled || err != -ENOENT)
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; return err;
pr_info("DRBG: Continuing without Jitter RNG\n");
} }
/* return 0;
* Require frequent reseeds until the seed source is fully
* initialized.
*/
drbg->reseed_threshold = 50;
return err;
} }
/* /*
@ -1578,7 +1594,8 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
if (!drbg->core) { if (!drbg->core) {
drbg->core = &drbg_cores[coreref]; drbg->core = &drbg_cores[coreref];
drbg->pr = pr; drbg->pr = pr;
drbg->seeded = false; drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
drbg->last_seed_time = 0;
drbg->reseed_threshold = drbg_max_requests(drbg); drbg->reseed_threshold = drbg_max_requests(drbg);
ret = drbg_alloc_state(drbg); ret = drbg_alloc_state(drbg);
@ -1589,14 +1606,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
if (ret) if (ret)
goto free_everything; 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; reseed = false;
} }
@ -1629,11 +1638,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
*/ */
static int drbg_uninstantiate(struct drbg_state *drbg) 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)) if (!IS_ERR_OR_NULL(drbg->jent))
crypto_free_rng(drbg->jent); crypto_free_rng(drbg->jent);
drbg->jent = NULL; drbg->jent = NULL;
@ -2003,7 +2007,7 @@ static inline int __init drbg_healthcheck_sanity(void)
#define OUTBUFLEN 16 #define OUTBUFLEN 16
unsigned char buf[OUTBUFLEN]; unsigned char buf[OUTBUFLEN];
struct drbg_state *drbg = NULL; struct drbg_state *drbg = NULL;
int ret = -EFAULT; int ret;
int rc = -EFAULT; int rc = -EFAULT;
bool pr = false; bool pr = false;
int coreref = 0; int coreref = 0;

View File

@ -32,10 +32,10 @@
#include <linux/fips.h> #include <linux/fips.h>
#include <crypto/ecdh.h> #include <crypto/ecdh.h>
#include <crypto/rng.h> #include <crypto/rng.h>
#include <crypto/internal/ecc.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/ratelimit.h> #include <linux/ratelimit.h>
#include "ecc.h"
#include "ecc_curve_defs.h" #include "ecc_curve_defs.h"
typedef struct { typedef struct {
@ -81,7 +81,7 @@ static void ecc_free_digits_space(u64 *space)
kfree_sensitive(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); struct ecc_point *p = kmalloc(sizeof(*p), GFP_KERNEL);
@ -106,8 +106,9 @@ static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
kfree(p); kfree(p);
return NULL; 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) if (!p)
return; return;
@ -116,6 +117,7 @@ static void ecc_free_point(struct ecc_point *p)
kfree_sensitive(p->y); kfree_sensitive(p->y);
kfree_sensitive(p); kfree_sensitive(p);
} }
EXPORT_SYMBOL(ecc_free_point);
static void vli_clear(u64 *vli, unsigned int ndigits) 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. */ /* 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; unsigned int i, num_digits;
u64 digit; u64 digit;
@ -180,6 +182,7 @@ static unsigned int vli_num_bits(const u64 *vli, unsigned int ndigits)
return ((num_digits - 1) * 64 + i); return ((num_digits - 1) * 64 + i);
} }
EXPORT_SYMBOL(vli_num_bits);
/* Set dest from unaligned bit string src. */ /* Set dest from unaligned bit string src. */
void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits) void vli_from_be64(u64 *dest, const void *src, unsigned int ndigits)
@ -1062,11 +1065,12 @@ EXPORT_SYMBOL(vli_mod_inv);
/* ------ Point operations ------ */ /* ------ Point operations ------ */
/* Returns true if p_point is the point at infinity, false otherwise. */ /* 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) && return (vli_is_zero(point->x, point->ndigits) &&
vli_is_zero(point->y, 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 /* Point multiplication algorithm using Montgomery's ladder with co-Z
* coordinates. From https://eprint.iacr.org/2011/338.pdf * coordinates. From https://eprint.iacr.org/2011/338.pdf

View File

@ -6,11 +6,11 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <crypto/internal/ecc.h>
#include <crypto/internal/kpp.h> #include <crypto/internal/kpp.h>
#include <crypto/kpp.h> #include <crypto/kpp.h>
#include <crypto/ecdh.h> #include <crypto/ecdh.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include "ecc.h"
struct ecdh_ctx { struct ecdh_ctx {
unsigned int curve_id; unsigned int curve_id;

View File

@ -5,12 +5,12 @@
#include <linux/module.h> #include <linux/module.h>
#include <crypto/internal/akcipher.h> #include <crypto/internal/akcipher.h>
#include <crypto/internal/ecc.h>
#include <crypto/akcipher.h> #include <crypto/akcipher.h>
#include <crypto/ecdh.h> #include <crypto/ecdh.h>
#include <linux/asn1_decoder.h> #include <linux/asn1_decoder.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include "ecc.h"
#include "ecdsasignature.asn1.h" #include "ecdsasignature.asn1.h"
struct ecc_ctx { struct ecc_ctx {

View File

@ -20,12 +20,12 @@
#include <linux/crypto.h> #include <linux/crypto.h>
#include <crypto/streebog.h> #include <crypto/streebog.h>
#include <crypto/internal/akcipher.h> #include <crypto/internal/akcipher.h>
#include <crypto/internal/ecc.h>
#include <crypto/akcipher.h> #include <crypto/akcipher.h>
#include <linux/oid_registry.h> #include <linux/oid_registry.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include "ecrdsa_params.asn1.h" #include "ecrdsa_params.asn1.h"
#include "ecrdsa_pub_key.asn1.h" #include "ecrdsa_pub_key.asn1.h"
#include "ecc.h"
#include "ecrdsa_defs.h" #include "ecrdsa_defs.h"
#define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8) #define ECRDSA_MAX_SIG_SIZE (2 * 512 / 8)

View File

@ -13,7 +13,7 @@
#ifndef _CRYTO_ECRDSA_DEFS_H #ifndef _CRYTO_ECRDSA_DEFS_H
#define _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_SIG_SIZE (2 * 512 / 8)
#define ECRDSA_MAX_DIGITS (512 / 64) #define ECRDSA_MAX_DIGITS (512 / 64)

View File

@ -10,6 +10,7 @@
#include <crypto/algapi.h> #include <crypto/algapi.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/jump_label.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/notifier.h> #include <linux/notifier.h>
@ -27,6 +28,7 @@ struct crypto_larval {
struct crypto_alg *adult; struct crypto_alg *adult;
struct completion completion; struct completion completion;
u32 mask; u32 mask;
bool test_started;
}; };
enum { enum {
@ -45,6 +47,8 @@ extern struct list_head crypto_alg_list;
extern struct rw_semaphore crypto_alg_sem; extern struct rw_semaphore crypto_alg_sem;
extern struct blocking_notifier_head crypto_chain; extern struct blocking_notifier_head crypto_chain;
DECLARE_STATIC_KEY_FALSE(crypto_boot_test_finished);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
void __init crypto_init_proc(void); void __init crypto_init_proc(void);
void __exit crypto_exit_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); struct crypto_larval *crypto_larval_alloc(const char *name, u32 type, u32 mask);
void crypto_larval_kill(struct crypto_alg *alg); 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_alg_tested(const char *name, int err);
void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list, 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(); cond_resched();
} }
static inline int crypto_is_test_larval(struct crypto_larval *larval)
{
return larval->alg.cra_driver_name[0];
}
#endif /* _CRYPTO_INTERNAL_H */ #endif /* _CRYPTO_INTERNAL_H */

View File

@ -40,7 +40,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/fips.h>
#include <linux/time.h> #include <linux/time.h>
#include <crypto/internal/rng.h> #include <crypto/internal/rng.h>
@ -60,11 +59,6 @@ void jent_zfree(void *ptr)
kfree_sensitive(ptr); kfree_sensitive(ptr);
} }
int jent_fips_enabled(void)
{
return fips_enabled;
}
void jent_panic(char *s) void jent_panic(char *s)
{ {
panic("%s", s); panic("%s", s);

View File

@ -117,6 +117,22 @@ struct rand_data {
#define JENT_EHEALTH 9 /* Health test failed during initialization */ #define JENT_EHEALTH 9 /* Health test failed during initialization */
#define JENT_ERCT 10 /* RCT 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" #include "jitterentropy.h"
/*************************************************************************** /***************************************************************************
@ -125,7 +141,7 @@ struct rand_data {
* This test complies with SP800-90B section 4.4.2. * This test complies with SP800-90B section 4.4.2.
***************************************************************************/ ***************************************************************************/
/** /*
* Reset the APT counter * Reset the APT counter
* *
* @ec [in] Reference to entropy collector * @ec [in] Reference to entropy collector
@ -138,7 +154,7 @@ static void jent_apt_reset(struct rand_data *ec, unsigned int delta_masked)
ec->apt_observations = 0; ec->apt_observations = 0;
} }
/** /*
* Insert a new entropy event into APT * Insert a new entropy event into APT
* *
* @ec [in] Reference to entropy collector * @ec [in] Reference to entropy collector
@ -182,7 +198,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. * 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 * Repetition Count Test as defined in SP800-90B section 4.4.1
* *
* @ec [in] Reference to entropy collector * @ec [in] Reference to entropy collector
@ -223,7 +239,7 @@ static void jent_rct_insert(struct rand_data *ec, int stuck)
} }
} }
/** /*
* Is there an RCT health test failure? * Is there an RCT health test failure?
* *
* @ec [in] Reference to entropy collector * @ec [in] Reference to entropy collector
@ -246,7 +262,7 @@ static inline __u64 jent_delta(__u64 prev, __u64 next)
(JENT_UINT64_MAX - prev + 1 + next); (JENT_UINT64_MAX - prev + 1 + next);
} }
/** /*
* Stuck test by checking the: * Stuck test by checking the:
* 1st derivative of the jitter measurement (time delta) * 1st derivative of the jitter measurement (time delta)
* 2nd derivative of the jitter measurement (delta of time deltas) * 2nd derivative of the jitter measurement (delta of time deltas)
@ -287,7 +303,7 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta)
return 0; return 0;
} }
/** /*
* Report any health test failures * Report any health test failures
* *
* @ec [in] Reference to entropy collector * @ec [in] Reference to entropy collector
@ -298,10 +314,6 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta)
*/ */
static int jent_health_failure(struct rand_data *ec) 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; return ec->health_failure;
} }
@ -309,7 +321,7 @@ static int jent_health_failure(struct rand_data *ec)
* Noise sources * Noise sources
***************************************************************************/ ***************************************************************************/
/** /*
* Update of the loop count used for the next round of * Update of the loop count used for the next round of
* an entropy collection. * an entropy collection.
* *
@ -352,7 +364,7 @@ static __u64 jent_loop_shuffle(struct rand_data *ec,
return (shuffle + (1<<min)); return (shuffle + (1<<min));
} }
/** /*
* CPU Jitter noise source -- this is the noise source based on the CPU * CPU Jitter noise source -- this is the noise source based on the CPU
* execution time jitter * execution time jitter
* *
@ -434,7 +446,7 @@ static void jent_lfsr_time(struct rand_data *ec, __u64 time, __u64 loop_cnt,
ec->data = new; ec->data = new;
} }
/** /*
* Memory Access noise source -- this is a noise source based on variations in * Memory Access noise source -- this is a noise source based on variations in
* memory access times * memory access times
* *
@ -499,7 +511,7 @@ static void jent_memaccess(struct rand_data *ec, __u64 loop_cnt)
/*************************************************************************** /***************************************************************************
* Start of entropy processing logic * Start of entropy processing logic
***************************************************************************/ ***************************************************************************/
/** /*
* This is the heart of the entropy generation: calculate time deltas and * 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 * use the CPU jitter in the time deltas. The jitter is injected into the
* entropy pool. * entropy pool.
@ -538,7 +550,7 @@ static int jent_measure_jitter(struct rand_data *ec)
return stuck; return stuck;
} }
/** /*
* Generator of one 64 bit random number * Generator of one 64 bit random number
* Function fills rand_data->data * Function fills rand_data->data
* *
@ -546,12 +558,15 @@ static int jent_measure_jitter(struct rand_data *ec)
*/ */
static void jent_gen_entropy(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 */ /* priming of the ->prev_time value */
jent_measure_jitter(ec); jent_measure_jitter(ec);
while (1) { while (!jent_health_failure(ec)) {
/* If a stuck measurement is received, repeat measurement */ /* If a stuck measurement is received, repeat measurement */
if (jent_measure_jitter(ec)) if (jent_measure_jitter(ec))
continue; continue;
@ -560,12 +575,12 @@ static void jent_gen_entropy(struct rand_data *ec)
* We multiply the loop value with ->osr to obtain the * We multiply the loop value with ->osr to obtain the
* oversampling rate requested by the caller * oversampling rate requested by the caller
*/ */
if (++k >= (DATA_SIZE_BITS * ec->osr)) if (++k >= ((DATA_SIZE_BITS + safety_factor) * ec->osr))
break; break;
} }
} }
/** /*
* Entry function: Obtain entropy for the caller. * Entry function: Obtain entropy for the caller.
* *
* This function invokes the entropy gathering logic as often to generate * This function invokes the entropy gathering logic as often to generate

View File

@ -2,7 +2,6 @@
extern void *jent_zalloc(unsigned int len); extern void *jent_zalloc(unsigned int len);
extern void jent_zfree(void *ptr); extern void jent_zfree(void *ptr);
extern int jent_fips_enabled(void);
extern void jent_panic(char *s); extern void jent_panic(char *s);
extern void jent_memcpy(void *dest, const void *src, unsigned int n); extern void jent_memcpy(void *dest, const void *src, unsigned int n);
extern void jent_get_nstime(__u64 *out); extern void jent_get_nstime(__u64 *out);

View File

@ -5,6 +5,7 @@
* Authors: Tadeusz Struk <tadeusz.struk@intel.com> * Authors: Tadeusz Struk <tadeusz.struk@intel.com>
*/ */
#include <linux/fips.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mpi.h> #include <linux/mpi.h>
#include <crypto/internal/rsa.h> #include <crypto/internal/rsa.h>
@ -144,6 +145,9 @@ static int rsa_check_key_length(unsigned int len)
case 512: case 512:
case 1024: case 1024:
case 1536: case 1536:
if (fips_enabled)
return -EINVAL;
fallthrough;
case 2048: case 2048:
case 3072: case 3072:
case 4096: case 4096:

View File

@ -33,18 +33,6 @@ const u8 sha256_zero_message_hash[SHA256_DIGEST_SIZE] = {
}; };
EXPORT_SYMBOL_GPL(sha256_zero_message_hash); 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, int crypto_sha256_update(struct shash_desc *desc, const u8 *data,
unsigned int len) unsigned int len)
{ {
@ -72,7 +60,7 @@ EXPORT_SYMBOL(crypto_sha256_finup);
static struct shash_alg sha256_algs[2] = { { static struct shash_alg sha256_algs[2] = { {
.digestsize = SHA256_DIGEST_SIZE, .digestsize = SHA256_DIGEST_SIZE,
.init = crypto_sha256_init, .init = sha256_base_init,
.update = crypto_sha256_update, .update = crypto_sha256_update,
.final = crypto_sha256_final, .final = crypto_sha256_final,
.finup = crypto_sha256_finup, .finup = crypto_sha256_finup,
@ -86,7 +74,7 @@ static struct shash_alg sha256_algs[2] = { {
} }
}, { }, {
.digestsize = SHA224_DIGEST_SIZE, .digestsize = SHA224_DIGEST_SIZE,
.init = crypto_sha224_init, .init = sha224_base_init,
.update = crypto_sha256_update, .update = crypto_sha256_update,
.final = crypto_sha256_final, .final = crypto_sha256_final,
.finup = crypto_sha256_finup, .finup = crypto_sha256_finup,

View File

@ -1061,14 +1061,14 @@ static void generate_random_testvec_config(struct testvec_config *cfg,
static void crypto_disable_simd_for_test(void) static void crypto_disable_simd_for_test(void)
{ {
preempt_disable(); migrate_disable();
__this_cpu_write(crypto_simd_disabled_for_test, true); __this_cpu_write(crypto_simd_disabled_for_test, true);
} }
static void crypto_reenable_simd_for_test(void) static void crypto_reenable_simd_for_test(void)
{ {
__this_cpu_write(crypto_simd_disabled_for_test, false); __this_cpu_write(crypto_simd_disabled_for_test, false);
preempt_enable(); migrate_enable();
} }
/* /*
@ -4193,7 +4193,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, { }, {
.alg = "authenc(hmac(sha1),cbc(des3_ede))", .alg = "authenc(hmac(sha1),cbc(des3_ede))",
.test = alg_test_aead, .test = alg_test_aead,
.fips_allowed = 1,
.suite = { .suite = {
.aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp) .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))", .alg = "authenc(hmac(sha224),cbc(des3_ede))",
.test = alg_test_aead, .test = alg_test_aead,
.fips_allowed = 1,
.suite = { .suite = {
.aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp) .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))", .alg = "authenc(hmac(sha256),cbc(des3_ede))",
.test = alg_test_aead, .test = alg_test_aead,
.fips_allowed = 1,
.suite = { .suite = {
.aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp) .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))", .alg = "authenc(hmac(sha384),cbc(des3_ede))",
.test = alg_test_aead, .test = alg_test_aead,
.fips_allowed = 1,
.suite = { .suite = {
.aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp) .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))", .alg = "authenc(hmac(sha512),cbc(des3_ede))",
.test = alg_test_aead, .test = alg_test_aead,
.fips_allowed = 1,
.suite = { .suite = {
.aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp) .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)", .alg = "cbc(des3_ede)",
.test = alg_test_skcipher, .test = alg_test_skcipher,
.fips_allowed = 1,
.suite = { .suite = {
.cipher = __VECS(des3_ede_cbc_tv_template) .cipher = __VECS(des3_ede_cbc_tv_template)
}, },
@ -4505,7 +4499,6 @@ static const struct alg_test_desc alg_test_descs[] = {
} }
}, { }, {
.alg = "cmac(des3_ede)", .alg = "cmac(des3_ede)",
.fips_allowed = 1,
.test = alg_test_hash, .test = alg_test_hash,
.suite = { .suite = {
.hash = __VECS(des3_ede_cmac64_tv_template) .hash = __VECS(des3_ede_cmac64_tv_template)
@ -4580,7 +4573,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, { }, {
.alg = "ctr(des3_ede)", .alg = "ctr(des3_ede)",
.test = alg_test_skcipher, .test = alg_test_skcipher,
.fips_allowed = 1,
.suite = { .suite = {
.cipher = __VECS(des3_ede_ctr_tv_template) .cipher = __VECS(des3_ede_ctr_tv_template)
} }
@ -4846,7 +4838,6 @@ static const struct alg_test_desc alg_test_descs[] = {
}, { }, {
.alg = "ecb(des3_ede)", .alg = "ecb(des3_ede)",
.test = alg_test_skcipher, .test = alg_test_skcipher,
.fips_allowed = 1,
.suite = { .suite = {
.cipher = __VECS(des3_ede_tv_template) .cipher = __VECS(des3_ede_tv_template)
} }

View File

@ -257,9 +257,9 @@ static const struct akcipher_testvec rsa_tv_template[] = {
}, { }, {
#endif #endif
.key = .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\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" "\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" "\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" "\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" /* exponent1 - integer of 1 byte */
"\x02\x01\x00" /* exponent2 - integer of 1 byte */ "\x02\x01\x00" /* exponent2 - integer of 1 byte */
"\x02\x01\x00", /* coefficient - 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", .m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
.c = .c =
"\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe" "\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe"
@ -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" "\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" "\xb8\x35\xdf\x41\x02\x01\x00\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: * m is SHA256 hash of following message:
* "\x49\x41\xbe\x0a\x0c\xc9\xf6\x35\x51\xe4\x27\x56\x13\x71\x4b\xd0" * "\x49\x41\xbe\x0a\x0c\xc9\xf6\x35\x51\xe4\x27\x56\x13\x71\x4b\xd0"

View File

@ -18,22 +18,22 @@
#define ZSTD_DEF_LEVEL 3 #define ZSTD_DEF_LEVEL 3
struct zstd_ctx { struct zstd_ctx {
ZSTD_CCtx *cctx; zstd_cctx *cctx;
ZSTD_DCtx *dctx; zstd_dctx *dctx;
void *cwksp; void *cwksp;
void *dwksp; void *dwksp;
}; };
static ZSTD_parameters zstd_params(void) static zstd_parameters zstd_params(void)
{ {
return ZSTD_getParams(ZSTD_DEF_LEVEL, 0, 0); return zstd_get_params(ZSTD_DEF_LEVEL, 0);
} }
static int zstd_comp_init(struct zstd_ctx *ctx) static int zstd_comp_init(struct zstd_ctx *ctx)
{ {
int ret = 0; int ret = 0;
const ZSTD_parameters params = zstd_params(); const zstd_parameters params = zstd_params();
const size_t wksp_size = ZSTD_CCtxWorkspaceBound(params.cParams); const size_t wksp_size = zstd_cctx_workspace_bound(&params.cParams);
ctx->cwksp = vzalloc(wksp_size); ctx->cwksp = vzalloc(wksp_size);
if (!ctx->cwksp) { if (!ctx->cwksp) {
@ -41,7 +41,7 @@ static int zstd_comp_init(struct zstd_ctx *ctx)
goto out; goto out;
} }
ctx->cctx = ZSTD_initCCtx(ctx->cwksp, wksp_size); ctx->cctx = zstd_init_cctx(ctx->cwksp, wksp_size);
if (!ctx->cctx) { if (!ctx->cctx) {
ret = -EINVAL; ret = -EINVAL;
goto out_free; goto out_free;
@ -56,7 +56,7 @@ static int zstd_comp_init(struct zstd_ctx *ctx)
static int zstd_decomp_init(struct zstd_ctx *ctx) static int zstd_decomp_init(struct zstd_ctx *ctx)
{ {
int ret = 0; int ret = 0;
const size_t wksp_size = ZSTD_DCtxWorkspaceBound(); const size_t wksp_size = zstd_dctx_workspace_bound();
ctx->dwksp = vzalloc(wksp_size); ctx->dwksp = vzalloc(wksp_size);
if (!ctx->dwksp) { if (!ctx->dwksp) {
@ -64,7 +64,7 @@ static int zstd_decomp_init(struct zstd_ctx *ctx)
goto out; goto out;
} }
ctx->dctx = ZSTD_initDCtx(ctx->dwksp, wksp_size); ctx->dctx = zstd_init_dctx(ctx->dwksp, wksp_size);
if (!ctx->dctx) { if (!ctx->dctx) {
ret = -EINVAL; ret = -EINVAL;
goto out_free; goto out_free;
@ -152,10 +152,10 @@ static int __zstd_compress(const u8 *src, unsigned int slen,
{ {
size_t out_len; size_t out_len;
struct zstd_ctx *zctx = ctx; struct zstd_ctx *zctx = ctx;
const ZSTD_parameters params = zstd_params(); const zstd_parameters params = zstd_params();
out_len = ZSTD_compressCCtx(zctx->cctx, dst, *dlen, src, slen, params); out_len = zstd_compress_cctx(zctx->cctx, dst, *dlen, src, slen, &params);
if (ZSTD_isError(out_len)) if (zstd_is_error(out_len))
return -EINVAL; return -EINVAL;
*dlen = out_len; *dlen = out_len;
return 0; return 0;
@ -182,8 +182,8 @@ static int __zstd_decompress(const u8 *src, unsigned int slen,
size_t out_len; size_t out_len;
struct zstd_ctx *zctx = ctx; struct zstd_ctx *zctx = ctx;
out_len = ZSTD_decompressDCtx(zctx->dctx, dst, *dlen, src, slen); out_len = zstd_decompress_dctx(zctx->dctx, dst, *dlen, src, slen);
if (ZSTD_isError(out_len)) if (zstd_is_error(out_len))
return -EINVAL; return -EINVAL;
*dlen = out_len; *dlen = out_len;
return 0; return 0;