Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp139773iog; Fri, 17 Jun 2022 00:09:06 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vCl8xca4cRBXOOIwzaiA+GtIxUkIVLq24Qu27sHcT/imAtuwLIhQPR8+Bv6wIV8ZIPbJj2 X-Received: by 2002:a17:907:a407:b0:704:34ac:835c with SMTP id sg7-20020a170907a40700b0070434ac835cmr7922788ejc.663.1655449746464; Fri, 17 Jun 2022 00:09:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1655449746; cv=none; d=google.com; s=arc-20160816; b=HIgaYShSKgAG+5OQMJBYjcC1i3ukpZOia0LDzsxIk0oYR0fwzG7qrz5FOJUiRVTaeO NZ6nnjWtbaekYB9/nWYIf7tkuoyo6oyAMY1kyZJ9fbNIS59D6wZBheVRb/fTHLZEa4gW u0mx7MyiQGEW+EieJVbXCtQnDiewKRiv4DQycjS4/TaVIqeRjebG3BcX1kmuFMHYflf7 3yHemgmgYquJAXKXHTAHZ0cVvr5hZ+WhgBuwAUKw6voP6NimcxVXEPIMVG3rlfQyeyoe HlZU7RSvLiYAb6Igu31WCXlFbKox8PrbWSYqhx+//D/YcewqP+1uIVrP/e1anMHrzSJD YwHQ== 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=ehUSni+ddsWxiWUC9Vsg9AFV5u1hN4XtlUBq70uM3/Y=; b=rqOjptpe8acf6lca7mg0mQ0Ew8r4fmlddjRz2lE1A/3AcjI7f6wgUh7iJUdPe5mzgO bJDwPXluQo6hoeroXR7ZBAd5ZwoJHvydXdug2UgmJEs25n+jwcupayTiEUnYiyR/hUsu +dq7tLX2i8zYoEK6NGf9eswEZEvjlyd0XgT2qz9YzKhzuUI0EDHbh5UJ7L2xBH1EuF6q ZGTaqWGMy6f83WOAH4jtHO8YOoaK2mnUMqKoSP8Wq0AE2mCTSgmx5TF6bS6F1dYEO4bW SA8YR0no6w5TCKzdu4XhHuVR92NiN2BETeXlYpLHXFRFQZIAYicy/qjVH/HsZ2g4zyjG +KBg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bytedance-com.20210112.gappssmtp.com header.s=20210112 header.b=JEcTyJoT; 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 ev6-20020a056402540600b004355e62629fsi1212857edb.157.2022.06.17.00.08.38; Fri, 17 Jun 2022 00:09:06 -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=JEcTyJoT; 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 S1380366AbiFQHIa (ORCPT + 99 others); Fri, 17 Jun 2022 03:08:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1380095AbiFQHIQ (ORCPT ); Fri, 17 Jun 2022 03:08:16 -0400 Received: from mail-pj1-x1033.google.com (mail-pj1-x1033.google.com [IPv6:2607:f8b0:4864:20::1033]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0077F63533 for ; Fri, 17 Jun 2022 00:08:15 -0700 (PDT) Received: by mail-pj1-x1033.google.com with SMTP id gd1so3295313pjb.2 for ; Fri, 17 Jun 2022 00:08:15 -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=ehUSni+ddsWxiWUC9Vsg9AFV5u1hN4XtlUBq70uM3/Y=; b=JEcTyJoTA/2JVh2/RYjQrzVcoXo3GmPS3qUuYVsm2YIjDmmx5zEovpQ+qQqUFlmgq5 fHFYbR7bAyF0B0i0G8JJ3KjD1r2qAq9SeXhlkcx/dBlVFrm0TlfeAUZhzcBrh05vjf4d SBkdq7mpkJjKe5ojfZyO3iWKzBYbRGINNFsYSi6qUlwZDFf/0ycbnKCa5ppTDG+j85Qw umZpAfcfNUvfhv5KphLUd0G/ytcU6yyu1QGCWVULPpTs0h0JI9W7akf8hCvpX5aMbib1 VmcNUUC5PpIfgLVXW6fuCJ+Jwjzj6+GYmTc1dVId2jAjMHb14E4Jk/BvHNTQGCdypH+F ZmYw== 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=ehUSni+ddsWxiWUC9Vsg9AFV5u1hN4XtlUBq70uM3/Y=; b=PBpaqNjdnqEfXiMbZLSkGrsXLd3MbUxoKki8yK8rJeGuZssMXyRdiz6fvg+bLKrgKi xSOgaysmUcY7GS4HI1Fa00hTrKHexHpkve4/J9SdKCwpw9NUY+tIF2jNtd80xM4AXNAt DDJlag519ASVPtR6XLJMuphojv39YnMx+kFF2j4RNSjPwrtYmS1bEdLH+p3frlIGuhjm OfPHMB0J5zMfcQkADkou+KofJgSmaM6piiH7jWJri6wMckFwjYyDllx6e0DbHakApc5v 0fq2FNBdiHnsiSWxMr0LBMniUcNFHK0GsC0gbI07bnmabyF6JpasyetBHnohCcouqv/p KZDg== X-Gm-Message-State: AJIora/pBovBbiqf7Z3gpTOsYvle2IyODZKi6FHtrewP07HxmMOe6mX3 eELRaT5UeSy04WCvx+8S4589MQ== X-Received: by 2002:a17:903:22cb:b0:167:992f:60c3 with SMTP id y11-20020a17090322cb00b00167992f60c3mr8383332plg.59.1655449695368; Fri, 17 Jun 2022 00:08:15 -0700 (PDT) Received: from FVFDK26JP3YV.bytedance.net ([139.177.225.234]) by smtp.gmail.com with ESMTPSA id j1-20020a170903028100b00163d4c3ffabsm2757868plr.304.2022.06.17.00.08.11 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 17 Jun 2022 00:08:14 -0700 (PDT) From: Lei He To: herbert@gondor.apana.org.au, davem@davemloft.net, dhowells@redhat.com, mst@redhat.com Cc: arei.gonglei@huawei.com, jasowang@redhat.com, linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, pizhenwei@bytedance.com, helei.sig11@bytedance.com, f4bug@amsat.org, berrange@redhat.com Subject: [PATCH 1/4] crypto: fix the calculation of max_size for ECDSA Date: Fri, 17 Jun 2022 15:07:50 +0800 Message-Id: <20220617070754.73667-2-helei.sig11@bytedance.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20220617070754.73667-1-helei.sig11@bytedance.com> References: <20220617070754.73667-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=ham 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 41068811fd0e..b54d067602cc 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 f754c4d17d6b..b59b15ee087c 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