Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp5560790iog; Thu, 23 Jun 2022 00:07:09 -0700 (PDT) X-Google-Smtp-Source: AGRyM1tuN4IVg5k45IHfR2JJNys/8aPS5o8HdIKgUOOTSXcd40gSftbbbKAVIx0LgQN8LtPPn6Ab X-Received: by 2002:a17:903:248:b0:168:cf03:eefe with SMTP id j8-20020a170903024800b00168cf03eefemr37303780plh.124.1655968029209; Thu, 23 Jun 2022 00:07:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1655968029; cv=none; d=google.com; s=arc-20160816; b=BTKqPpWpRNm6MQ51hhiUOdlpIX6U0hHblLjd0dbgF1liH9rAHT+J8obzQ76JNNM34k uhcycnA7txQOL/Nu0X+ZRNvNLnjJjYftwsNEPAMGhqXwxplE2Xa+Bb+PYy1DDB6CUnKQ pxNeZAT/jJYzW7tU/J41EmNE1tF1+brnDFUJ8iqrDIvqkGADu2KgrQmZAWhD/9xhVnEl u/zyo3RQ185C66ar9oIZ3Va7mvU4y/9omRVCgf+Xd+fiCNqkL4HsC5pma2jHjnBp4+Yb V5JyncrfiEa2zdglPzOt77VA4w8vhFPSqFn2DSWCx2528KdduZezwEgAiG2S3IA8qqCy Y2sA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=oTdRX4nzzh5XnScdkMS8ZCJNByGLkKSHjz8cEvYbU9o=; b=Ym4ODvwM6CfN7o4z7C/T+v0dLaEITAigKGuIT2/bnhJrDrkK8Yj26WxazHxKwMMI87 fc2FG2yu2/2m7csaWrHiLri6MIWGHwXV4NN67iEnKIkcSxPGgpMA2NoVBqDeMiORlgUl PzeB1BXPUcbINfYyAObPVt/ufDtdQUldHSvJKZsZYPawIY4z22AOttjGKOqxT+qkq7hp xFZ9h8yAigZvu7HOVEmX1ShpwkCzHd8qq2eVJiStUGaXf0sXFCtsgt3oiY9R5xKi0UnH oC/F1z0HNAR9bb/NX/7n/AHL5m2TOpVM9VWj94/81vZVHq9zKn+yLF/D7Fh8rEwDHXs3 p3/A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bytedance-com.20210112.gappssmtp.com header.s=20210112 header.b=iZYbYsqG; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=bytedance.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id qe12-20020a17090b4f8c00b001df8cee9818si2556305pjb.173.2022.06.23.00.06.43; Thu, 23 Jun 2022 00:07:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@bytedance-com.20210112.gappssmtp.com header.s=20210112 header.b=iZYbYsqG; spf=pass (google.com: domain of linux-crypto-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=bytedance.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230089AbiFWHGO (ORCPT + 99 others); Thu, 23 Jun 2022 03:06:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230072AbiFWHGI (ORCPT ); Thu, 23 Jun 2022 03:06:08 -0400 Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 72BA04552A for ; Thu, 23 Jun 2022 00:06:06 -0700 (PDT) Received: by mail-pj1-x102c.google.com with SMTP id d14so14506453pjs.3 for ; Thu, 23 Jun 2022 00:06:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bytedance-com.20210112.gappssmtp.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oTdRX4nzzh5XnScdkMS8ZCJNByGLkKSHjz8cEvYbU9o=; b=iZYbYsqGGdZupjhjwO8Klh7C9GQRFPlWPbx6yN0XRAsBfx1KAHbXQ7JlhzQjeOXJ+a SjPVgU0/bO8yaLCDkU+a2BkAu6vXMP0CMkgv27UgZhb5emsq/PWq5bTXhT1rgjRStSNi uMe418DKIHy8zAcWVQEfXn+hRvXndB3+WevUI39+dDQGCUPzwv1ZBhmfkjjZ90v/1TLK +m6oBQIh4QJJ/ZLEYBOA6rVaZMfaPZfKz4aL78E53CZzgcYZkDKllDwHRP5+s29Cj4L9 8SGsjIw9+oXZOe88YjgEkFlUM6L1KH7GU0SMLur/4x7qrkAxnOQdT/0/503QRTtiLh5I qRyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oTdRX4nzzh5XnScdkMS8ZCJNByGLkKSHjz8cEvYbU9o=; b=s6leUKMpeOFblg8QzaLt8RztbBajCOos4NDiqsg53IUyaxcGfPkkdJg1+Q3QPvBjzv Dprfg9uxjWzN9/BuumofnymXp2A/IYx7p8CzoBquyycxYbGB6InbVzsltKy1DvtgOTVp EZwnasSF7dA6SAM9iGM5jKveUl8cRnTLK2NmX8nIJGprkT5xJT9WRR3vSq++h720wyp0 kj/wwuz6Xz6V6Zv5l12mpTpGUwvSDgq/2M7iBB7TtLC4pyCLfOpiT27X/M7QAZDTjO3o n/oCxQhDRFFbjgZwirCCwzQodsIyAu7PG0UFHk9gc6Z9FRolkXsigwLCfD0c+KungOnE qeTg== X-Gm-Message-State: AJIora+WfadL30v6qS7pThEmTKF9bwAJupF5K5chzEUHOcYPATX2YOmr 6MNpInnepEnmXipWrZH9abrvQQ== X-Received: by 2002:a17:902:e945:b0:16a:1c41:f66 with SMTP id b5-20020a170902e94500b0016a1c410f66mr22591623pll.129.1655967965973; Thu, 23 Jun 2022 00:06:05 -0700 (PDT) Received: from FVFDK26JP3YV.bytedance.net ([139.177.225.250]) by smtp.gmail.com with ESMTPSA id ji1-20020a170903324100b0016a15842cf5sm9125184plb.121.2022.06.23.00.06.02 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 23 Jun 2022 00:06:05 -0700 (PDT) From: Lei He To: davem@davemloft.net, herbert@gondor.apana.org.au, dhowells@redhat.com Cc: mst@redhat.com, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, berrange@redhat.com, pizhenwei@bytedance.com, lei he Subject: [PATCH v2 1/4] crypto: fix the calculation of max_size for ECDSA Date: Thu, 23 Jun 2022 15:05:47 +0800 Message-Id: <20220623070550.82053-2-helei.sig11@bytedance.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20220623070550.82053-1-helei.sig11@bytedance.com> References: <20220623070550.82053-1-helei.sig11@bytedance.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org From: lei he The signature of ECDSA is consists of two big integers up to the size of keylen, and is DER encoded into one SEQUENCE. Calculate max_size of ECDSA signature more accurately according to the DER encoding rules. Signed-off-by: lei he --- crypto/Kconfig | 1 + crypto/Makefile | 2 ++ crypto/ecdsa.c | 3 ++- crypto/ecdsa_helper.c | 45 +++++++++++++++++++++++++++++++++ include/crypto/internal/ecdsa.h | 15 +++++++++++ include/linux/asn1_encoder.h | 2 ++ lib/asn1_encoder.c | 3 ++- 7 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 crypto/ecdsa_helper.c create mode 100644 include/crypto/internal/ecdsa.h diff --git a/crypto/Kconfig b/crypto/Kconfig index 19197469cfab..3e82c7bc8424 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -254,6 +254,7 @@ config CRYPTO_ECDSA select CRYPTO_ECC select CRYPTO_AKCIPHER select ASN1 + select ASN1_ENCODER help Elliptic Curve Digital Signature Algorithm (NIST P192, P256 etc.) is A NIST cryptographic standard algorithm. Only signature verification diff --git a/crypto/Makefile b/crypto/Makefile index 43bc33e247d1..226bc2cfb9b7 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -52,8 +52,10 @@ obj-$(CONFIG_CRYPTO_SM2) += sm2_generic.o $(obj)/ecdsasignature.asn1.o: $(obj)/ecdsasignature.asn1.c $(obj)/ecdsasignature.asn1.h $(obj)/ecdsa.o: $(obj)/ecdsasignature.asn1.h + ecdsa_generic-y += ecdsa.o ecdsa_generic-y += ecdsasignature.asn1.o +ecdsa_generic-y += ecdsa_helper.o obj-$(CONFIG_CRYPTO_ECDSA) += ecdsa_generic.o crypto_acompress-y := acompress.o diff --git a/crypto/ecdsa.c b/crypto/ecdsa.c index b3a8a6b572ba..2ba44c92d271 100644 --- a/crypto/ecdsa.c +++ b/crypto/ecdsa.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -262,7 +263,7 @@ static unsigned int ecdsa_max_size(struct crypto_akcipher *tfm) { struct ecc_ctx *ctx = akcipher_tfm_ctx(tfm); - return ctx->pub_key.ndigits << ECC_DIGITS_TO_BYTES_SHIFT; + return ecdsa_max_signature_size(ctx->curve); } static int ecdsa_nist_p384_init_tfm(struct crypto_akcipher *tfm) diff --git a/crypto/ecdsa_helper.c b/crypto/ecdsa_helper.c new file mode 100644 index 000000000000..487c4e9c0f67 --- /dev/null +++ b/crypto/ecdsa_helper.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * RSA key extract helper + * + * Copyright 2022 Bytedance CO., LTD. + * + * Authors: lei he + */ +#include +#include +#include +#include +#include +#include + +unsigned int ecdsa_max_signature_size(const struct ecc_curve *curve) +{ + unsigned int keylen = curve->g.ndigits * sizeof(u64); + /* Up to one extra byte to indicate the format */ + unsigned char buffer[sizeof(size_t) + 1], *data = buffer; + int buffer_len = sizeof(buffer); + unsigned int coordinate_length, sequence_length; + + asn1_encode_length(&data, &buffer_len, keylen); + /** + * The extra cost for encoding keylen bytes as INTEGER in ASN.1: + * 1. one byte for tag + * 2. sizeof(buffer) - buffer_len bytes for length + * 3. one leading zero byte for integers whose leftmost bit is 1 + */ + coordinate_length = 1 + sizeof(buffer) - buffer_len + 1 + keylen; + + /** + * The extra cost for encoding coordinate_length * 2 bytes as SEQUENCE in ASN.1: + * 1. one byte for tag + * 2. sizeof(buffer) - buffer_len bytes for length + */ + buffer_len = sizeof(buffer); + data = buffer; + asn1_encode_length(&data, &buffer_len, coordinate_length * 2); + sequence_length = 1 + sizeof(buffer) - buffer_len + coordinate_length * 2; + + return sequence_length; +} +EXPORT_SYMBOL_GPL(ecdsa_max_signature_size); diff --git a/include/crypto/internal/ecdsa.h b/include/crypto/internal/ecdsa.h new file mode 100644 index 000000000000..e35638a35dc2 --- /dev/null +++ b/include/crypto/internal/ecdsa.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * ECDSA internal helpers + * + * Copyright (c) 2022 lei he + */ + + #ifndef _CRYPTO_ECDSA_H + #define _CRYPTO_ECDSA_H + +#include + +unsigned int ecdsa_max_signature_size(const struct ecc_curve *curve); + +#endif diff --git a/include/linux/asn1_encoder.h b/include/linux/asn1_encoder.h index 08cd0c2ad34f..fe439c9a73e3 100644 --- a/include/linux/asn1_encoder.h +++ b/include/linux/asn1_encoder.h @@ -29,4 +29,6 @@ unsigned char * asn1_encode_boolean(unsigned char *data, const unsigned char *end_data, bool val); +int asn1_encode_length(unsigned char **data, int *data_len, int len); + #endif diff --git a/lib/asn1_encoder.c b/lib/asn1_encoder.c index 0fd3c454a468..644af3055ebb 100644 --- a/lib/asn1_encoder.c +++ b/lib/asn1_encoder.c @@ -188,7 +188,7 @@ EXPORT_SYMBOL_GPL(asn1_encode_oid); * encoder primitives to accept negative lengths as singalling the * sequence will be re-encoded when the length is known. */ -static int asn1_encode_length(unsigned char **data, int *data_len, int len) +int asn1_encode_length(unsigned char **data, int *data_len, int len) { if (*data_len < 1) return -EINVAL; @@ -239,6 +239,7 @@ static int asn1_encode_length(unsigned char **data, int *data_len, int len) return 0; } +EXPORT_SYMBOL_GPL(asn1_encode_length); /** * asn1_encode_tag() - add a tag for optional or explicit value -- 2.20.1