From patchwork Fri Jan 14 08:19:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 12713461 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92DADC433EF for ; Fri, 14 Jan 2022 08:22:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240477AbiANIWX (ORCPT ); Fri, 14 Jan 2022 03:22:23 -0500 Received: from dfw.source.kernel.org ([139.178.84.217]:60024 "EHLO dfw.source.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239965AbiANIVM (ORCPT ); Fri, 14 Jan 2022 03:21:12 -0500 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 0CC0D61E34; Fri, 14 Jan 2022 08:21:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 44E28C36AED; Fri, 14 Jan 2022 08:21:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1642148471; bh=Y8I8G02qtt+1LJcVr6kJCIIHChwaLeQ0Deg0+o4Caa8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mZ4JjzxTCh0Vi1sV81c40V13i0OhsdxV4lUsjAoo4dzwr+ZZA7AtFa/LjnOanKa0U 6Aw0v21mbmsg83jWnPNsntNj82bzqVDW2Nu7oKFUxfXi+iCBj7UpGyptUpkOIoQq7e ZE3c49Gxn4G2mRak6E9pB3jC0FcWkM95wHw+BqJfsSLBRqpkdDY+wQLtV11i0hIoxZ aGfFYAzD8sgaSOsAc5OhpPOA9/2tYRATEJf8l5IhWRykOr/w0oTL2Yn5FNuaEZnSMG lWg+9nSn5tV5h4qGu4rwUwKSI2lq2oEKc2CzzFRl7C9jiKyasH6a8i6fgwVm+J0ro5 tha7V8d1vmSiw== From: Eric Biggers To: linux-crypto@vger.kernel.org, Herbert Xu Cc: keyrings@vger.kernel.org, Vitaly Chikunov , Denis Kenzior , stable@vger.kernel.org Subject: [PATCH 1/3] crypto: rsa-pkcs1pad - correctly get hash from source scatterlist Date: Fri, 14 Jan 2022 00:19:37 -0800 Message-Id: <20220114081939.218416-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220114081939.218416-1-ebiggers@kernel.org> References: <20220114081939.218416-1-ebiggers@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org From: Eric Biggers Commit c7381b012872 ("crypto: akcipher - new verify API for public key algorithms") changed akcipher_alg::verify to take in both the signature and the actual hash and do the signature verification, rather than just return the hash expected by the signature as was the case before. To do this, it implemented a hack where the signature and hash are concatenated with each other in one scatterlist. Obviously, for this to work correctly, akcipher_alg::verify needs to correctly extract the two items from the scatterlist it is given. Unfortunately, it doesn't correctly extract the hash in the case where the signature is longer than the RSA key size, as it assumes that the signature's length is equal to the RSA key size. This causes a prefix of the hash, or even the entire hash, to be taken from the *signature*. It is unclear whether the resulting scheme has any useful security properties. Fix this by correctly extracting the hash from the scatterlist. Fixes: c7381b012872 ("crypto: akcipher - new verify API for public key algorithms") Cc: # v5.2+ Signed-off-by: Eric Biggers Reviewed-by: Vitaly Chikunov --- crypto/rsa-pkcs1pad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index 1b3545781425..7b223adebabf 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c @@ -495,7 +495,7 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) sg_nents_for_len(req->src, req->src_len + req->dst_len), req_ctx->out_buf + ctx->key_size, - req->dst_len, ctx->key_size); + req->dst_len, req->src_len); /* Do the actual verification step. */ if (memcmp(req_ctx->out_buf + ctx->key_size, out_buf + pos, req->dst_len) != 0) From patchwork Fri Jan 14 08:19:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 12713463 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 55BD0C433EF for ; Fri, 14 Jan 2022 08:22:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240228AbiANIWo (ORCPT ); Fri, 14 Jan 2022 03:22:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50054 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240269AbiANIV1 (ORCPT ); Fri, 14 Jan 2022 03:21:27 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C11C5C0617A7; Fri, 14 Jan 2022 00:21:12 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 61BB361E37; Fri, 14 Jan 2022 08:21:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 971C7C36AE9; Fri, 14 Jan 2022 08:21:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1642148471; bh=42/E2d5qp+aGEb3LON47WXAM0iCKqIGuFaGn17hu4ts=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JwEY2mD2KTqbOdCNrAF+34oRuR7ZeEHeS/ssxh6swbbl2GJscXxJezaxAQOpJbh9J 3x4uIyVb4YHrVnFeh8wkaKu5qE5MyUq0m90yTEp8pKnfr7d7kv+IV4ZwpLD8ZHnuPS v+xhwlpjy/gshT8EQK6DqXqYmfFP5JS4dW+CP7da/TxARNnSU7t/dZoMyf8gshjlU2 wo+y2dnnQIbpTgv9TqgqAjxdgo+C55QOklM48homFpxz9JdKq7OuHK6QJRQEARV0kj zwtlTnolTgK85pyq+x8MxKDvDr0ab8GQ1YZv2lw00hLX7iP5q82CtfMDbcLUzzBh2i 6PMtXfp96PW6w== From: Eric Biggers To: linux-crypto@vger.kernel.org, Herbert Xu Cc: keyrings@vger.kernel.org, Vitaly Chikunov , Denis Kenzior , Tadeusz Struk , stable@vger.kernel.org Subject: [PATCH 2/3] crypto: rsa-pkcs1pad - fix buffer overread in pkcs1pad_verify_complete() Date: Fri, 14 Jan 2022 00:19:38 -0800 Message-Id: <20220114081939.218416-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220114081939.218416-1-ebiggers@kernel.org> References: <20220114081939.218416-1-ebiggers@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org From: Eric Biggers Before checking whether the expected digest_info is present, we need to check that there are enough bytes remaining. Fixes: a49de377e051 ("crypto: Add hash param to pkcs1pad") Cc: Tadeusz Struk Cc: # v4.6+ Signed-off-by: Eric Biggers --- crypto/rsa-pkcs1pad.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index 7b223adebabf..6cd24b4b9b9e 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c @@ -476,6 +476,8 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) pos++; if (digest_info) { + if (digest_info->size > dst_len - pos) + goto done; if (crypto_memneq(out_buf + pos, digest_info->data, digest_info->size)) goto done; From patchwork Fri Jan 14 08:19:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 12713464 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2389EC433F5 for ; Fri, 14 Jan 2022 08:22:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240004AbiANIW4 (ORCPT ); Fri, 14 Jan 2022 03:22:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50328 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240208AbiANIVU (ORCPT ); Fri, 14 Jan 2022 03:21:20 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6B0D0C0617A9; Fri, 14 Jan 2022 00:21:12 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 4D8F061E30; Fri, 14 Jan 2022 08:21:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F08F2C36AEA; Fri, 14 Jan 2022 08:21:11 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1642148472; bh=Dk3kLypObH2mqW0ZKWU+/2CO0Ao8WaPUXgjLmFLpykk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TqZ7D66vF/3eCKKjWN6fxPaZq/PMrA1ZwxQTIUadcxOdeI/n5kYfPUTLHt67hSjgr m1sDzCIYh/A0QHohL+S5tW9bOnRibwSePvphDF0oIwaWXKhEmXLy3/2Gvb4T/hyTSN /0w/moE9pVdPBPcj1MMVCKAFR2J2oElmgX/RPge55OJj1lAkr/lixRRpu/IdWwa793 oexDBmEmKOdmhOSPaa49JKjJXXl8UEbrByZS0/+YKYvC7+YGf4jQVCn47jrmaI2Er1 Ki5k9bqIMdpecmjn2TZI2us51QlQid1MZNCvmmMEKC7KrYMr5aWiT4O9p3MRETsg+z /3AKDtbUJXOdg== From: Eric Biggers To: linux-crypto@vger.kernel.org, Herbert Xu Cc: keyrings@vger.kernel.org, Vitaly Chikunov , Denis Kenzior Subject: [PATCH 3/3] crypto: rsa-pkcs1pad - use clearer variable names Date: Fri, 14 Jan 2022 00:19:39 -0800 Message-Id: <20220114081939.218416-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220114081939.218416-1-ebiggers@kernel.org> References: <20220114081939.218416-1-ebiggers@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org From: Eric Biggers The new convention for akcipher_alg::verify makes it unclear which values are the lengths of the signature and digest. Add local variables to make it clearer what is going on. Also rename the digest_size variable in pkcs1pad_sign(), as it is actually the digest *info* size, not the digest size which is different. Signed-off-by: Eric Biggers --- crypto/rsa-pkcs1pad.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c index 6cd24b4b9b9e..8a3054a43735 100644 --- a/crypto/rsa-pkcs1pad.c +++ b/crypto/rsa-pkcs1pad.c @@ -385,15 +385,15 @@ static int pkcs1pad_sign(struct akcipher_request *req) struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst); const struct rsa_asn1_template *digest_info = ictx->digest_info; int err; - unsigned int ps_end, digest_size = 0; + unsigned int ps_end, digest_info_size = 0; if (!ctx->key_size) return -EINVAL; if (digest_info) - digest_size = digest_info->size; + digest_info_size = digest_info->size; - if (req->src_len + digest_size > ctx->key_size - 11) + if (req->src_len + digest_info_size > ctx->key_size - 11) return -EOVERFLOW; if (req->dst_len < ctx->key_size) { @@ -406,7 +406,7 @@ static int pkcs1pad_sign(struct akcipher_request *req) if (!req_ctx->in_buf) return -ENOMEM; - ps_end = ctx->key_size - digest_size - req->src_len - 2; + ps_end = ctx->key_size - digest_info_size - req->src_len - 2; req_ctx->in_buf[0] = 0x01; memset(req_ctx->in_buf + 1, 0xff, ps_end - 1); req_ctx->in_buf[ps_end] = 0x00; @@ -441,6 +441,8 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) struct akcipher_instance *inst = akcipher_alg_instance(tfm); struct pkcs1pad_inst_ctx *ictx = akcipher_instance_ctx(inst); const struct rsa_asn1_template *digest_info = ictx->digest_info; + const unsigned int sig_size = req->src_len; + const unsigned int digest_size = req->dst_len; unsigned int dst_len; unsigned int pos; u8 *out_buf; @@ -487,20 +489,19 @@ static int pkcs1pad_verify_complete(struct akcipher_request *req, int err) err = 0; - if (req->dst_len != dst_len - pos) { + if (digest_size != dst_len - pos) { err = -EKEYREJECTED; req->dst_len = dst_len - pos; goto done; } /* Extract appended digest. */ sg_pcopy_to_buffer(req->src, - sg_nents_for_len(req->src, - req->src_len + req->dst_len), + sg_nents_for_len(req->src, sig_size + digest_size), req_ctx->out_buf + ctx->key_size, - req->dst_len, req->src_len); + digest_size, sig_size); /* Do the actual verification step. */ if (memcmp(req_ctx->out_buf + ctx->key_size, out_buf + pos, - req->dst_len) != 0) + digest_size) != 0) err = -EKEYREJECTED; done: kfree_sensitive(req_ctx->out_buf); @@ -536,14 +537,15 @@ static int pkcs1pad_verify(struct akcipher_request *req) struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req); struct pkcs1pad_ctx *ctx = akcipher_tfm_ctx(tfm); struct pkcs1pad_request *req_ctx = akcipher_request_ctx(req); + const unsigned int sig_size = req->src_len; + const unsigned int digest_size = req->dst_len; int err; - if (WARN_ON(req->dst) || - WARN_ON(!req->dst_len) || - !ctx->key_size || req->src_len < ctx->key_size) + if (WARN_ON(req->dst) || WARN_ON(!digest_size) || + !ctx->key_size || sig_size < ctx->key_size) return -EINVAL; - req_ctx->out_buf = kmalloc(ctx->key_size + req->dst_len, GFP_KERNEL); + req_ctx->out_buf = kmalloc(ctx->key_size + digest_size, GFP_KERNEL); if (!req_ctx->out_buf) return -ENOMEM; @@ -556,8 +558,7 @@ static int pkcs1pad_verify(struct akcipher_request *req) /* Reuse input buffer, output to a new buffer */ akcipher_request_set_crypt(&req_ctx->child_req, req->src, - req_ctx->out_sg, req->src_len, - ctx->key_size); + req_ctx->out_sg, sig_size, ctx->key_size); err = crypto_akcipher_encrypt(&req_ctx->child_req); if (err != -EINPROGRESS && err != -EBUSY)