mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-01-30 14:52:17 +00:00
phase 9
This commit is contained in:
parent
a80f575781
commit
a9d5e6067d
@ -1845,6 +1845,10 @@ config CRYPTO_JITTERENTROPY
|
||||
random numbers. This Jitterentropy RNG registers with
|
||||
the kernel crypto API and can be used by any caller.
|
||||
|
||||
config CRYPTO_KDF800108_CTR
|
||||
tristate
|
||||
select CRYPTO_SHA256
|
||||
|
||||
config CRYPTO_USER_API
|
||||
tristate
|
||||
|
||||
@ -1919,7 +1923,6 @@ config CRYPTO_STATS
|
||||
config CRYPTO_HASH_INFO
|
||||
bool
|
||||
|
||||
source "lib/crypto/Kconfig"
|
||||
source "drivers/crypto/Kconfig"
|
||||
source "crypto/asymmetric_keys/Kconfig"
|
||||
source "certs/Kconfig"
|
||||
|
@ -119,6 +119,8 @@ CFLAGS_aegis128-neon-inner.o += $(aegis128-cflags-y)
|
||||
CFLAGS_REMOVE_aegis128-neon-inner.o += -mgeneral-regs-only
|
||||
aegis128-$(CONFIG_CRYPTO_AEGIS128_SIMD) += aegis128-neon.o aegis128-neon-inner.o
|
||||
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_CRYPTD) += cryptd.o
|
||||
@ -198,3 +200,8 @@ obj-$(CONFIG_ASYMMETRIC_KEY_TYPE) += asymmetric_keys/
|
||||
obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o
|
||||
crypto_simd-y := simd.o
|
||||
obj-$(CONFIG_CRYPTO_SIMD) += crypto_simd.o
|
||||
|
||||
#
|
||||
# Key derivation function
|
||||
#
|
||||
obj-$(CONFIG_CRYPTO_KDF800108_CTR) += kdf_sp800108.o
|
||||
|
@ -25,12 +25,9 @@ struct alg_type_list {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
static atomic_long_t alg_memory_allocated;
|
||||
|
||||
static struct proto alg_proto = {
|
||||
.name = "ALG",
|
||||
.owner = THIS_MODULE,
|
||||
.memory_allocated = &alg_memory_allocated,
|
||||
.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);
|
||||
|
||||
do {
|
||||
struct page *pg;
|
||||
unsigned int i = sgl->cur;
|
||||
|
||||
plen = min_t(size_t, len, PAGE_SIZE);
|
||||
|
||||
sg_assign_page(sg + i, alloc_page(GFP_KERNEL));
|
||||
if (!sg_page(sg + i)) {
|
||||
pg = alloc_page(GFP_KERNEL);
|
||||
if (!pg) {
|
||||
err = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
sg_assign_page(sg + i, pg);
|
||||
|
||||
err = memcpy_from_msg(page_address(sg_page(sg + i)),
|
||||
msg, plen);
|
||||
if (err) {
|
||||
@ -1076,7 +1076,7 @@ void af_alg_async_cb(struct crypto_async_request *_req, int err)
|
||||
af_alg_free_resources(areq);
|
||||
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);
|
||||
|
||||
|
125
crypto/algapi.c
125
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,22 @@ 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);
|
||||
else
|
||||
alg->cra_flags |= CRYPTO_ALG_TESTED;
|
||||
|
||||
crypto_stats_init(alg);
|
||||
|
||||
out:
|
||||
return larval;
|
||||
|
||||
free_larval:
|
||||
kfree(larval);
|
||||
err:
|
||||
larval = ERR_PTR(ret);
|
||||
goto out;
|
||||
@ -389,29 +406,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 +419,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 +634,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 +644,7 @@ int crypto_register_instance(struct crypto_template *tmpl,
|
||||
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 +1265,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 +1315,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");
|
||||
|
@ -67,7 +67,7 @@ static int cryptomgr_probe(void *data)
|
||||
complete_all(¶m->larval->completion);
|
||||
crypto_alg_put(¶m->larval->alg);
|
||||
kfree(param);
|
||||
module_put_and_exit(0);
|
||||
module_put_and_kthread_exit(0);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
kfree(param);
|
||||
module_put_and_exit(0);
|
||||
module_put_and_kthread_exit(0);
|
||||
}
|
||||
|
||||
static int cryptomgr_schedule_test(struct crypto_alg *alg)
|
||||
|
50
crypto/api.c
50
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);
|
||||
|
||||
|
@ -36,16 +36,23 @@ static DECLARE_RWSEM(asymmetric_key_parsers_sem);
|
||||
* find_asymmetric_key - Find a key by ID.
|
||||
* @keyring: The keys to search.
|
||||
* @id_0: The first ID to look for or NULL.
|
||||
* @id_1: The second ID to look for or NULL.
|
||||
* @partial: Use partial match if true, exact if false.
|
||||
* @id_1: The second ID to look for or NULL, matched together with @id_0
|
||||
* 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
|
||||
* 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,
|
||||
const struct asymmetric_key_id *id_0,
|
||||
const struct asymmetric_key_id *id_1,
|
||||
const struct asymmetric_key_id *id_2,
|
||||
bool partial)
|
||||
{
|
||||
struct key *key;
|
||||
@ -54,14 +61,17 @@ struct key *find_asymmetric_key(struct key *keyring,
|
||||
char *req, *p;
|
||||
int len;
|
||||
|
||||
BUG_ON(!id_0 && !id_1);
|
||||
WARN_ON(!id_0 && !id_1 && !id_2);
|
||||
|
||||
if (id_0) {
|
||||
lookup = id_0->data;
|
||||
len = id_0->len;
|
||||
} else {
|
||||
} else if (id_1) {
|
||||
lookup = id_1->data;
|
||||
len = id_1->len;
|
||||
} else {
|
||||
lookup = id_2->data;
|
||||
len = id_2->len;
|
||||
}
|
||||
|
||||
/* Construct an identifier "id:<keyid>". */
|
||||
@ -69,7 +79,10 @@ struct key *find_asymmetric_key(struct key *keyring,
|
||||
if (!req)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (partial) {
|
||||
if (!id_0 && !id_1) {
|
||||
*p++ = 'd';
|
||||
*p++ = 'n';
|
||||
} else if (partial) {
|
||||
*p++ = 'i';
|
||||
*p++ = 'd';
|
||||
} else {
|
||||
@ -185,8 +198,8 @@ bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
|
||||
EXPORT_SYMBOL_GPL(asymmetric_key_id_partial);
|
||||
|
||||
/**
|
||||
* asymmetric_match_key_ids - Search asymmetric key IDs
|
||||
* @kids: The list of key IDs to check
|
||||
* asymmetric_match_key_ids - Search asymmetric key IDs 1 & 2
|
||||
* @kids: The pair of key IDs to check
|
||||
* @match_id: The key ID we're looking for
|
||||
* @match: The match function to use
|
||||
*/
|
||||
@ -200,7 +213,7 @@ static bool asymmetric_match_key_ids(
|
||||
|
||||
if (!kids || !match_id)
|
||||
return false;
|
||||
for (i = 0; i < ARRAY_SIZE(kids->id); i++)
|
||||
for (i = 0; i < 2; i++)
|
||||
if (match(kids->id[i], match_id))
|
||||
return true;
|
||||
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,
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
* 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
|
||||
* description:
|
||||
*
|
||||
* "id:<id>" - find a key by partial match on any available ID
|
||||
* "ex:<id>" - find a key by exact 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 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
|
||||
* 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[2] == ':') {
|
||||
id = spec + 3;
|
||||
} else if (spec[0] == 'd' &&
|
||||
spec[1] == 'n' &&
|
||||
spec[2] == ':') {
|
||||
id = spec + 3;
|
||||
cmp = asymmetric_key_cmp_name;
|
||||
} else {
|
||||
goto default_match;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ static int pkcs7_validate_trust_one(struct pkcs7_message *pkcs7,
|
||||
* keys.
|
||||
*/
|
||||
key = find_asymmetric_key(trust_keyring,
|
||||
x509->id, x509->skid, false);
|
||||
x509->id, x509->skid, NULL, false);
|
||||
if (!IS_ERR(key)) {
|
||||
/* One of the X.509 certificates in the PKCS#7 message
|
||||
* 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,
|
||||
last->sig->auth_ids[0],
|
||||
last->sig->auth_ids[1],
|
||||
false);
|
||||
NULL, false);
|
||||
if (!IS_ERR(key)) {
|
||||
x509 = last;
|
||||
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.
|
||||
*/
|
||||
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)) {
|
||||
pr_devel("sinfo %u: Direct signer is key %x\n",
|
||||
sinfo->index, key_serial(key));
|
||||
|
@ -87,7 +87,7 @@ int restrict_link_by_signature(struct key *dest_keyring,
|
||||
sig = payload->data[asym_auth];
|
||||
if (!sig)
|
||||
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;
|
||||
|
||||
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. */
|
||||
key = find_asymmetric_key(trust_keyring,
|
||||
sig->auth_ids[0], sig->auth_ids[1],
|
||||
false);
|
||||
sig->auth_ids[2], false);
|
||||
if (IS_ERR(key))
|
||||
return -ENOKEY;
|
||||
|
||||
@ -108,11 +108,11 @@ int restrict_link_by_signature(struct key *dest_keyring,
|
||||
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)
|
||||
{
|
||||
return (asymmetric_key_id_same(pair->id[0], single) ||
|
||||
asymmetric_key_id_same(pair->id[1], single));
|
||||
return (asymmetric_key_id_same(pair[0], single) ||
|
||||
asymmetric_key_id_same(pair[1], single));
|
||||
}
|
||||
|
||||
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];
|
||||
if (!sig)
|
||||
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;
|
||||
|
||||
if (trusted) {
|
||||
if (trusted->type == &key_type_keyring) {
|
||||
/* See if we have a key that signed this one. */
|
||||
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))
|
||||
key = NULL;
|
||||
} 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
|
||||
@ -164,22 +166,29 @@ static int key_or_keyring_common(struct key *dest_keyring,
|
||||
* The signer_ids are identifiers for the
|
||||
* signing key specified for dest_keyring.
|
||||
*
|
||||
* The first auth_id is the preferred id, and
|
||||
* the second is the fallback. If only one
|
||||
* auth_id is present, it may match against
|
||||
* either signer_id. If two auth_ids are
|
||||
* present, the first auth_id must match one
|
||||
* signer_id and the second auth_id must match
|
||||
* the second signer_id.
|
||||
* The first auth_id is the preferred id, 2nd and
|
||||
* 3rd are the fallbacks. If exactly one of
|
||||
* auth_ids[0] and auth_ids[1] is present, it may
|
||||
* match either signer_ids[0] or signed_ids[1].
|
||||
* If both are present the first one may match
|
||||
* either signed_id but the second one must match
|
||||
* 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;
|
||||
|
||||
auth_id = sig->auth_ids[0] ?: sig->auth_ids[1];
|
||||
if (match_either_id(signer_ids, auth_id))
|
||||
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]) &&
|
||||
match_either_id(signer_ids,
|
||||
sig->auth_ids[0])) {
|
||||
@ -193,7 +202,8 @@ static int key_or_keyring_common(struct key *dest_keyring,
|
||||
if (check_dest && !key) {
|
||||
/* See if the destination has a key that signed this one. */
|
||||
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))
|
||||
key = NULL;
|
||||
}
|
||||
|
@ -441,8 +441,18 @@ int x509_note_issuer(void *context, size_t hdrlen,
|
||||
const void *value, size_t vlen)
|
||||
{
|
||||
struct x509_parse_context *ctx = context;
|
||||
struct asymmetric_key_id *kid;
|
||||
|
||||
ctx->cert->raw_issuer = value;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -223,6 +223,13 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
|
||||
goto error_free_desc;
|
||||
kids->id[0] = cert->id;
|
||||
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 */
|
||||
__module_get(public_key_subtype.owner);
|
||||
@ -239,8 +246,11 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
|
||||
cert->skid = NULL;
|
||||
cert->sig = NULL;
|
||||
desc = NULL;
|
||||
kids = NULL;
|
||||
ret = 0;
|
||||
|
||||
error_free_kids:
|
||||
kfree(kids);
|
||||
error_free_desc:
|
||||
kfree(desc);
|
||||
error_free_cert:
|
||||
|
@ -15,12 +15,12 @@
|
||||
static int crypto_blake2s_update_generic(struct shash_desc *desc,
|
||||
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)
|
||||
{
|
||||
return crypto_blake2s_final(desc, out, blake2s_compress_generic);
|
||||
return crypto_blake2s_final(desc, out, true);
|
||||
}
|
||||
|
||||
#define BLAKE2S_ALG(name, driver_name, digest_size) \
|
||||
|
@ -327,6 +327,19 @@ int crypto_transfer_hash_request_to_engine(struct crypto_engine *engine,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_transfer_hash_request_to_engine);
|
||||
|
||||
/**
|
||||
* crypto_transfer_kpp_request_to_engine - transfer one kpp_request to list
|
||||
* into the engine queue
|
||||
* @engine: the hardware engine
|
||||
* @req: the request need to be listed into the engine queue
|
||||
*/
|
||||
int crypto_transfer_kpp_request_to_engine(struct crypto_engine *engine,
|
||||
struct kpp_request *req)
|
||||
{
|
||||
return crypto_transfer_request_to_engine(engine, &req->base);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_transfer_kpp_request_to_engine);
|
||||
|
||||
/**
|
||||
* crypto_transfer_skcipher_request_to_engine - transfer one skcipher_request
|
||||
* to list into the engine queue
|
||||
@ -382,6 +395,19 @@ void crypto_finalize_hash_request(struct crypto_engine *engine,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_finalize_hash_request);
|
||||
|
||||
/**
|
||||
* crypto_finalize_kpp_request - finalize one kpp_request if the request is done
|
||||
* @engine: the hardware engine
|
||||
* @req: the request need to be finalized
|
||||
* @err: error number
|
||||
*/
|
||||
void crypto_finalize_kpp_request(struct crypto_engine *engine,
|
||||
struct kpp_request *req, int err)
|
||||
{
|
||||
return crypto_finalize_request(engine, &req->base, err);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(crypto_finalize_kpp_request);
|
||||
|
||||
/**
|
||||
* crypto_finalize_skcipher_request - finalize one skcipher_request if
|
||||
* the request is done
|
||||
|
@ -5,11 +5,11 @@
|
||||
* Authors: Salvatore Benedetto <salvatore.benedetto@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/fips.h>
|
||||
#include <linux/module.h>
|
||||
#include <crypto/internal/kpp.h>
|
||||
#include <crypto/kpp.h>
|
||||
#include <crypto/dh.h>
|
||||
#include <linux/fips.h>
|
||||
#include <linux/mpi.h>
|
||||
|
||||
struct dh_ctx {
|
||||
@ -47,6 +47,9 @@ static inline struct dh_ctx *dh_get_ctx(struct crypto_kpp *tfm)
|
||||
|
||||
static int dh_check_params_length(unsigned int p_len)
|
||||
{
|
||||
if (fips_enabled)
|
||||
return (p_len < 2048) ? -EINVAL : 0;
|
||||
|
||||
return (p_len < 1536) ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
|
156
crypto/drbg.c
156
crypto/drbg.c
@ -100,6 +100,7 @@
|
||||
#include <crypto/drbg.h>
|
||||
#include <crypto/internal/cipher.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/jiffies.h>
|
||||
|
||||
/***************************************************************
|
||||
* Backend cipher definitions available to DRBG
|
||||
@ -1036,17 +1037,39 @@ static const struct drbg_state_ops drbg_hash_ops = {
|
||||
******************************************************************/
|
||||
|
||||
static inline int __drbg_seed(struct drbg_state *drbg, struct list_head *seed,
|
||||
int reseed)
|
||||
int reseed, enum drbg_seed_state new_seed_state)
|
||||
{
|
||||
int ret = drbg->d_ops->update(drbg, seed, reseed);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drbg->seeded = true;
|
||||
drbg->seeded = new_seed_state;
|
||||
drbg->last_seed_time = jiffies;
|
||||
/* 10.1.1.2 / 10.1.1.3 step 5 */
|
||||
drbg->reseed_ctr = 1;
|
||||
|
||||
switch (drbg->seeded) {
|
||||
case DRBG_SEED_STATE_UNSEEDED:
|
||||
/* Impossible, but handle it to silence compiler warnings. */
|
||||
fallthrough;
|
||||
case DRBG_SEED_STATE_PARTIAL:
|
||||
/*
|
||||
* Require frequent reseeds until the seed source is
|
||||
* fully initialized.
|
||||
*/
|
||||
drbg->reseed_threshold = 50;
|
||||
break;
|
||||
|
||||
case DRBG_SEED_STATE_FULL:
|
||||
/*
|
||||
* Seed source has become fully initialized, frequent
|
||||
* reseeds no longer required.
|
||||
*/
|
||||
drbg->reseed_threshold = drbg_max_requests(drbg);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1066,12 +1089,10 @@ static inline int drbg_get_random_bytes(struct drbg_state *drbg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drbg_async_seed(struct work_struct *work)
|
||||
static int drbg_seed_from_random(struct drbg_state *drbg)
|
||||
{
|
||||
struct drbg_string data;
|
||||
LIST_HEAD(seedlist);
|
||||
struct drbg_state *drbg = container_of(work, struct drbg_state,
|
||||
seed_work);
|
||||
unsigned int entropylen = drbg_sec_strength(drbg->core->flags);
|
||||
unsigned char entropy[32];
|
||||
int ret;
|
||||
@ -1082,26 +1103,35 @@ static void drbg_async_seed(struct work_struct *work)
|
||||
drbg_string_fill(&data, entropy, entropylen);
|
||||
list_add_tail(&data.list, &seedlist);
|
||||
|
||||
mutex_lock(&drbg->drbg_mutex);
|
||||
|
||||
ret = drbg_get_random_bytes(drbg, entropy, entropylen);
|
||||
if (ret)
|
||||
goto unlock;
|
||||
goto out;
|
||||
|
||||
/* Set seeded to false so that if __drbg_seed fails the
|
||||
* next generate call will trigger a reseed.
|
||||
*/
|
||||
drbg->seeded = false;
|
||||
|
||||
__drbg_seed(drbg, &seedlist, true);
|
||||
|
||||
if (drbg->seeded)
|
||||
drbg->reseed_threshold = drbg_max_requests(drbg);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&drbg->drbg_mutex);
|
||||
ret = __drbg_seed(drbg, &seedlist, true, DRBG_SEED_STATE_FULL);
|
||||
|
||||
out:
|
||||
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);
|
||||
struct drbg_string data1;
|
||||
LIST_HEAD(seedlist);
|
||||
enum drbg_seed_state new_seed_state = DRBG_SEED_STATE_FULL;
|
||||
|
||||
/* 9.1 / 9.2 / 9.3.1 step 3 */
|
||||
if (pers && pers->len > (drbg_max_addtl(drbg))) {
|
||||
@ -1150,6 +1181,9 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
|
||||
BUG_ON((entropylen * 2) > sizeof(entropy));
|
||||
|
||||
/* Get seed from in-kernel /dev/urandom */
|
||||
if (!rng_is_initialized())
|
||||
new_seed_state = DRBG_SEED_STATE_PARTIAL;
|
||||
|
||||
ret = drbg_get_random_bytes(drbg, entropy, entropylen);
|
||||
if (ret)
|
||||
goto out;
|
||||
@ -1159,11 +1193,14 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
|
||||
pr_devel("DRBG: (re)seeding with %u bytes of entropy\n",
|
||||
entropylen);
|
||||
} else {
|
||||
/* Get seed from Jitter RNG */
|
||||
/*
|
||||
* Get seed from Jitter RNG, failures are
|
||||
* fatal only in FIPS mode.
|
||||
*/
|
||||
ret = crypto_rng_get_bytes(drbg->jent,
|
||||
entropy + entropylen,
|
||||
entropylen);
|
||||
if (ret) {
|
||||
if (fips_enabled && ret) {
|
||||
pr_devel("DRBG: jent failed with %d\n", ret);
|
||||
|
||||
/*
|
||||
@ -1206,7 +1243,7 @@ static int drbg_seed(struct drbg_state *drbg, struct drbg_string *pers,
|
||||
memset(drbg->C, 0, drbg_statelen(drbg));
|
||||
}
|
||||
|
||||
ret = __drbg_seed(drbg, &seedlist, reseed);
|
||||
ret = __drbg_seed(drbg, &seedlist, reseed, new_seed_state);
|
||||
|
||||
out:
|
||||
memzero_explicit(entropy, entropylen * 2);
|
||||
@ -1386,19 +1423,26 @@ static int drbg_generate(struct drbg_state *drbg,
|
||||
* here. The spec is a bit convoluted here, we make it simpler.
|
||||
*/
|
||||
if (drbg->reseed_threshold < drbg->reseed_ctr)
|
||||
drbg->seeded = false;
|
||||
drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
|
||||
|
||||
if (drbg->pr || !drbg->seeded) {
|
||||
if (drbg->pr || drbg->seeded == DRBG_SEED_STATE_UNSEEDED) {
|
||||
pr_devel("DRBG: reseeding before generation (prediction "
|
||||
"resistance: %s, state %s)\n",
|
||||
drbg->pr ? "true" : "false",
|
||||
drbg->seeded ? "seeded" : "unseeded");
|
||||
(drbg->seeded == DRBG_SEED_STATE_FULL ?
|
||||
"seeded" : "unseeded"));
|
||||
/* 9.3.1 steps 7.1 through 7.3 */
|
||||
len = drbg_seed(drbg, addtl, true);
|
||||
if (len)
|
||||
goto err;
|
||||
/* 9.3.1 step 7.4 */
|
||||
addtl = NULL;
|
||||
} else if (rng_is_initialized() &&
|
||||
(drbg->seeded == DRBG_SEED_STATE_PARTIAL ||
|
||||
drbg_nopr_reseed_interval_elapsed(drbg))) {
|
||||
len = drbg_seed_from_random(drbg);
|
||||
if (len)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (addtl && 0 < addtl->len)
|
||||
@ -1491,51 +1535,23 @@ static int drbg_generate_long(struct drbg_state *drbg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drbg_schedule_async_seed(struct random_ready_callback *rdy)
|
||||
{
|
||||
struct drbg_state *drbg = container_of(rdy, struct drbg_state,
|
||||
random_ready);
|
||||
|
||||
schedule_work(&drbg->seed_work);
|
||||
}
|
||||
|
||||
static int drbg_prepare_hrng(struct drbg_state *drbg)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* We do not need an HRNG in test mode. */
|
||||
if (list_empty(&drbg->test_data.list))
|
||||
return 0;
|
||||
|
||||
drbg->jent = crypto_alloc_rng("jitterentropy_rng", 0, 0);
|
||||
if (IS_ERR(drbg->jent)) {
|
||||
const int err = PTR_ERR(drbg->jent);
|
||||
|
||||
INIT_WORK(&drbg->seed_work, drbg_async_seed);
|
||||
|
||||
drbg->random_ready.owner = THIS_MODULE;
|
||||
drbg->random_ready.func = drbg_schedule_async_seed;
|
||||
|
||||
err = add_random_ready_callback(&drbg->random_ready);
|
||||
|
||||
switch (err) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case -EALREADY:
|
||||
err = 0;
|
||||
fallthrough;
|
||||
|
||||
default:
|
||||
drbg->random_ready.func = NULL;
|
||||
return err;
|
||||
drbg->jent = NULL;
|
||||
if (fips_enabled || err != -ENOENT)
|
||||
return err;
|
||||
pr_info("DRBG: Continuing without Jitter RNG\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Require frequent reseeds until the seed source is fully
|
||||
* initialized.
|
||||
*/
|
||||
drbg->reseed_threshold = 50;
|
||||
|
||||
return err;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1578,7 +1594,8 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
|
||||
if (!drbg->core) {
|
||||
drbg->core = &drbg_cores[coreref];
|
||||
drbg->pr = pr;
|
||||
drbg->seeded = false;
|
||||
drbg->seeded = DRBG_SEED_STATE_UNSEEDED;
|
||||
drbg->last_seed_time = 0;
|
||||
drbg->reseed_threshold = drbg_max_requests(drbg);
|
||||
|
||||
ret = drbg_alloc_state(drbg);
|
||||
@ -1589,14 +1606,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
|
||||
if (ret)
|
||||
goto free_everything;
|
||||
|
||||
if (IS_ERR(drbg->jent)) {
|
||||
ret = PTR_ERR(drbg->jent);
|
||||
drbg->jent = NULL;
|
||||
if (fips_enabled || ret != -ENOENT)
|
||||
goto free_everything;
|
||||
pr_info("DRBG: Continuing without Jitter RNG\n");
|
||||
}
|
||||
|
||||
reseed = false;
|
||||
}
|
||||
|
||||
@ -1629,11 +1638,6 @@ static int drbg_instantiate(struct drbg_state *drbg, struct drbg_string *pers,
|
||||
*/
|
||||
static int drbg_uninstantiate(struct drbg_state *drbg)
|
||||
{
|
||||
if (drbg->random_ready.func) {
|
||||
del_random_ready_callback(&drbg->random_ready);
|
||||
cancel_work_sync(&drbg->seed_work);
|
||||
}
|
||||
|
||||
if (!IS_ERR_OR_NULL(drbg->jent))
|
||||
crypto_free_rng(drbg->jent);
|
||||
drbg->jent = NULL;
|
||||
@ -2003,7 +2007,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;
|
||||
|
14
crypto/ecc.c
14
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 @@ static struct ecc_point *ecc_alloc_point(unsigned int ndigits)
|
||||
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
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/fips.h>
|
||||
#include <linux/time.h>
|
||||
#include <crypto/internal/rng.h>
|
||||
|
||||
@ -60,11 +59,6 @@ void jent_zfree(void *ptr)
|
||||
kfree_sensitive(ptr);
|
||||
}
|
||||
|
||||
int jent_fips_enabled(void)
|
||||
{
|
||||
return fips_enabled;
|
||||
}
|
||||
|
||||
void jent_panic(char *s)
|
||||
{
|
||||
panic("%s", s);
|
||||
|
@ -117,6 +117,22 @@ struct rand_data {
|
||||
#define JENT_EHEALTH 9 /* Health test failed during initialization */
|
||||
#define JENT_ERCT 10 /* RCT failed during initialization */
|
||||
|
||||
/*
|
||||
* The output n bits can receive more than n bits of min entropy, of course,
|
||||
* but the fixed output of the conditioning function can only asymptotically
|
||||
* approach the output size bits of min entropy, not attain that bound. Random
|
||||
* maps will tend to have output collisions, which reduces the creditable
|
||||
* output entropy (that is what SP 800-90B Section 3.1.5.1.2 attempts to bound).
|
||||
*
|
||||
* The value "64" is justified in Appendix A.4 of the current 90C draft,
|
||||
* and aligns with NIST's in "epsilon" definition in this document, which is
|
||||
* that a string can be considered "full entropy" if you can bound the min
|
||||
* entropy in each bit of output to at least 1-epsilon, where epsilon is
|
||||
* required to be <= 2^(-32).
|
||||
*/
|
||||
#define JENT_ENTROPY_SAFETY_FACTOR 64
|
||||
|
||||
#include <linux/fips.h>
|
||||
#include "jitterentropy.h"
|
||||
|
||||
/***************************************************************************
|
||||
@ -125,7 +141,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 +154,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 +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.
|
||||
***************************************************************************/
|
||||
|
||||
/**
|
||||
/*
|
||||
* Repetition Count Test as defined in SP800-90B section 4.4.1
|
||||
*
|
||||
* @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?
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Stuck test by checking the:
|
||||
* 1st derivative of the jitter measurement (time delta)
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Report any health test failures
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
/* Test is only enabled in FIPS mode */
|
||||
if (!jent_fips_enabled())
|
||||
return 0;
|
||||
|
||||
return ec->health_failure;
|
||||
}
|
||||
|
||||
@ -309,7 +321,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.
|
||||
*
|
||||
@ -352,7 +364,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
|
||||
*
|
||||
@ -434,7 +446,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
|
||||
*
|
||||
@ -499,7 +511,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.
|
||||
@ -538,7 +550,7 @@ static int jent_measure_jitter(struct rand_data *ec)
|
||||
return stuck;
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Generator of one 64 bit random number
|
||||
* 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)
|
||||
{
|
||||
unsigned int k = 0;
|
||||
unsigned int k = 0, safety_factor = 0;
|
||||
|
||||
if (fips_enabled)
|
||||
safety_factor = JENT_ENTROPY_SAFETY_FACTOR;
|
||||
|
||||
/* priming of the ->prev_time value */
|
||||
jent_measure_jitter(ec);
|
||||
|
||||
while (1) {
|
||||
while (!jent_health_failure(ec)) {
|
||||
/* If a stuck measurement is received, repeat measurement */
|
||||
if (jent_measure_jitter(ec))
|
||||
continue;
|
||||
@ -560,12 +575,12 @@ static void jent_gen_entropy(struct rand_data *ec)
|
||||
* We multiply the loop value with ->osr to obtain the
|
||||
* oversampling rate requested by the caller
|
||||
*/
|
||||
if (++k >= (DATA_SIZE_BITS * ec->osr))
|
||||
if (++k >= ((DATA_SIZE_BITS + safety_factor) * ec->osr))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
/*
|
||||
* Entry function: Obtain entropy for the caller.
|
||||
*
|
||||
* This function invokes the entropy gathering logic as often to generate
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
extern void *jent_zalloc(unsigned int len);
|
||||
extern void jent_zfree(void *ptr);
|
||||
extern int jent_fips_enabled(void);
|
||||
extern void jent_panic(char *s);
|
||||
extern void jent_memcpy(void *dest, const void *src, unsigned int n);
|
||||
extern void jent_get_nstime(__u64 *out);
|
||||
|
@ -5,6 +5,7 @@
|
||||
* Authors: Tadeusz Struk <tadeusz.struk@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/fips.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mpi.h>
|
||||
#include <crypto/internal/rsa.h>
|
||||
@ -144,6 +145,9 @@ static int rsa_check_key_length(unsigned int len)
|
||||
case 512:
|
||||
case 1024:
|
||||
case 1536:
|
||||
if (fips_enabled)
|
||||
return -EINVAL;
|
||||
fallthrough;
|
||||
case 2048:
|
||||
case 3072:
|
||||
case 4096:
|
||||
|
@ -33,18 +33,6 @@ const u8 sha256_zero_message_hash[SHA256_DIGEST_SIZE] = {
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(sha256_zero_message_hash);
|
||||
|
||||
static int crypto_sha256_init(struct shash_desc *desc)
|
||||
{
|
||||
sha256_init(shash_desc_ctx(desc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int crypto_sha224_init(struct shash_desc *desc)
|
||||
{
|
||||
sha224_init(shash_desc_ctx(desc));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crypto_sha256_update(struct shash_desc *desc, const u8 *data,
|
||||
unsigned int len)
|
||||
{
|
||||
@ -72,7 +60,7 @@ EXPORT_SYMBOL(crypto_sha256_finup);
|
||||
|
||||
static struct shash_alg sha256_algs[2] = { {
|
||||
.digestsize = SHA256_DIGEST_SIZE,
|
||||
.init = crypto_sha256_init,
|
||||
.init = sha256_base_init,
|
||||
.update = crypto_sha256_update,
|
||||
.final = crypto_sha256_final,
|
||||
.finup = crypto_sha256_finup,
|
||||
@ -86,7 +74,7 @@ static struct shash_alg sha256_algs[2] = { {
|
||||
}
|
||||
}, {
|
||||
.digestsize = SHA224_DIGEST_SIZE,
|
||||
.init = crypto_sha224_init,
|
||||
.init = sha224_base_init,
|
||||
.update = crypto_sha256_update,
|
||||
.final = crypto_sha256_final,
|
||||
.finup = crypto_sha256_finup,
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -4193,7 +4193,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha1),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = __VECS(hmac_sha1_des3_ede_cbc_tv_temp)
|
||||
}
|
||||
@ -4220,7 +4219,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha224),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = __VECS(hmac_sha224_des3_ede_cbc_tv_temp)
|
||||
}
|
||||
@ -4240,7 +4238,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha256),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = __VECS(hmac_sha256_des3_ede_cbc_tv_temp)
|
||||
}
|
||||
@ -4261,7 +4258,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha384),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = __VECS(hmac_sha384_des3_ede_cbc_tv_temp)
|
||||
}
|
||||
@ -4289,7 +4285,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "authenc(hmac(sha512),cbc(des3_ede))",
|
||||
.test = alg_test_aead,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.aead = __VECS(hmac_sha512_des3_ede_cbc_tv_temp)
|
||||
}
|
||||
@ -4399,7 +4394,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "cbc(des3_ede)",
|
||||
.test = alg_test_skcipher,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.cipher = __VECS(des3_ede_cbc_tv_template)
|
||||
},
|
||||
@ -4505,7 +4499,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}
|
||||
}, {
|
||||
.alg = "cmac(des3_ede)",
|
||||
.fips_allowed = 1,
|
||||
.test = alg_test_hash,
|
||||
.suite = {
|
||||
.hash = __VECS(des3_ede_cmac64_tv_template)
|
||||
@ -4580,7 +4573,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "ctr(des3_ede)",
|
||||
.test = alg_test_skcipher,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.cipher = __VECS(des3_ede_ctr_tv_template)
|
||||
}
|
||||
@ -4846,7 +4838,6 @@ static const struct alg_test_desc alg_test_descs[] = {
|
||||
}, {
|
||||
.alg = "ecb(des3_ede)",
|
||||
.test = alg_test_skcipher,
|
||||
.fips_allowed = 1,
|
||||
.suite = {
|
||||
.cipher = __VECS(des3_ede_tv_template)
|
||||
}
|
||||
|
@ -257,9 +257,9 @@ static const struct akcipher_testvec rsa_tv_template[] = {
|
||||
}, {
|
||||
#endif
|
||||
.key =
|
||||
"\x30\x82\x02\x1F" /* sequence of 543 bytes */
|
||||
"\x30\x82\x02\x20" /* sequence of 544 bytes */
|
||||
"\x02\x01\x01" /* version - integer of 1 byte */
|
||||
"\x02\x82\x01\x00" /* modulus - integer of 256 bytes */
|
||||
"\x02\x82\x01\x01\x00" /* modulus - integer of 256 bytes */
|
||||
"\xDB\x10\x1A\xC2\xA3\xF1\xDC\xFF\x13\x6B\xED\x44\xDF\xF0\x02\x6D"
|
||||
"\x13\xC7\x88\xDA\x70\x6B\x54\xF1\xE8\x27\xDC\xC3\x0F\x99\x6A\xFA"
|
||||
"\xC6\x67\xFF\x1D\x1E\x3C\x1D\xC1\xB5\x5F\x6C\xC0\xB2\x07\x3A\x6D"
|
||||
@ -299,7 +299,7 @@ static const struct akcipher_testvec rsa_tv_template[] = {
|
||||
"\x02\x01\x00" /* exponent1 - integer of 1 byte */
|
||||
"\x02\x01\x00" /* exponent2 - integer of 1 byte */
|
||||
"\x02\x01\x00", /* coefficient - integer of 1 byte */
|
||||
.key_len = 547,
|
||||
.key_len = 548,
|
||||
.m = "\x54\x85\x9b\x34\x2c\x49\xea\x2a",
|
||||
.c =
|
||||
"\xb2\x97\x76\xb4\xae\x3e\x38\x3c\x7e\x64\x1f\xcc\xa2\x7f\xf6\xbe"
|
||||
@ -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"
|
||||
|
@ -18,22 +18,22 @@
|
||||
#define ZSTD_DEF_LEVEL 3
|
||||
|
||||
struct zstd_ctx {
|
||||
ZSTD_CCtx *cctx;
|
||||
ZSTD_DCtx *dctx;
|
||||
zstd_cctx *cctx;
|
||||
zstd_dctx *dctx;
|
||||
void *cwksp;
|
||||
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)
|
||||
{
|
||||
int ret = 0;
|
||||
const ZSTD_parameters params = zstd_params();
|
||||
const size_t wksp_size = ZSTD_CCtxWorkspaceBound(params.cParams);
|
||||
const zstd_parameters params = zstd_params();
|
||||
const size_t wksp_size = zstd_cctx_workspace_bound(¶ms.cParams);
|
||||
|
||||
ctx->cwksp = vzalloc(wksp_size);
|
||||
if (!ctx->cwksp) {
|
||||
@ -41,7 +41,7 @@ static int zstd_comp_init(struct zstd_ctx *ctx)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx->cctx = ZSTD_initCCtx(ctx->cwksp, wksp_size);
|
||||
ctx->cctx = zstd_init_cctx(ctx->cwksp, wksp_size);
|
||||
if (!ctx->cctx) {
|
||||
ret = -EINVAL;
|
||||
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)
|
||||
{
|
||||
int ret = 0;
|
||||
const size_t wksp_size = ZSTD_DCtxWorkspaceBound();
|
||||
const size_t wksp_size = zstd_dctx_workspace_bound();
|
||||
|
||||
ctx->dwksp = vzalloc(wksp_size);
|
||||
if (!ctx->dwksp) {
|
||||
@ -64,7 +64,7 @@ static int zstd_decomp_init(struct zstd_ctx *ctx)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ctx->dctx = ZSTD_initDCtx(ctx->dwksp, wksp_size);
|
||||
ctx->dctx = zstd_init_dctx(ctx->dwksp, wksp_size);
|
||||
if (!ctx->dctx) {
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
@ -152,10 +152,10 @@ static int __zstd_compress(const u8 *src, unsigned int slen,
|
||||
{
|
||||
size_t out_len;
|
||||
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);
|
||||
if (ZSTD_isError(out_len))
|
||||
out_len = zstd_compress_cctx(zctx->cctx, dst, *dlen, src, slen, ¶ms);
|
||||
if (zstd_is_error(out_len))
|
||||
return -EINVAL;
|
||||
*dlen = out_len;
|
||||
return 0;
|
||||
@ -182,8 +182,8 @@ static int __zstd_decompress(const u8 *src, unsigned int slen,
|
||||
size_t out_len;
|
||||
struct zstd_ctx *zctx = ctx;
|
||||
|
||||
out_len = ZSTD_decompressDCtx(zctx->dctx, dst, *dlen, src, slen);
|
||||
if (ZSTD_isError(out_len))
|
||||
out_len = zstd_decompress_dctx(zctx->dctx, dst, *dlen, src, slen);
|
||||
if (zstd_is_error(out_len))
|
||||
return -EINVAL;
|
||||
*dlen = out_len;
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user