From 2d439db8f7402cd2fa3b848f308f503300bb6a73 Mon Sep 17 00:00:00 2001 From: Gaosheng Cui Date: Mon, 19 Jun 2023 21:24:24 +0800 Subject: KEYS: fix kernel-doc warnings in verify_pefile Fix kernel-doc warnings in verify_pefile: crypto/asymmetric_keys/verify_pefile.c:423: warning: Excess function parameter 'trust_keys' description in 'verify_pefile_signature' crypto/asymmetric_keys/verify_pefile.c:423: warning: Function parameter or member 'trusted_keys' not described in 'verify_pefile_signature' Signed-off-by: Gaosheng Cui Signed-off-by: Herbert Xu --- crypto/asymmetric_keys/verify_pefile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index 22beaf22..f440767b 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c @@ -391,7 +391,7 @@ error_no_desc: * verify_pefile_signature - Verify the signature on a PE binary image * @pebuf: Buffer containing the PE binary image * @pelen: Length of the binary image - * @trust_keys: Signing certificate(s) to use as starting points + * @trusted_keys: Signing certificate(s) to use as starting points * @usage: The use to which the key is being put. * * Validate that the certificate chain inside the PKCS#7 message inside the PE -- cgit v1.2.3 From 04902aa6217b01e858cc7cd8f287da39418ede3a Mon Sep 17 00:00:00 2001 From: Azeem Shaikh Date: Tue, 20 Jun 2023 20:08:32 +0000 Subject: crypto: lrw,xts - Replace strlcpy with strscpy strlcpy() reads the entire source buffer first. This read may exceed the destination size limit. This is both inefficient and can lead to linear read overflows if a source string is not NUL-terminated [1]. In an effort to remove strlcpy() completely [2], replace strlcpy() here with strscpy(). Direct replacement is safe here since return value of -errno is used to check for truncation instead of sizeof(dest). [1] https://www.kernel.org/doc/html/latest/process/deprecated.html#strlcpy [2] https://github.com/KSPP/linux/issues/89 Signed-off-by: Azeem Shaikh Reviewed-by: Kees Cook Signed-off-by: Herbert Xu --- crypto/lrw.c | 6 +++--- crypto/xts.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crypto/lrw.c b/crypto/lrw.c index 1b0f76ba..59260aef 100644 --- a/crypto/lrw.c +++ b/crypto/lrw.c @@ -357,10 +357,10 @@ static int lrw_create(struct crypto_template *tmpl, struct rtattr **tb) * cipher name. */ if (!strncmp(cipher_name, "ecb(", 4)) { - unsigned len; + int len; - len = strlcpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); - if (len < 2 || len >= sizeof(ecb_name)) + len = strscpy(ecb_name, cipher_name + 4, sizeof(ecb_name)); + if (len < 2) goto err_free_inst; if (ecb_name[len - 1] != ')') diff --git a/crypto/xts.c b/crypto/xts.c index 09be909a..548b302c 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -396,10 +396,10 @@ static int xts_create(struct crypto_template *tmpl, struct rtattr **tb) * cipher name. */ if (!strncmp(cipher_name, "ecb(", 4)) { - unsigned len; + int len; - len = strlcpy(ctx->name, cipher_name + 4, sizeof(ctx->name)); - if (len < 2 || len >= sizeof(ctx->name)) + len = strscpy(ctx->name, cipher_name + 4, sizeof(ctx->name)); + if (len < 2) goto err_free_inst; if (ctx->name[len - 1] != ')') -- cgit v1.2.3 From e575fa651a63d3a55785977be53d18ed660d23ad Mon Sep 17 00:00:00 2001 From: Jiapeng Chong Date: Fri, 30 Jun 2023 15:54:24 +0800 Subject: crypto: sig - Remove some unused functions These functions are defined in the sig.c file, but not called elsewhere, so delete these unused functions. crypto/sig.c:24:34: warning: unused function '__crypto_sig_tfm'. Reported-by: Abaci Robot Closes: https://bugzilla.openanolis.cn/show_bug.cgi?id=5701 Signed-off-by: Jiapeng Chong Signed-off-by: Herbert Xu --- crypto/sig.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/crypto/sig.c b/crypto/sig.c index b48c18ec..224c4701 100644 --- a/crypto/sig.c +++ b/crypto/sig.c @@ -21,11 +21,6 @@ static const struct crypto_type crypto_sig_type; -static inline struct crypto_sig *__crypto_sig_tfm(struct crypto_tfm *tfm) -{ - return container_of(tfm, struct crypto_sig, base); -} - static int crypto_sig_init_tfm(struct crypto_tfm *tfm) { if (tfm->__crt_alg->cra_type != &crypto_sig_type) -- cgit v1.2.3 From 92fb7f1da9cf9e74f3100fcd05fc7f2b87333406 Mon Sep 17 00:00:00 2001 From: Mahmoud Adam Date: Mon, 17 Jul 2023 12:55:09 +0000 Subject: KEYS: use kfree_sensitive with key key might contain private part of the key, so better use kfree_sensitive to free it Signed-off-by: Mahmoud Adam Signed-off-by: Herbert Xu --- crypto/asymmetric_keys/public_key.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 773e159d..abeecb83 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -42,7 +42,7 @@ static void public_key_describe(const struct key *asymmetric_key, void public_key_free(struct public_key *key) { if (key) { - kfree(key->key); + kfree_sensitive(key->key); kfree(key->params); kfree(key); } @@ -263,7 +263,7 @@ error_free_tfm: else crypto_free_akcipher(tfm); error_free_key: - kfree(key); + kfree_sensitive(key); pr_devel("<==%s() = %d\n", __func__, ret); return ret; } @@ -369,7 +369,7 @@ error_free_tfm: else crypto_free_akcipher(tfm); error_free_key: - kfree(key); + kfree_sensitive(key); pr_devel("<==%s() = %d\n", __func__, ret); return ret; } @@ -441,7 +441,7 @@ int public_key_verify_signature(const struct public_key *pkey, sig->digest, sig->digest_size); error_free_key: - kfree(key); + kfree_sensitive(key); error_free_tfm: crypto_free_sig(tfm); pr_devel("<==%s() = %d\n", __func__, ret); -- cgit v1.2.3 From 2841abbe70a763f0a5577126fbc61527a4c7c454 Mon Sep 17 00:00:00 2001 From: David Howells Date: Wed, 26 Jul 2023 22:53:19 +0100 Subject: crypto: af_alg - Fix missing initialisation affecting gcm-aes-s390 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix af_alg_alloc_areq() to initialise areq->first_rsgl.sgl.sgt.sgl to point to the scatterlist array in areq->first_rsgl.sgl.sgl. Without this, the gcm-aes-s390 driver will oops when it tries to do gcm_walk_start() on req->dst because req->dst is set to the value of areq->first_rsgl.sgl.sgl by _aead_recvmsg() calling aead_request_set_crypt(). The problem comes if an empty ciphertext is passed: the loop in af_alg_get_rsgl() just passes straight out and doesn't set areq->first_rsgl up. This isn't a problem on x86_64 using gcmaes_crypt_by_sg() because, as far as I can tell, that ignores req->dst and only uses req->src[*]. [*] Is this a bug in aesni-intel_glue.c? The s390x oops looks something like: Unable to handle kernel pointer dereference in virtual kernel address space Failing address: 0000000a00000000 TEID: 0000000a00000803 Fault in home space mode while using kernel ASCE. AS:00000000a43a0007 R3:0000000000000024 Oops: 003b ilc:2 [#1] SMP ... Call Trace: [<000003ff7fc3d47e>] gcm_walk_start+0x16/0x28 [aes_s390] [<00000000a2a342f2>] crypto_aead_decrypt+0x9a/0xb8 [<00000000a2a60888>] aead_recvmsg+0x478/0x698 [<00000000a2e519a0>] sock_recvmsg+0x70/0xb0 [<00000000a2e51a56>] sock_read_iter+0x76/0xa0 [<00000000a273e066>] vfs_read+0x26e/0x2a8 [<00000000a273e8c4>] ksys_read+0xbc/0x100 [<00000000a311d808>] __do_syscall+0x1d0/0x1f8 [<00000000a312ff30>] system_call+0x70/0x98 Last Breaking-Event-Address: [<000003ff7fc3e6b4>] gcm_aes_crypt+0x104/0xa68 [aes_s390] Fixes: 023da088aecb ("crypto: af_alg: Use extract_iter_to_sg() to create scatterlists") Reported-by: Ondrej Mosnáček Link: https://lore.kernel.org/r/CAAUqJDuRkHE8fPgZJGaKjUjd3QfGwzfumuJBmStPqBhubxyk_A@mail.gmail.com/ Signed-off-by: David Howells cc: Herbert Xu cc: Sven Schnelle cc: Harald Freudenberger cc: "David S. Miller" cc: Paolo Abeni cc: linux-crypto@vger.kernel.org cc: linux-s390@vger.kernel.org cc: regressions@lists.linux.dev Tested-by: Sven Schnelle Tested-by: Ondrej Mosnáček Signed-off-by: Herbert Xu --- crypto/af_alg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 06b15b9f..9ee8575d 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -1192,6 +1192,7 @@ struct af_alg_async_req *af_alg_alloc_areq(struct sock *sk, areq->areqlen = areqlen; areq->sk = sk; + areq->first_rsgl.sgl.sgt.sgl = areq->first_rsgl.sgl.sgl; areq->last_rsgl = NULL; INIT_LIST_HEAD(&areq->rsgl_list); areq->tsgl = NULL; -- cgit v1.2.3 From 3a830c4ffeadcc50253e02f47538600dd7217aee Mon Sep 17 00:00:00 2001 From: Frederick Lawler Date: Tue, 1 Aug 2023 08:57:09 -0500 Subject: crypto: af_alg - Decrement struct key.usage in alg_set_by_key_serial() Calls to lookup_user_key() require a corresponding key_put() to decrement the usage counter. Once it reaches zero, we schedule key GC. Therefore decrement struct key.usage in alg_set_by_key_serial(). Fixes: 4fdd110f6f3f ("crypto: af_alg - Support symmetric encryption via keyring keys") Cc: Signed-off-by: Frederick Lawler Signed-off-by: Herbert Xu --- crypto/af_alg.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 9ee8575d..e9969dc0 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -320,18 +320,21 @@ static int alg_setkey_by_key_serial(struct alg_sock *ask, sockptr_t optval, if (IS_ERR(ret)) { up_read(&key->sem); + key_put(key); return PTR_ERR(ret); } key_data = sock_kmalloc(&ask->sk, key_datalen, GFP_KERNEL); if (!key_data) { up_read(&key->sem); + key_put(key); return -ENOMEM; } memcpy(key_data, ret, key_datalen); up_read(&key->sem); + key_put(key); err = type->setkey(ask->private, key_data, key_datalen); -- cgit v1.2.3 From e631a4734dbbca9072090a7709b196a1bf963ee6 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 3 Aug 2023 17:59:28 +0800 Subject: crypto: api - Use work queue in crypto_destroy_instance The function crypto_drop_spawn expects to be called in process context. However, when an instance is unregistered while it still has active users, the last user may cause the instance to be freed in atomic context. Fix this by delaying the freeing to a work queue. Fixes: 525ed3dcb430 ("[CRYPTO] api: Added spawns") Reported-by: Florent Revest Reported-by: syzbot+d769eed29cc42d75e2a3@syzkaller.appspotmail.com Reported-by: syzbot+610ec0671f51e838436e@syzkaller.appspotmail.com Signed-off-by: Herbert Xu Tested-by: Florent Revest Acked-by: Florent Revest Signed-off-by: Herbert Xu --- crypto/algapi.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crypto/algapi.c b/crypto/algapi.c index 5e7cd603..4fe95c44 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "internal.h" @@ -74,15 +75,26 @@ static void crypto_free_instance(struct crypto_instance *inst) inst->alg.cra_type->free(inst); } -static void crypto_destroy_instance(struct crypto_alg *alg) +static void crypto_destroy_instance_workfn(struct work_struct *w) { - struct crypto_instance *inst = (void *)alg; + struct crypto_instance *inst = container_of(w, struct crypto_instance, + free_work); struct crypto_template *tmpl = inst->tmpl; crypto_free_instance(inst); crypto_tmpl_put(tmpl); } +static void crypto_destroy_instance(struct crypto_alg *alg) +{ + struct crypto_instance *inst = container_of(alg, + struct crypto_instance, + alg); + + INIT_WORK(&inst->free_work, crypto_destroy_instance_workfn); + schedule_work(&inst->free_work); +} + /* * This function adds a spawn to the list secondary_spawns which * will be used at the end of crypto_remove_spawns to unregister -- cgit v1.2.3 From 61e2a6b7e0ec1c74fbd2951cb4254884ce5a2ad9 Mon Sep 17 00:00:00 2001 From: Joachim Vandersmissen Date: Sun, 6 Aug 2023 14:19:03 -0500 Subject: crypto: jitter - Add clarifying comments to Jitter Entropy RCT cutoff values The RCT cutoff values are correct, but they don't exactly match the ones one would expect when computing them using the formula in SP800-90B. This discrepancy is due to the fact that the Jitter Entropy RCT starts at 1. To avoid any confusion by future reviewers, add some comments and explicitly subtract 1 from the "correct" cutoff values in the definitions. Signed-off-by: Joachim Vandersmissen Reviewed-by: Stephan Mueller Signed-off-by: Herbert Xu --- crypto/jitterentropy.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c index c7d7f2ca..fe9c233e 100644 --- a/crypto/jitterentropy.c +++ b/crypto/jitterentropy.c @@ -89,10 +89,14 @@ struct rand_data { unsigned int rct_count; /* Number of stuck values */ /* Intermittent health test failure threshold of 2^-30 */ -#define JENT_RCT_CUTOFF 30 /* Taken from SP800-90B sec 4.4.1 */ -#define JENT_APT_CUTOFF 325 /* Taken from SP800-90B sec 4.4.2 */ + /* From an SP800-90B perspective, this RCT cutoff value is equal to 31. */ + /* However, our RCT implementation starts at 1, so we subtract 1 here. */ +#define JENT_RCT_CUTOFF (31 - 1) /* Taken from SP800-90B sec 4.4.1 */ +#define JENT_APT_CUTOFF 325 /* Taken from SP800-90B sec 4.4.2 */ /* Permanent health test failure threshold of 2^-60 */ -#define JENT_RCT_CUTOFF_PERMANENT 60 + /* From an SP800-90B perspective, this RCT cutoff value is equal to 61. */ + /* However, our RCT implementation starts at 1, so we subtract 1 here. */ +#define JENT_RCT_CUTOFF_PERMANENT (61 - 1) #define JENT_APT_CUTOFF_PERMANENT 355 #define JENT_APT_WINDOW_SIZE 512 /* Data window size */ /* LSB of time stamp to process */ -- cgit v1.2.3 From ca533816d0923a435f4d3cbd05d2ee9a668e794f Mon Sep 17 00:00:00 2001 From: Eric Snowberg Date: Mon, 22 May 2023 19:09:42 -0400 Subject: KEYS: DigitalSignature link restriction Add a new link restriction. Restrict the addition of keys in a keyring based on the key having digitalSignature usage set. Additionally, verify the new certificate against the ones in the system keyrings. Add two additional functions to use the new restriction within either the builtin or secondary keyrings. [jarkko@kernel.org: Fix checkpatch.pl --strict issues] Signed-off-by: Eric Snowberg Reviewed-and-tested-by: Mimi Zohar Reviewed-by: Jarkko Sakkinen Signed-off-by: Jarkko Sakkinen --- crypto/asymmetric_keys/restrict.c | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c index 276bdb62..6b69ea40 100644 --- a/crypto/asymmetric_keys/restrict.c +++ b/crypto/asymmetric_keys/restrict.c @@ -148,6 +148,50 @@ int restrict_link_by_ca(struct key *dest_keyring, return 0; } +/** + * restrict_link_by_digsig - Restrict additions to a ring of digsig keys + * @dest_keyring: Keyring being linked to. + * @type: The type of key being added. + * @payload: The payload of the new key. + * @trust_keyring: A ring of keys that can be used to vouch for the new cert. + * + * Check if the new certificate has digitalSignature usage set. If it is, + * then mark the new certificate as being ok to link. Afterwards verify + * the new certificate against the ones in the trust_keyring. + * + * Returns 0 if the new certificate was accepted, -ENOKEY if the + * certificate is not a digsig. -ENOPKG if the signature uses unsupported + * crypto, or some other error if there is a matching certificate but + * the signature check cannot be performed. + */ +int restrict_link_by_digsig(struct key *dest_keyring, + const struct key_type *type, + const union key_payload *payload, + struct key *trust_keyring) +{ + const struct public_key *pkey; + + if (type != &key_type_asymmetric) + return -EOPNOTSUPP; + + pkey = payload->data[asym_crypto]; + + if (!pkey) + return -ENOPKG; + + if (!test_bit(KEY_EFLAG_DIGITALSIG, &pkey->key_eflags)) + return -ENOKEY; + + if (test_bit(KEY_EFLAG_CA, &pkey->key_eflags)) + return -ENOKEY; + + if (test_bit(KEY_EFLAG_KEYCERTSIGN, &pkey->key_eflags)) + return -ENOKEY; + + return restrict_link_by_signature(dest_keyring, type, payload, + trust_keyring); +} + static bool match_either_id(const struct asymmetric_key_id **pair, const struct asymmetric_key_id *single) { -- cgit v1.2.3 From e3cee839ef8886c26207127015653214c7a28b24 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 13 Aug 2023 14:54:32 +0800 Subject: crypto: engine - Remove prepare/unprepare request The callbacks for prepare and unprepare request in crypto_engine is superfluous. They can be done directly from do_one_request. Move the code into do_one_request and remove the unused callbacks. Signed-off-by: Herbert Xu --- crypto/crypto_engine.c | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c index 74fcc089..17f79555 100644 --- a/crypto/crypto_engine.c +++ b/crypto/crypto_engine.c @@ -26,9 +26,6 @@ static void crypto_finalize_request(struct crypto_engine *engine, struct crypto_async_request *req, int err) { unsigned long flags; - bool finalize_req = false; - int ret; - struct crypto_engine_ctx *enginectx; /* * If hardware cannot enqueue more requests @@ -38,21 +35,11 @@ static void crypto_finalize_request(struct crypto_engine *engine, if (!engine->retry_support) { spin_lock_irqsave(&engine->queue_lock, flags); if (engine->cur_req == req) { - finalize_req = true; engine->cur_req = NULL; } spin_unlock_irqrestore(&engine->queue_lock, flags); } - if (finalize_req || engine->retry_support) { - enginectx = crypto_tfm_ctx(req->tfm); - if (enginectx->op.prepare_request && - enginectx->op.unprepare_request) { - ret = enginectx->op.unprepare_request(engine, req); - if (ret) - dev_err(engine->dev, "failed to unprepare request\n"); - } - } lockdep_assert_in_softirq(); crypto_request_complete(req, err); @@ -141,20 +128,12 @@ start_request: ret = engine->prepare_crypt_hardware(engine); if (ret) { dev_err(engine->dev, "failed to prepare crypt hardware\n"); - goto req_err_2; + goto req_err_1; } } enginectx = crypto_tfm_ctx(async_req->tfm); - if (enginectx->op.prepare_request) { - ret = enginectx->op.prepare_request(engine, async_req); - if (ret) { - dev_err(engine->dev, "failed to prepare request: %d\n", - ret); - goto req_err_2; - } - } if (!enginectx->op.do_one_request) { dev_err(engine->dev, "failed to do request\n"); ret = -EINVAL; @@ -177,18 +156,6 @@ start_request: ret); goto req_err_1; } - /* - * If retry mechanism is supported, - * unprepare current request and - * enqueue it back into crypto-engine queue. - */ - if (enginectx->op.unprepare_request) { - ret = enginectx->op.unprepare_request(engine, - async_req); - if (ret) - dev_err(engine->dev, - "failed to unprepare request\n"); - } spin_lock_irqsave(&engine->queue_lock, flags); /* * If hardware was unable to execute request, enqueue it @@ -204,13 +171,6 @@ start_request: goto retry; req_err_1: - if (enginectx->op.unprepare_request) { - ret = enginectx->op.unprepare_request(engine, async_req); - if (ret) - dev_err(engine->dev, "failed to unprepare request\n"); - } - -req_err_2: crypto_request_complete(async_req, ret); retry: -- cgit v1.2.3 From 21c5ca0dfcd04d46de228f3fc2feb5110239fdd8 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 13 Aug 2023 14:54:36 +0800 Subject: crypto: engine - Move crypto inclusions out of header file The engine file does not need the actual crypto type definitions so move those header inclusions to where they are actually used. Signed-off-by: Herbert Xu --- crypto/crypto_engine.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c index 17f79555..ba43dfba 100644 --- a/crypto/crypto_engine.c +++ b/crypto/crypto_engine.c @@ -7,10 +7,15 @@ * Author: Baolin Wang */ +#include +#include +#include +#include +#include +#include #include #include #include -#include #include #include "internal.h" -- cgit v1.2.3 From 6432265de18ee6869b6edeac87f9ba1162e7d6b6 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 13 Aug 2023 14:54:41 +0800 Subject: crypto: engine - Create internal/engine.h Create crypto/internal/engine.h to house details that should not be used by drivers. It is empty for the time being. Signed-off-by: Herbert Xu --- crypto/crypto_engine.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c index ba43dfba..a75162bc 100644 --- a/crypto/crypto_engine.c +++ b/crypto/crypto_engine.c @@ -9,8 +9,8 @@ #include #include -#include #include +#include #include #include #include -- cgit v1.2.3 From e5b5b0c801e3132ef9461b0fd4ac36e10e4bb2eb Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 13 Aug 2023 14:54:49 +0800 Subject: crypto: engine - Move crypto_engine_ops from request into crypto_alg Rather than having the callback in the request, move it into the crypto_alg object. This avoids having crypto_engine look into the request context is private to the driver. Signed-off-by: Herbert Xu --- crypto/crypto_engine.c | 215 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 203 insertions(+), 12 deletions(-) diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c index a75162bc..abfb1e6b 100644 --- a/crypto/crypto_engine.c +++ b/crypto/crypto_engine.c @@ -7,20 +7,30 @@ * Author: Baolin Wang */ -#include -#include -#include +#include +#include #include -#include -#include +#include +#include +#include #include #include #include +#include +#include #include #include "internal.h" #define CRYPTO_ENGINE_MAX_QLEN 10 +/* Temporary algorithm flag used to indicate an updated driver. */ +#define CRYPTO_ALG_ENGINE 0x200 + +struct crypto_engine_alg { + struct crypto_alg base; + struct crypto_engine_op op; +}; + /** * crypto_finalize_request - finalize one request if the request is done * @engine: the hardware engine @@ -64,6 +74,8 @@ static void crypto_pump_requests(struct crypto_engine *engine, bool in_kthread) { struct crypto_async_request *async_req, *backlog; + struct crypto_engine_alg *alg; + struct crypto_engine_op *op; unsigned long flags; bool was_busy = false; int ret; @@ -137,15 +149,22 @@ start_request: } } - enginectx = crypto_tfm_ctx(async_req->tfm); - - if (!enginectx->op.do_one_request) { - dev_err(engine->dev, "failed to do request\n"); - ret = -EINVAL; - goto req_err_1; + if (async_req->tfm->__crt_alg->cra_flags & CRYPTO_ALG_ENGINE) { + alg = container_of(async_req->tfm->__crt_alg, + struct crypto_engine_alg, base); + op = &alg->op; + } else { + enginectx = crypto_tfm_ctx(async_req->tfm); + op = &enginectx->op; + + if (!op->do_one_request) { + dev_err(engine->dev, "failed to do request\n"); + ret = -EINVAL; + goto req_err_1; + } } - ret = enginectx->op.do_one_request(engine, async_req); + ret = op->do_one_request(engine, async_req); /* Request unsuccessfully executed by hardware */ if (ret < 0) { @@ -556,5 +575,177 @@ int crypto_engine_exit(struct crypto_engine *engine) } EXPORT_SYMBOL_GPL(crypto_engine_exit); +int crypto_engine_register_aead(struct aead_engine_alg *alg) +{ + if (!alg->op.do_one_request) + return -EINVAL; + + alg->base.base.cra_flags |= CRYPTO_ALG_ENGINE; + + return crypto_register_aead(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_register_aead); + +void crypto_engine_unregister_aead(struct aead_engine_alg *alg) +{ + crypto_unregister_aead(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_unregister_aead); + +int crypto_engine_register_aeads(struct aead_engine_alg *algs, int count) +{ + int i, ret; + + for (i = 0; i < count; i++) { + ret = crypto_engine_register_aead(&algs[i]); + if (ret) + goto err; + } + + return 0; + +err: + crypto_engine_unregister_aeads(algs, i); + + return ret; +} +EXPORT_SYMBOL_GPL(crypto_engine_register_aeads); + +void crypto_engine_unregister_aeads(struct aead_engine_alg *algs, int count) +{ + int i; + + for (i = count - 1; i >= 0; --i) + crypto_engine_unregister_aead(&algs[i]); +} +EXPORT_SYMBOL_GPL(crypto_engine_unregister_aeads); + +int crypto_engine_register_ahash(struct ahash_engine_alg *alg) +{ + if (!alg->op.do_one_request) + return -EINVAL; + + alg->base.halg.base.cra_flags |= CRYPTO_ALG_ENGINE; + + return crypto_register_ahash(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_register_ahash); + +void crypto_engine_unregister_ahash(struct ahash_engine_alg *alg) +{ + crypto_unregister_ahash(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_unregister_ahash); + +int crypto_engine_register_ahashes(struct ahash_engine_alg *algs, int count) +{ + int i, ret; + + for (i = 0; i < count; i++) { + ret = crypto_engine_register_ahash(&algs[i]); + if (ret) + goto err; + } + + return 0; + +err: + crypto_engine_unregister_ahashes(algs, i); + + return ret; +} +EXPORT_SYMBOL_GPL(crypto_engine_register_ahashes); + +void crypto_engine_unregister_ahashes(struct ahash_engine_alg *algs, + int count) +{ + int i; + + for (i = count - 1; i >= 0; --i) + crypto_engine_unregister_ahash(&algs[i]); +} +EXPORT_SYMBOL_GPL(crypto_engine_unregister_ahashes); + +int crypto_engine_register_akcipher(struct akcipher_engine_alg *alg) +{ + if (!alg->op.do_one_request) + return -EINVAL; + + alg->base.base.cra_flags |= CRYPTO_ALG_ENGINE; + + return crypto_register_akcipher(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_register_akcipher); + +void crypto_engine_unregister_akcipher(struct akcipher_engine_alg *alg) +{ + crypto_unregister_akcipher(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_unregister_akcipher); + +int crypto_engine_register_kpp(struct kpp_engine_alg *alg) +{ + if (!alg->op.do_one_request) + return -EINVAL; + + alg->base.base.cra_flags |= CRYPTO_ALG_ENGINE; + + return crypto_register_kpp(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_register_kpp); + +void crypto_engine_unregister_kpp(struct kpp_engine_alg *alg) +{ + crypto_unregister_kpp(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_unregister_kpp); + +int crypto_engine_register_skcipher(struct skcipher_engine_alg *alg) +{ + if (!alg->op.do_one_request) + return -EINVAL; + + alg->base.base.cra_flags |= CRYPTO_ALG_ENGINE; + + return crypto_register_skcipher(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_register_skcipher); + +void crypto_engine_unregister_skcipher(struct skcipher_engine_alg *alg) +{ + return crypto_unregister_skcipher(&alg->base); +} +EXPORT_SYMBOL_GPL(crypto_engine_unregister_skcipher); + +int crypto_engine_register_skciphers(struct skcipher_engine_alg *algs, + int count) +{ + int i, ret; + + for (i = 0; i < count; i++) { + ret = crypto_engine_register_skcipher(&algs[i]); + if (ret) + goto err; + } + + return 0; + +err: + crypto_engine_unregister_skciphers(algs, i); + + return ret; +} +EXPORT_SYMBOL_GPL(crypto_engine_register_skciphers); + +void crypto_engine_unregister_skciphers(struct skcipher_engine_alg *algs, + int count) +{ + int i; + + for (i = count - 1; i >= 0; --i) + crypto_engine_unregister_skcipher(&algs[i]); +} +EXPORT_SYMBOL_GPL(crypto_engine_unregister_skciphers); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Crypto hardware engine framework"); -- cgit v1.2.3 From 889ba14d3d5f1d20db2c66d09f0a9fa67c253525 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 13 Aug 2023 14:55:20 +0800 Subject: crypto: engine - Remove crypto_engine_ctx Remove the obsolete crypto_engine_ctx structure. Signed-off-by: Herbert Xu --- crypto/crypto_engine.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/crypto/crypto_engine.c b/crypto/crypto_engine.c index abfb1e6b..108d9d55 100644 --- a/crypto/crypto_engine.c +++ b/crypto/crypto_engine.c @@ -79,7 +79,6 @@ static void crypto_pump_requests(struct crypto_engine *engine, unsigned long flags; bool was_busy = false; int ret; - struct crypto_engine_ctx *enginectx; spin_lock_irqsave(&engine->queue_lock, flags); @@ -154,14 +153,9 @@ start_request: struct crypto_engine_alg, base); op = &alg->op; } else { - enginectx = crypto_tfm_ctx(async_req->tfm); - op = &enginectx->op; - - if (!op->do_one_request) { - dev_err(engine->dev, "failed to do request\n"); - ret = -EINVAL; - goto req_err_1; - } + dev_err(engine->dev, "failed to do request\n"); + ret = -EINVAL; + goto req_err_1; } ret = op->do_one_request(engine, async_req); -- cgit v1.2.3 From 520b1f5d9ce30fb1663c1148e1bbb35d7fc42de6 Mon Sep 17 00:00:00 2001 From: Pavel Skripkin Date: Mon, 14 Aug 2023 21:03:41 +0300 Subject: crypto: fix uninit-value in af_alg_free_resources Syzbot was able to trigger use of uninitialized memory in af_alg_free_resources. Bug is caused by missing initialization of rsgl->sgl.need_unpin before adding to rsgl_list. Then in case of extract_iter_to_sg() failure, rsgl is left with uninitialized need_unpin which is read during clean up BUG: KMSAN: uninit-value in af_alg_free_sg crypto/af_alg.c:545 [inline] BUG: KMSAN: uninit-value in af_alg_free_areq_sgls crypto/af_alg.c:778 [inline] BUG: KMSAN: uninit-value in af_alg_free_resources+0x3d1/0xf60 crypto/af_alg.c:1117 af_alg_free_sg crypto/af_alg.c:545 [inline] af_alg_free_areq_sgls crypto/af_alg.c:778 [inline] af_alg_free_resources+0x3d1/0xf60 crypto/af_alg.c:1117 _skcipher_recvmsg crypto/algif_skcipher.c:144 [inline] ... Uninit was created at: slab_post_alloc_hook+0x12f/0xb70 mm/slab.h:767 slab_alloc_node mm/slub.c:3470 [inline] __kmem_cache_alloc_node+0x536/0x8d0 mm/slub.c:3509 __do_kmalloc_node mm/slab_common.c:984 [inline] __kmalloc+0x121/0x3c0 mm/slab_common.c:998 kmalloc include/linux/slab.h:586 [inline] sock_kmalloc+0x128/0x1c0 net/core/sock.c:2683 af_alg_alloc_areq+0x41/0x2a0 crypto/af_alg.c:1188 _skcipher_recvmsg crypto/algif_skcipher.c:71 [inline] Fixes: 023da088aecb ("crypto: af_alg: Use extract_iter_to_sg() to create scatterlists") Reported-and-tested-by: syzbot+cba21d50095623218389@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=cba21d50095623218389 Signed-off-by: Pavel Skripkin Signed-off-by: Herbert Xu --- crypto/af_alg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index 06b15b9f..10efb56d 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -1241,6 +1241,8 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags, return -ENOMEM; } + rsgl->sgl.need_unpin = + iov_iter_extract_will_pin(&msg->msg_iter); rsgl->sgl.sgt.sgl = rsgl->sgl.sgl; rsgl->sgl.sgt.nents = 0; rsgl->sgl.sgt.orig_nents = 0; @@ -1255,8 +1257,6 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags, } sg_mark_end(rsgl->sgl.sgt.sgl + rsgl->sgl.sgt.nents - 1); - rsgl->sgl.need_unpin = - iov_iter_extract_will_pin(&msg->msg_iter); /* chain the new scatterlist with previous one */ if (areq->last_rsgl) -- cgit v1.2.3 From 827773a83d7340b5d4ee073695acc290774cb411 Mon Sep 17 00:00:00 2001 From: Thore Sommer Date: Tue, 15 Aug 2023 14:29:42 +0300 Subject: X.509: if signature is unsupported skip validation When the hash algorithm for the signature is not available the digest size is 0 and the signature in the certificate is marked as unsupported. When validating a self-signed certificate, this needs to be checked, because otherwise trying to validate the signature will fail with an warning: Loading compiled-in X.509 certificates WARNING: CPU: 0 PID: 1 at crypto/rsa-pkcs1pad.c:537 \ pkcs1pad_verify+0x46/0x12c ... Problem loading in-kernel X.509 certificate (-22) Signed-off-by: Thore Sommer Cc: stable@vger.kernel.org # v4.7+ Fixes: c68cd83d9915 ("X.509: Extract signature digest and make self-signed cert checks earlier") Signed-off-by: Herbert Xu --- crypto/asymmetric_keys/x509_public_key.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 6fdfc82e..7c71db3a 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c @@ -130,6 +130,11 @@ int x509_check_for_self_signed(struct x509_certificate *cert) goto out; } + if (cert->unsupported_sig) { + ret = 0; + goto out; + } + ret = public_key_verify_signature(cert->pub, cert->sig); if (ret < 0) { if (ret == -ENOPKG) { -- cgit v1.2.3 From af0da410464fb21bd9b7d70b7dad70ece687a017 Mon Sep 17 00:00:00 2001 From: Tianjia Zhang Date: Mon, 18 Sep 2023 16:38:50 +0800 Subject: crypto: sm2 - Fix crash caused by uninitialized context In sm2_compute_z_digest() function, the newly allocated structure mpi_ec_ctx is used, but forget to initialize it, which will cause a crash when performing subsequent operations. Fixes: 5dd39ae86c10 ("KEYS: asymmetric: Move sm2 code into x509_public_key") Cc: stable@vger.kernel.org # v6.5 Signed-off-by: Tianjia Zhang Signed-off-by: Herbert Xu --- crypto/sm2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crypto/sm2.c b/crypto/sm2.c index 285b3cb7..5ab120d7 100644 --- a/crypto/sm2.c +++ b/crypto/sm2.c @@ -278,10 +278,14 @@ int sm2_compute_z_digest(struct shash_desc *desc, if (!ec) return -ENOMEM; - err = __sm2_set_pub_key(ec, key, keylen); + err = sm2_ec_ctx_init(ec); if (err) goto out_free_ec; + err = __sm2_set_pub_key(ec, key, keylen); + if (err) + goto out_deinit_ec; + bits_len = SM2_DEFAULT_USERID_LEN * 8; entl[0] = bits_len >> 8; entl[1] = bits_len & 0xff; -- cgit v1.2.3 From 20c0d4fe1f8a911f4366571cac32749e9c0d10c6 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 16 Oct 2023 16:35:36 +0800 Subject: KEYS: asymmetric: Fix sign/verify on pkcs1pad without a hash The new sign/verify code broke the case of pkcs1pad without a hash algorithm. Fix it by setting issig correctly for this case. Fixes: 63a91af75117 ("KEYS: asymmetric: Use new crypto interface without scatterlists") Cc: stable@vger.kernel.org # v6.5 Reported-by: Denis Kenzior Signed-off-by: Herbert Xu Tested-by: Denis Kenzior Signed-off-by: Herbert Xu --- crypto/asymmetric_keys/public_key.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index abeecb83..1dcab279 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -81,14 +81,13 @@ software_key_determine_akcipher(const struct public_key *pkey, * RSA signatures usually use EMSA-PKCS1-1_5 [RFC3447 sec 8.2]. */ if (strcmp(encoding, "pkcs1") == 0) { + *sig = op == kernel_pkey_sign || + op == kernel_pkey_verify; if (!hash_algo) { - *sig = false; n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s)", pkey->pkey_algo); } else { - *sig = op == kernel_pkey_sign || - op == kernel_pkey_verify; n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, "pkcs1pad(%s,%s)", pkey->pkey_algo, hash_algo); -- cgit v1.2.3