From nobody Wed Oct 1 22:33:17 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75F451BD035 for ; Fri, 26 Sep 2025 14:20:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896422; cv=none; b=j4o21lypEbLZQA3FsA+024HUfZZqTOQYKfg3nS4qm2ayhsLEsEcctN1lxumJQR2fqljcVLEAstDvMwnuDXSq/HR0m5NsYXMc90ls0WOU33H2bffte3pO7rRCzDjiYiLe5f2q22USKwaoqYEEQGc1fa4X5NCUQkhBvGLx0CzrztA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896422; c=relaxed/simple; bh=GfjEOwIZvP6ZV3GP07VdgHRmLY/8P+pYs2iDKRrn0vA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OKZHCd1eB97gbakUvhsXylEoL4DulpLngsj5DkoR88yHL7miSLiVmjukWiMIn8pTfwkS23FM2fi5Qb87q9SQV2B9/KXBj0fOVozUxionLjmj/wKCyb8XXXPNy+3aqFcejpTSj6xvOynuwtPohNOb8eAVlI6SteR1VumNMMyGAew= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Ju/Obxj2; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Ju/Obxj2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758896419; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=crVe3jLhJ1XzzLdm8GA5F+o0SRGF7gXz4EGryRbWYhc=; b=Ju/Obxj2Cnhk4d48X4eXI2y0cDSSeupVTjMAJaz/BxUhpFB35znzQKF40afKTS9R86UuoU As3g3t1nwld6H+m1eRZXTWjuENvNvbJSweTTjJvXZUmrp0FZ/H95OZyzbDLRwd1Vq+zTJ5 oppi3gidWMq8QMcdG3do0bpQjgdyybA= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-679-IGyjZpYWMIyZcqNFFflK0Q-1; Fri, 26 Sep 2025 10:20:14 -0400 X-MC-Unique: IGyjZpYWMIyZcqNFFflK0Q-1 X-Mimecast-MFC-AGG-ID: IGyjZpYWMIyZcqNFFflK0Q_1758896411 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 22E701955DD8; Fri, 26 Sep 2025 14:20:11 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.155]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 78C1430001B7; Fri, 26 Sep 2025 14:20:07 +0000 (UTC) From: David Howells To: Cc: David Howells , Eric Biggers , "Jason A . Donenfeld" , Ard Biesheuvel , Herbert Xu , Stephan Mueller , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Harald Freudenberger , Holger Dengler , linux-s390@vger.kernel.org Subject: [PATCH v3 1/8] s390/sha3: Rename conflicting functions Date: Fri, 26 Sep 2025 15:19:44 +0100 Message-ID: <20250926141959.1272455-2-dhowells@redhat.com> In-Reply-To: <20250926141959.1272455-1-dhowells@redhat.com> References: <20250926141959.1272455-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 Content-Type: text/plain; charset="utf-8" Rename the s390 sha3_* functions to have an "s390_" prefix to avoid conflict with generic code. Signed-off-by: David Howells cc: Eric Biggers cc: Jason A. Donenfeld cc: Ard Biesheuvel cc: Harald Freudenberger cc: Holger Dengler cc: Herbert Xu cc: Stephan Mueller cc: linux-crypto@vger.kernel.org cc: linux-s390@vger.kernel.org Acked-By: Harald Freudenberger --- arch/s390/crypto/sha3_256_s390.c | 26 +++++++++++++------------- arch/s390/crypto/sha3_512_s390.c | 26 +++++++++++++------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/arch/s390/crypto/sha3_256_s390.c b/arch/s390/crypto/sha3_256_s= 390.c index 03bb4f4bab70..fd5ecae60a57 100644 --- a/arch/s390/crypto/sha3_256_s390.c +++ b/arch/s390/crypto/sha3_256_s390.c @@ -19,7 +19,7 @@ =20 #include "sha.h" =20 -static int sha3_256_init(struct shash_desc *desc) +static int s390_sha3_256_init(struct shash_desc *desc) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); =20 @@ -32,7 +32,7 @@ static int sha3_256_init(struct shash_desc *desc) return 0; } =20 -static int sha3_256_export(struct shash_desc *desc, void *out) +static int s390_sha3_256_export(struct shash_desc *desc, void *out) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); union { @@ -50,7 +50,7 @@ static int sha3_256_export(struct shash_desc *desc, void = *out) return 0; } =20 -static int sha3_256_import(struct shash_desc *desc, const void *in) +static int s390_sha3_256_import(struct shash_desc *desc, const void *in) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); union { @@ -68,22 +68,22 @@ static int sha3_256_import(struct shash_desc *desc, con= st void *in) return 0; } =20 -static int sha3_224_import(struct shash_desc *desc, const void *in) +static int s390_sha3_224_import(struct shash_desc *desc, const void *in) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); =20 - sha3_256_import(desc, in); + s390_sha3_256_import(desc, in); sctx->func =3D CPACF_KIMD_SHA3_224; return 0; } =20 static struct shash_alg sha3_256_alg =3D { .digestsize =3D SHA3_256_DIGEST_SIZE, /* =3D 32 */ - .init =3D sha3_256_init, + .init =3D s390_sha3_256_init, .update =3D s390_sha_update_blocks, .finup =3D s390_sha_finup, - .export =3D sha3_256_export, - .import =3D sha3_256_import, + .export =3D s390_sha3_256_export, + .import =3D s390_sha3_256_import, .descsize =3D S390_SHA_CTX_SIZE, .statesize =3D SHA3_STATE_SIZE, .base =3D { @@ -96,22 +96,22 @@ static struct shash_alg sha3_256_alg =3D { } }; =20 -static int sha3_224_init(struct shash_desc *desc) +static int s390_sha3_224_init(struct shash_desc *desc) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); =20 - sha3_256_init(desc); + s390_sha3_256_init(desc); sctx->func =3D CPACF_KIMD_SHA3_224; return 0; } =20 static struct shash_alg sha3_224_alg =3D { .digestsize =3D SHA3_224_DIGEST_SIZE, - .init =3D sha3_224_init, + .init =3D s390_sha3_224_init, .update =3D s390_sha_update_blocks, .finup =3D s390_sha_finup, - .export =3D sha3_256_export, /* same as for 256 */ - .import =3D sha3_224_import, /* function code different! */ + .export =3D s390_sha3_256_export, /* same as for 256 */ + .import =3D s390_sha3_224_import, /* function code different! */ .descsize =3D S390_SHA_CTX_SIZE, .statesize =3D SHA3_STATE_SIZE, .base =3D { diff --git a/arch/s390/crypto/sha3_512_s390.c b/arch/s390/crypto/sha3_512_s= 390.c index a5c9690eecb1..f4b52a3a0433 100644 --- a/arch/s390/crypto/sha3_512_s390.c +++ b/arch/s390/crypto/sha3_512_s390.c @@ -18,7 +18,7 @@ =20 #include "sha.h" =20 -static int sha3_512_init(struct shash_desc *desc) +static int s390_sha3_512_init(struct shash_desc *desc) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); =20 @@ -31,7 +31,7 @@ static int sha3_512_init(struct shash_desc *desc) return 0; } =20 -static int sha3_512_export(struct shash_desc *desc, void *out) +static int s390_sha3_512_export(struct shash_desc *desc, void *out) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); union { @@ -49,7 +49,7 @@ static int sha3_512_export(struct shash_desc *desc, void = *out) return 0; } =20 -static int sha3_512_import(struct shash_desc *desc, const void *in) +static int s390_sha3_512_import(struct shash_desc *desc, const void *in) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); union { @@ -67,22 +67,22 @@ static int sha3_512_import(struct shash_desc *desc, con= st void *in) return 0; } =20 -static int sha3_384_import(struct shash_desc *desc, const void *in) +static int s390_sha3_384_import(struct shash_desc *desc, const void *in) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); =20 - sha3_512_import(desc, in); + s390_sha3_512_import(desc, in); sctx->func =3D CPACF_KIMD_SHA3_384; return 0; } =20 static struct shash_alg sha3_512_alg =3D { .digestsize =3D SHA3_512_DIGEST_SIZE, - .init =3D sha3_512_init, + .init =3D s390_sha3_512_init, .update =3D s390_sha_update_blocks, .finup =3D s390_sha_finup, - .export =3D sha3_512_export, - .import =3D sha3_512_import, + .export =3D s390_sha3_512_export, + .import =3D s390_sha3_512_import, .descsize =3D S390_SHA_CTX_SIZE, .statesize =3D SHA3_STATE_SIZE, .base =3D { @@ -97,22 +97,22 @@ static struct shash_alg sha3_512_alg =3D { =20 MODULE_ALIAS_CRYPTO("sha3-512"); =20 -static int sha3_384_init(struct shash_desc *desc) +static int s390_sha3_384_init(struct shash_desc *desc) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); =20 - sha3_512_init(desc); + s390_sha3_512_init(desc); sctx->func =3D CPACF_KIMD_SHA3_384; return 0; } =20 static struct shash_alg sha3_384_alg =3D { .digestsize =3D SHA3_384_DIGEST_SIZE, - .init =3D sha3_384_init, + .init =3D s390_sha3_384_init, .update =3D s390_sha_update_blocks, .finup =3D s390_sha_finup, - .export =3D sha3_512_export, /* same as for 512 */ - .import =3D sha3_384_import, /* function code different! */ + .export =3D s390_sha3_512_export, /* same as for 512 */ + .import =3D s390_sha3_384_import, /* function code different! */ .descsize =3D S390_SHA_CTX_SIZE, .statesize =3D SHA3_STATE_SIZE, .base =3D { From nobody Wed Oct 1 22:33:17 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6C40A2FFFAE for ; Fri, 26 Sep 2025 14:20:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896427; cv=none; b=DOa9NwXl6xx6xXgX/htA4lPsL93/CD875c5NzfOXO4EAeRUcr1O/XC/4NF7PiNgjs+R5CT+TAgD4fcEXHw7g/DW5sIbvL8hEahRGFmuLvYLNGi4gHj3EvnT4yaOyOyrRiZae7h4gHAAt56CIsZZpsypia0E41/RnDX5oGmrXS4A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896427; c=relaxed/simple; bh=NZEIOIblbdawTCrxGt/Ero7Fwtqw3BTyIDWtF6I6nvk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AsMAxUqG5IX8XtumUUmzNi45JyvkstgBUMysgmlgMeKjePMylKnYJruI0YdU3ERW5sx/LWrjdSVfGNQnJB43DqrWemiObF2zB0gBLsqHzPJZ+GcMXQ1PSQiw/HwQcHakI1aLUscsqH9qL7U5OvbAzKW5TsrYEJ9GsqHLkeIZmrs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=NGS061Qx; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="NGS061Qx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758896424; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gS6I9+pn+T6EshQ8kERlfqfUoiq0QQuAAxssnEC3ucQ=; b=NGS061QxKya04skSUOhBTyZVbdqfCPGUsyQLQLIYVKc+9/jgK5+ew4V3kBUmNeKzStEzvM VDG0CNTTeg0P6fuMTQSTa3ITRQ+x6Kqg3qzBZ1eIuQDSsmHOGLwtNZeo31SdfVlMdiYHwS nuvf4QSwrNs97TA8domLfkEto/XraF0= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-25-WqYyI61VP8-lq6wwfy1Pag-1; Fri, 26 Sep 2025 10:20:18 -0400 X-MC-Unique: WqYyI61VP8-lq6wwfy1Pag-1 X-Mimecast-MFC-AGG-ID: WqYyI61VP8-lq6wwfy1Pag_1758896416 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 301F51800586; Fri, 26 Sep 2025 14:20:16 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.155]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B0E3F195419F; Fri, 26 Sep 2025 14:20:12 +0000 (UTC) From: David Howells To: Cc: David Howells , Eric Biggers , "Jason A . Donenfeld" , Ard Biesheuvel , Herbert Xu , Stephan Mueller , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org, Catalin Marinas , Will Deacon , linux-arm-kernel@lists.infradead.org Subject: [PATCH v3 2/8] arm64/sha3: Rename conflicting functions Date: Fri, 26 Sep 2025 15:19:45 +0100 Message-ID: <20250926141959.1272455-3-dhowells@redhat.com> In-Reply-To: <20250926141959.1272455-1-dhowells@redhat.com> References: <20250926141959.1272455-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 Content-Type: text/plain; charset="utf-8" Rename the arm64 sha3_* functions to have an "arm64_" prefix to avoid conflict with generic code. Signed-off-by: David Howells cc: Eric Biggers cc: Jason A. Donenfeld cc: Ard Biesheuvel cc: Catalin Marinas cc: Will Deacon cc: Herbert Xu cc: Stephan Mueller cc: linux-crypto@vger.kernel.org cc: linux-arm-kernel@lists.infradead.org --- arch/arm64/crypto/sha3-ce-glue.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/arm64/crypto/sha3-ce-glue.c b/arch/arm64/crypto/sha3-ce-g= lue.c index b4f1001046c9..426d8044535a 100644 --- a/arch/arm64/crypto/sha3-ce-glue.c +++ b/arch/arm64/crypto/sha3-ce-glue.c @@ -31,7 +31,7 @@ MODULE_ALIAS_CRYPTO("sha3-512"); asmlinkage int sha3_ce_transform(u64 *st, const u8 *data, int blocks, int md_len); =20 -static int sha3_update(struct shash_desc *desc, const u8 *data, +static int arm64_sha3_update(struct shash_desc *desc, const u8 *data, unsigned int len) { struct sha3_state *sctx =3D shash_desc_ctx(desc); @@ -55,8 +55,8 @@ static int sha3_update(struct shash_desc *desc, const u8 = *data, return len; } =20 -static int sha3_finup(struct shash_desc *desc, const u8 *src, unsigned int= len, - u8 *out) +static int arm64_sha3_finup(struct shash_desc *desc, const u8 *src, unsign= ed int len, + u8 *out) { struct sha3_state *sctx =3D shash_desc_ctx(desc); struct crypto_shash *tfm =3D desc->tfm; @@ -90,8 +90,8 @@ static int sha3_finup(struct shash_desc *desc, const u8 *= src, unsigned int len, static struct shash_alg algs[] =3D { { .digestsize =3D SHA3_224_DIGEST_SIZE, .init =3D crypto_sha3_init, - .update =3D sha3_update, - .finup =3D sha3_finup, + .update =3D arm64_sha3_update, + .finup =3D arm64_sha3_finup, .descsize =3D SHA3_STATE_SIZE, .base.cra_name =3D "sha3-224", .base.cra_driver_name =3D "sha3-224-ce", @@ -102,8 +102,8 @@ static struct shash_alg algs[] =3D { { }, { .digestsize =3D SHA3_256_DIGEST_SIZE, .init =3D crypto_sha3_init, - .update =3D sha3_update, - .finup =3D sha3_finup, + .update =3D arm64_sha3_update, + .finup =3D arm64_sha3_finup, .descsize =3D SHA3_STATE_SIZE, .base.cra_name =3D "sha3-256", .base.cra_driver_name =3D "sha3-256-ce", @@ -114,8 +114,8 @@ static struct shash_alg algs[] =3D { { }, { .digestsize =3D SHA3_384_DIGEST_SIZE, .init =3D crypto_sha3_init, - .update =3D sha3_update, - .finup =3D sha3_finup, + .update =3D arm64_sha3_update, + .finup =3D arm64_sha3_finup, .descsize =3D SHA3_STATE_SIZE, .base.cra_name =3D "sha3-384", .base.cra_driver_name =3D "sha3-384-ce", @@ -126,8 +126,8 @@ static struct shash_alg algs[] =3D { { }, { .digestsize =3D SHA3_512_DIGEST_SIZE, .init =3D crypto_sha3_init, - .update =3D sha3_update, - .finup =3D sha3_finup, + .update =3D arm64_sha3_update, + .finup =3D arm64_sha3_finup, .descsize =3D SHA3_STATE_SIZE, .base.cra_name =3D "sha3-512", .base.cra_driver_name =3D "sha3-512-ce", From nobody Wed Oct 1 22:33:17 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D74882EF65E for ; Fri, 26 Sep 2025 14:20:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896431; cv=none; b=KPL+hJeSpbqLwfBJVPvKvvdYf5/GMXP/AyDf7HpUtY78HifqO1loF+taWyMxg0FjQRdqqOF9Zw7Ex3z+JY36ATSNbmL+eaL6Alr0U3FC+yOJ5qqTgZOYfNBCVvYoDE+rF9Rc/fPVsrTddBe+P+ipb9tcpxGW0xdnwoFUPNJA1n4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896431; c=relaxed/simple; bh=Lm6nWZoTQ7iqE93/aJpx4zkzO9/hh1+RfCz+ZWG9Ehw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=WnktTr4aUXAsP98hnXSB6IA4g3/kMBltusP+2Z0PCM0GTkHPY58ePbQYircpGR0WIfhWFelJTeJT7rqdGsJFKRgw6go6DMaA/tOFKi6oRwYRaXcSX+kOzfxiSL5yEgQZpRSK2VG8McrxMA3ie9bbx4JNzPH40Yp2VPA76AwCLUQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=MxoqZBQy; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="MxoqZBQy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758896426; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8rSF2PuTI9w1l7AuXkE52T145cvAzmymSgnlso9hU8c=; b=MxoqZBQyL4lxfmOgIT0EClEzYxluIOaXJfvmUqtdO6OQ0u+d+8qYqsscZCKp+ze6lWgPI4 /6c2esEP6x7BKNDlsE/leXok2DK7xnHfXA2PzBce1lpGdBcHrkzRT+cfhh2VLkcYFbosj5 PiFpEGNvLqw+mhn0r9cSt00JV8dQfS0= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-471-44QyxI71MmqZTZ0wYvYolA-1; Fri, 26 Sep 2025 10:20:23 -0400 X-MC-Unique: 44QyxI71MmqZTZ0wYvYolA-1 X-Mimecast-MFC-AGG-ID: 44QyxI71MmqZTZ0wYvYolA_1758896420 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C08F819774D6; Fri, 26 Sep 2025 14:20:20 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.155]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9ED6119560AB; Fri, 26 Sep 2025 14:20:17 +0000 (UTC) From: David Howells To: Cc: David Howells , Eric Biggers , "Jason A . Donenfeld" , Ard Biesheuvel , Herbert Xu , Stephan Mueller , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 3/8] lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128, SHAKE256 Date: Fri, 26 Sep 2025 15:19:46 +0100 Message-ID: <20250926141959.1272455-4-dhowells@redhat.com> In-Reply-To: <20250926141959.1272455-1-dhowells@redhat.com> References: <20250926141959.1272455-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Add SHA3, providing SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128 and SHAKE256 to lib/crypto. Also add kunit tests for each of these. gen-hash-testvecs.py is also modified to be able to generate SHAKE hashes because Python's hashlib requires the output digest size supplying for those two algorithms as they produce arbitrary length digests. Notes: (1) I've left hooks in sha3.c for asm-optimised variants, but as I don't entirely know what those might look like, not having implemented any, the hooks' usability is uncertain. (2) The SHAKE algorithms will be required for ML-DSA. Signed-off-by: David Howells cc: Eric Biggers cc: Jason A. Donenfeld cc: Ard Biesheuvel cc: Herbert Xu cc: Stephan Mueller cc: linux-crypto@vger.kernel.org Changes =3D=3D=3D=3D=3D=3D=3D v3) - Split the s390 function rename out to a separate patch. v2) - Simplify things by keeping the state array in LE form and byteswapping all the 64-bit words before and after applying the keccak function on a BE system. This means no byteswapping is required when XOR'ing data into the state array or when extracting the digest. Further, this is a no-op on LE systems. - Rename sha3_final() to sha3_squeeze() and don't clear the context at the end as it's permitted to continue calling sha3_final() to extract continuations of the digest (needed by ML-DSA). - Don't reapply the end marker to the hash state in continuation sha3_squeeze() unless sha3_update() gets called again (needed by ML-DSA). - Give sha3_squeeze() the amount of digest to produce as a parameter rather than using ctx->digest_size and don't return the amount digested. - Reimplement sha3_final() as a wrapper around sha3_squeeze() that extracts ctx->digest_size amount of digest and then zeroes out the context. The latter is necessary to avoid upsetting hash-test-template.h. - Provide a sha3_reinit() function to clear the state, but to leave the parameters that indicate the hash properties unaffected, allowing for reuse. - Provide a sha3_set_digestsize() function to change the size of the digest to be extracted by sha3_final(). sha3_squeeze() takes a parameter for this instead. - Don't pass the digest size as a parameter to shake128/256_init() but rather default to 128/256 bits as per the function name. - Provide a sha3_clear() function to zero out the context. --- Documentation/crypto/index.rst | 1 + Documentation/crypto/sha3.rst | 245 +++++++++++++++ include/crypto/sha3.h | 467 ++++++++++++++++++++++++++++- lib/crypto/Kconfig | 7 + lib/crypto/Makefile | 6 + lib/crypto/sha3.c | 529 +++++++++++++++++++++++++++++++++ 6 files changed, 1254 insertions(+), 1 deletion(-) create mode 100644 Documentation/crypto/sha3.rst create mode 100644 lib/crypto/sha3.c diff --git a/Documentation/crypto/index.rst b/Documentation/crypto/index.rst index 100b47d049c0..4ee667c446f9 100644 --- a/Documentation/crypto/index.rst +++ b/Documentation/crypto/index.rst @@ -27,3 +27,4 @@ for cryptographic use cases, as well as programming examp= les. descore-readme device_drivers/index krb5 + sha3 diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst new file mode 100644 index 000000000000..ae4902895882 --- /dev/null +++ b/Documentation/crypto/sha3.rst @@ -0,0 +1,245 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D +SHA-3 Algorithm collection +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D + +.. Contents: + + - Overview + - Basic API + - Extendable-Output Functions + - Convenience API + - Internal API + - Testing + - References + - API Function Reference + + +Overview +=3D=3D=3D=3D=3D=3D=3D=3D + +The SHA-3 algorithm base, as specified in NIST FIPS-202[1], provides a num= ber +of specific algorithms all based on the same engine (Keccak). The differe= nces +between them are: the block size (how much of the common state buffer gets +updated with new data between invocations of the Keccak mixing function), = what +termination markers get mixed in upon finalisation and how much data is +extracted at the end. The Keccak engine is designed such that arbitrary +amounts of output can be obtained for certain algorithms. + +Four standard digest algorithms are provided: + + - SHA3-224 + - SHA3-256 + - SHA3-384 + - SHA3-512 + +and two Extendable-Output Functions (XOF): + + - SHAKE128 + - SHAKE256 + +Caution: The algorithm(s) may be accelerated with optimised assembly and, = as +such, may have to sync with or modify the FPU or CPU Vector Unit state. H= ow +this is done is arch specific and might involve waiting or locking. + +If selectable algorithms are required then the crypto_hash API must be used +instead as this binds each algorithm to a specific C type. + + +Basic API +=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The basic API has a separate context struct for each algorithm in the SHA3 +suite, none of the contents of which are expected to be accessed directly:: + + struct sha3_224_ctx { ... }; + struct sha3_256_ctx { ... }; + struct sha3_384_ctx { ... }; + struct sha3_512_ctx { ... }; + struct shake128_ctx { ... }; + struct shake256_ctx { ... }; + +Note that these are relatively large structures, so may not be suitable for +placing on the stack. + +There are a collection of initialisation functions, one for each algorithm +supported, that initialise the context appropriately for that algorithm:: + + void sha3_224_init(struct sha3_224_ctx *ctx); + void sha3_256_init(struct sha3_256_ctx *ctx); + void sha3_384_init(struct sha3_384_ctx *ctx); + void sha3_512_init(struct sha3_512_ctx *ctx); + void shake128_init(struct shake128_ctx *ctx); + void shake256_init(struct shake256_ctx *ctx); + +Data is then added with the appropriate update function, again one per +algorithm:: + + void sha3_224_update(struct sha3_224_ctx *ctx, + const u8 *data, unsigned int len); + void sha3_256_update(struct sha3_256_ctx *ctx, + const u8 *data, unsigned int len); + void sha3_384_update(struct sha3_384_ctx *ctx, + const u8 *data, unsigned int len); + void sha3_512_update(struct sha3_512_ctx *ctx, + const u8 *data, unsigned int len); + void shake128_update(struct shake128_ctx *ctx, + const u8 *data, unsigned int len); + void shake256_update(struct shake256_ctx *ctx, + const u8 *data, unsigned int len); + +The update function may be called multiple times if need be to add +non-contiguous data. + +For digest algorithms, the digest is finalised and extracted with the +algorithm-specific function:: + + unsigned int sha3_224_final(struct sha3_224_ctx *ctx, + u8 out[SHA3_224_DIGEST_SIZE]); + unsigned int sha3_256_final(struct sha3_256_ctx *ctx, + u8 out[SHA3_256_DIGEST_SIZE]); + unsigned int sha3_384_final(struct sha3_384_ctx *ctx, + u8 out[SHA3_384_DIGEST_SIZE]); + unsigned int sha3_512_final(struct sha3_512_ctx *ctx, + u8 out[SHA3_512_DIGEST_SIZE]); + +which also explicitly clears the context. The amount of data extracted is +determined by the type. + + +Extendable-Output Functions +--------------------------- + +For XOFs, once the data has been added to a context, a variable amount of = data +may be extracted. This can be done by calling the appropriate squeeze +function:: + + void shake128_squeeze(struct shake128_ctx *ctx, u8 *out, size_t out_len); + void shake256_squeeze(struct shake256_ctx *ctx, u8 *out, size_t out_len); + +and telling it how much data should be extracted. The squeeze function ma= y be +called multiple times but it will only finalise the context on the first +invocation. + +Note that performing a number of squeezes, with the output laid consequiti= vely +in a buffer, gets exactly the same output as doing a single squeeze for the +combined amount over the same buffer. + +Once all the desired output has been extracted, the context should be clea= red +with the clear function appropriate to the algorithm:: + + void shake128_clear(struct shake128_ctx *ctx); + void shake256_clear(struct shake256_ctx *ctx); + + +Convenience API +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +It only a single contiguous buffer of input needs to be added and only a s= ingle +buffer of digest or XOF output is required, then a convenience API is prov= ided +that wraps all the required steps into a single function. There is one +function for each algorithm supported:: + + void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE]); + void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE]); + void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE]); + void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE]); + void shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len); + void shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len); + + +Internal API +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +There is a common internal API underlying all of this that may be used to = build +further algorithms or APIs as the engine in the same in all cases. The +algorithm APIs all wrap the common context structure:: + + struct sha3_ctx { + struct sha3_state state; + u8 block_size; + u8 padding; + u8 absorb_offset; + u8 squeeze_offset; + bool end_marked; + }; + + struct sha3_state { + u64 st[SHA3_STATE_SIZE / 8]; + }; + +The fields are as follows: + + * ``state.st`` + + An array of 25 64-bit state buckets that are used to hold the mathemati= cal + state of the Keccak engine. Data is XOR'd onto part of this, the engin= e is + cranked and then the output is copied from this. + + For the convenience of adding input and extract output from it, the arr= ay is + kept in little-endian order most of the time, but is byteswapped to + host-endian in order to perform the Keccak function and then byteswapped + back again. On an LE machine, the byteswapping is a no-op. + + * ``block_size`` + + The size of the block of state that can be updated or extracted at a ti= me. + This is related to the algorithm size. + + * ``padding`` + + The terminating byte to add when finalising the stat. This may differ + between algorithms. + + * ``absorb_offset`` + + This tracks which is the next byte of state to be updated; when it hits + ``block_size``, the engine is cranked and this is reset to 0. + + * ``squeeze_offset`` + + This tracks which is the next byte of state to be extracted; similar to + ``partial``, when it hits ``block_size``, if more output is requested, = the + engine is cranked to generate more and this is reset to 0. + + * ``end_marked`` + + This is set to true when the end marker has been added into the state to + prevent multiple squeezings from XOF algorithms from re-terminating the + state. + +Note that the size of the digest is *not* included in here as that's only = needed +at finalisation/squeezing time and can be supplied then. + +To make use of the context, the following internal functions are provided:: + + void sha3_update(struct sha3_ctx *ctx, const u8 *data, unsigned int len); + void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_len); + void sha3_clear(struct sha3_ctx *ctx); + +These allow data to be added (absorbed) into the state, output to be extra= cted +(squeezed) from the state and the the state be cleared. Note that there i= s no +"final" function, per se, but that can be constructed by squeezing and +clearing. + + +Testing +------- + +The sha3 module does a basic sanity test on initialisation, but there is a= lso a +kunit test module available. + + +References +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +[1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf + + + +API Function Reference +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +.. kernel-doc:: crypto/lib/sha3.c +.. kernel-doc:: include/crypto/sha3.c diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h index 41e1b83a6d91..41bc211afa0b 100644 --- a/include/crypto/sha3.h +++ b/include/crypto/sha3.h @@ -1,11 +1,14 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Common values for SHA-3 algorithms + * + * See also Documentation/crypto/sha3.rst */ #ifndef __CRYPTO_SHA3_H__ #define __CRYPTO_SHA3_H__ =20 #include +#include =20 #define SHA3_224_DIGEST_SIZE (224 / 8) #define SHA3_224_BLOCK_SIZE (200 - 2 * SHA3_224_DIGEST_SIZE) @@ -23,6 +26,14 @@ #define SHA3_512_BLOCK_SIZE (200 - 2 * SHA3_512_DIGEST_SIZE) #define SHA3_512_EXPORT_SIZE SHA3_STATE_SIZE + SHA3_512_BLOCK_SIZE + 1 =20 +/* SHAKE128 and SHAKE256 actually have variable output size, but this + * is needed for the kunit tests. + */ +#define SHAKE128_DEFAULT_SIZE (128 / 8) +#define SHAKE128_BLOCK_SIZE (200 - 2 * SHAKE128_DEFAULT_SIZE) +#define SHAKE256_DEFAULT_SIZE (256 / 8) +#define SHAKE256_BLOCK_SIZE (200 - 2 * SHAKE256_DEFAULT_SIZE) + #define SHA3_STATE_SIZE 200 =20 struct shash_desc; @@ -31,6 +42,460 @@ struct sha3_state { u64 st[SHA3_STATE_SIZE / 8]; }; =20 +/* + * The SHA3 context structure and state buffer. + * + * To avoid the need to byteswap when adding input and extracting output f= rom + * the state array, the state array is kept in little-endian order most of= the + * time, but is byteswapped to host-endian in order to perform the Keccak + * function and then byteswapped back again after. On a LE machine, the + * byteswap step is a no-op. + */ +struct sha3_ctx { + struct sha3_state state; + u8 block_size; /* Block size in bytes */ + u8 padding; /* Padding byte */ + u8 absorb_offset; /* Next state byte to absorb into */ + u8 squeeze_offset; /* Next state byte to extract */ + bool end_marked; /* T if end marker inserted */ +}; + int crypto_sha3_init(struct shash_desc *desc); =20 -#endif +/** + * sha3_clear() - Explicitly clear the entire context + * @ctx: the context to clear + * + * Explicitly clear the entire context, including the type parameters; aft= er + * this, the context must be fully initialised again. + * + * Return: None. + * + * Context: Any context. + */ +static inline void sha3_clear(struct sha3_ctx *ctx) +{ + memzero_explicit(ctx, sizeof(*ctx)); +} + +void sha3_update(struct sha3_ctx *ctx, const u8 *data, unsigned int len); +void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_len); + +/* + * Context wrapper for SHA3-224. + */ +struct sha3_224_ctx { + struct sha3_ctx ctx; +}; + +/** + * sha3_224_init() - Set a SHA3 context for SHA3-224 + * @ctx: the context to initialise + * + * Initialise a SHA3 context for the production of a SHA3-224 digest of a + * message. + * + * Return: None. + * + * Context: Any context. + */ +static inline void sha3_224_init(struct sha3_224_ctx *ctx) +{ + *ctx =3D (struct sha3_224_ctx){ + .ctx.block_size =3D SHA3_224_BLOCK_SIZE, + .ctx.padding =3D 0x06, + }; +} + +/** + * sha3_224_update() - Update a SHA3-224 hash with message data + * @ctx: the context to update; must have been initialized + * @data: the message data + * @len: the data length in bytes + * + * This can be called any number of times to add data to the hash, perform= ing + * the "keccak sponge absorbing" phase. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void sha3_224_update(struct sha3_224_ctx *ctx, const u8 *dat= a, unsigned int len) +{ + return sha3_update(&ctx->ctx, data, len); +} + +/** + * sha3_224_final() - Finalise a SHA3-224 hash and extract the digest + * @ctx: The context to finalise; must have been initialised + * @out: Where to write the resulting message digest + * + * Finish the computation of a SHA3-224 hash and perform the "Keccak sponge + * squeezing" phase. The digest is written to @out buffer and the context= will + * be completely zeroed out. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void sha3_224_final(struct sha3_224_ctx *ctx, u8 out[SHA3_22= 4_DIGEST_SIZE]) +{ + sha3_squeeze(&ctx->ctx, out, SHA3_224_DIGEST_SIZE); + sha3_clear(&ctx->ctx); +} + +/* + * Context wrapper for SHA3-256. + */ +struct sha3_256_ctx { + struct sha3_ctx ctx; +}; + +/** + * sha3_256_init() - Set a SHA3 context for SHA3-256 + * @ctx: the context to initialise + * + * Initialise a SHA3 context for the production of a SHA3-256 digest of a + * message. + * + * Return: None. + * + * Context: Any context. + */ +static inline void sha3_256_init(struct sha3_256_ctx *ctx) +{ + *ctx =3D (struct sha3_256_ctx){ + .ctx.block_size =3D SHA3_256_BLOCK_SIZE, + .ctx.padding =3D 0x06, + }; +} + +/** + * sha3_256_update() - Update a SHA3-256 hash with message data + * @ctx: the context to update; must have been initialized + * @data: the message data + * @len: the data length in bytes + * + * This can be called any number of times to add data to the hash, perform= ing + * the "keccak sponge absorbing" phase. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void sha3_256_update(struct sha3_256_ctx *ctx, const u8 *dat= a, unsigned int len) +{ + return sha3_update(&ctx->ctx, data, len); +} + +/** + * sha3_256_final() - Finalise a SHA3-256 hash and extract the digest + * @ctx: The context to finalise; must have been initialised + * @out: Where to write the resulting message digest + * + * Finish the computation of a SHA3-256 hash and perform the "Keccak sponge + * squeezing" phase. The digest is written to @out buffer and the context= will + * be completely zeroed out. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void sha3_256_final(struct sha3_256_ctx *ctx, u8 out[SHA3_25= 6_DIGEST_SIZE]) +{ + sha3_squeeze(&ctx->ctx, out, SHA3_256_DIGEST_SIZE); + sha3_clear(&ctx->ctx); +} + +/* + * Context wrapper for SHA3-384. + */ +struct sha3_384_ctx { + struct sha3_ctx ctx; +}; + +/** + * sha3_384_init() - Set a SHA3 context for SHA3-384 + * @ctx: the context to initialise + * + * Initialise a SHA3 context for the production of a SHA3-384 digest of a + * message. + * + * Return: None. + * + * Context: Any context. + */ +static inline void sha3_384_init(struct sha3_384_ctx *ctx) +{ + *ctx =3D (struct sha3_384_ctx){ + .ctx.block_size =3D SHA3_384_BLOCK_SIZE, + .ctx.padding =3D 0x06, + }; +} + +/** + * sha3_384_update() - Update a SHA3-384 hash with message data + * @ctx: the context to update; must have been initialized + * @data: the message data + * @len: the data length in bytes + * + * This can be called any number of times to add data to the hash, perform= ing + * the "keccak sponge absorbing" phase. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void sha3_384_update(struct sha3_384_ctx *ctx, const u8 *dat= a, unsigned int len) +{ + return sha3_update(&ctx->ctx, data, len); +} + +/** + * sha3_384_final() - Finalise a SHA3-384 hash and extract the digest + * @ctx: The context to finalise; must have been initialised + * @out: Where to write the resulting message digest + * + * Finish the computation of a SHA3-384 hash and perform the "Keccak sponge + * squeezing" phase. The digest is written to @out buffer and the context= will + * be completely zeroed out. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void sha3_384_final(struct sha3_384_ctx *ctx, u8 out[SHA3_38= 4_DIGEST_SIZE]) +{ + sha3_squeeze(&ctx->ctx, out, SHA3_384_DIGEST_SIZE); + sha3_clear(&ctx->ctx); +} + +/* + * Context wrapper for SHA3-512. + */ +struct sha3_512_ctx { + struct sha3_ctx ctx; +}; + +/** + * sha3_512_init() - Set a SHA3 context for SHA3-512 + * @ctx: the context to initialise + * + * Initialise a SHA3 context for the production of a SHA3-512 digest of a + * message. + * + * Return: None. + * + * Context: Any context. + */ +static inline void sha3_512_init(struct sha3_512_ctx *ctx) +{ + *ctx =3D (struct sha3_512_ctx){ + .ctx.block_size =3D SHA3_512_BLOCK_SIZE, + .ctx.padding =3D 0x06, + }; +} + +/** + * sha3_512_update() - Update a SHA3-512 hash with message data + * @ctx: the context to update; must have been initialized + * @data: the message data + * @len: the data length in bytes + * + * This can be called any number of times to add data to the hash, perform= ing + * the "keccak sponge absorbing" phase. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void sha3_512_update(struct sha3_512_ctx *ctx, const u8 *dat= a, unsigned int len) +{ + return sha3_update(&ctx->ctx, data, len); +} + +/** + * sha3_512_final() - Finalise a SHA3-512 hash and extract the digest + * @ctx: The context to finalise; must have been initialised + * @out: Where to write the resulting message digest + * + * Finish the computation of a SHA3-512 hash and perform the "Keccak sponge + * squeezing" phase. The digest is written to @out buffer and the context= will + * be completely zeroed out. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void sha3_512_final(struct sha3_512_ctx *ctx, u8 out[SHA3_51= 2_DIGEST_SIZE]) +{ + sha3_squeeze(&ctx->ctx, out, SHA3_512_DIGEST_SIZE); + sha3_clear(&ctx->ctx); +} + +/* + * Context wrapper for SHAKE128. + */ +struct shake128_ctx { + struct sha3_ctx ctx; +}; + +/** + * shake128_init() - Set a SHA3 context for SHAKE128 + * @ctx: The context to initialise + * + * Initialise a SHA3 context for the production of SHAKE128 output generat= ion + * from a message. The sha3_squeeze() function can be used to extract an + * arbitrary amount of data from the context. + * + * Context: Any context. + */ +static inline void shake128_init(struct shake128_ctx *ctx) +{ + *ctx =3D (struct shake128_ctx){ + .ctx.block_size =3D SHAKE128_BLOCK_SIZE, + .ctx.padding =3D 0x1f, + }; +} + +/** + * shake128_update() - Update a SHAKE128 hash with message data + * @ctx: the context to update; must have been initialized + * @data: the message data + * @len: the data length in bytes + * + * This can be called any number of times to add data to the XOF state, + * performing the "keccak sponge absorbing" phase. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void shake128_update(struct shake128_ctx *ctx, const u8 *dat= a, unsigned int len) +{ + return sha3_update(&ctx->ctx, data, len); +} + +/** + * shake128_squeeze() - Finalize a SHAKE128 digest of any type and extract= the digest + * @ctx: the context to finalize; must have been initialized + * @out: Where to write the resulting message digest + * @out_size: The amount of digest to extract to @out in bytes + * + * Finish the computation of a SHAKE128 XOF and perform the "Keccak sponge + * squeezing" phase. @out_size amount of digest is written to @out buffer. + * + * This may be called multiple times to extract continuations of the diges= t. + * Note that, a number of consecutive squeezes laid end-to-end will yield = the + * same output as one big squeeze generating the same total amount of outp= ut. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void shake128_squeeze(struct shake128_ctx *ctx, u8 *out, siz= e_t out_size) +{ + return sha3_squeeze(&ctx->ctx, out, out_size); +} + +/** + * shake128_clear() - Explicitly clear the entire SHAKE128 context + * @ctx: the context to clear + * + * Explicitly clear the entire context; after this, the context must be + * initialised again. + * + * Return: None. + * + * Context: Any context. + */ +static inline void shake128_clear(struct shake128_ctx *ctx) +{ + sha3_clear(&ctx->ctx); +} + +/* + * Context wrapper for SHAKE256. + */ +struct shake256_ctx { + struct sha3_ctx ctx; +}; + +/** + * shake256_init() - Set a SHA3 context for SHAKE256 + * @ctx: The context to initialise + * + * Initialise a SHA3 context for the production of SHAKE256 output generat= ion + * from a message. The sha3_squeeze() function can be used to extract an + * arbitrary amount of data from the context. + * + * Context: Any context. + */ +static inline void shake256_init(struct shake256_ctx *ctx) +{ + *ctx =3D (struct shake256_ctx){ + .ctx.block_size =3D SHAKE256_BLOCK_SIZE, + .ctx.padding =3D 0x1f, + }; +} + +/** + * shake256_update() - Update a SHAKE256 hash with message data + * @ctx: the context to update; must have been initialized + * @data: the message data + * @len: the data length in bytes + * + * This can be called any number of times to add data to the XOF state, + * performing the "keccak sponge absorbing" phase. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void shake256_update(struct shake256_ctx *ctx, const u8 *dat= a, unsigned int len) +{ + return sha3_update(&ctx->ctx, data, len); +} + +/** + * shake256_squeeze() - Finalize a SHAKE256 digest of any type and extract= the digest + * @ctx: the context to finalize; must have been initialized + * @out: Where to write the resulting message digest + * @out_size: The amount of digest to extract to @out in bytes + * + * Finish the computation of a SHAKE256 XOF and perform the "Keccak sponge + * squeezing" phase. @out_size amount of digest is written to @out buffer. + * + * This may be called multiple times to extract continuations of the diges= t. + * Note that, a number of consecutive squeezes laid end-to-end will yield = the + * same output as one big squeeze generating the same total amount of outp= ut. + * + * Context: May use the FPU/Vector unit registers. + */ +static inline void shake256_squeeze(struct shake256_ctx *ctx, u8 *out, siz= e_t out_size) +{ + return sha3_squeeze(&ctx->ctx, out, out_size); +} + +/** + * shake256_clear() - Explicitly clear the entire SHAKE256 context + * @ctx: the context to clear + * + * Explicitly clear the entire context; after this, the context must be + * initialised again. + * + * Return: None. + * + * Context: Any context. + */ +static inline void shake256_clear(struct shake256_ctx *ctx) +{ + sha3_clear(&ctx->ctx); +} + +void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE]); +void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE]); +void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE]); +void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE]); +void shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len); +void shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len); + +#endif /* __CRYPTO_SHA3_H__ */ diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index eea17e36a22b..1caf3fbe24bf 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -184,6 +184,13 @@ config CRYPTO_LIB_SHA512_ARCH default y if SPARC64 default y if X86_64 =20 +config CRYPTO_LIB_SHA3 + tristate + help + The SHA3 library functions. + Select this if your module uses any of these functions from + . + config CRYPTO_LIB_SM3 tristate =20 diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index bded351aeace..b7fa51bfeebb 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -268,6 +268,12 @@ endif # CONFIG_CRYPTO_LIB_SHA512_ARCH =20 ##########################################################################= ###### =20 +#obj-$(CONFIG_CRYPTO_LIB_SHA3) +=3D libsha3.o +#libsha3-y :=3D sha3.o +obj-$(CONFIG_CRYPTO_SHA3) +=3D sha3.o + +##########################################################################= ###### + obj-$(CONFIG_MPILIB) +=3D mpi/ =20 obj-$(CONFIG_CRYPTO_SELFTESTS_FULL) +=3D simd.o diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c new file mode 100644 index 000000000000..a8eaa25a837f --- /dev/null +++ b/lib/crypto/sha3.c @@ -0,0 +1,529 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Cryptographic API. + * + * SHA-3, as specified in + * https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf + * + * SHA-3 code by Jeff Garzik + * Ard Biesheuvel + * David Howells + * + * See also Documentation/crypto/sha3.rst + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include +#include +#include +#include + +/* + * On some 32-bit architectures, such as h8300, GCC ends up using over 1 K= B of + * stack if the round calculation gets inlined into the loop in + * sha3_keccakf_rounds_generic(). On the other hand, on 64-bit architectu= res + * with plenty of [64-bit wide] general purpose registers, not inlining it + * severely hurts performance. So let's use 64-bitness as a heuristic to + * decide whether to inline or not. + */ +#ifdef CONFIG_64BIT +#define SHA3_INLINE inline +#else +#define SHA3_INLINE noinline +#endif + +#define SHA3_KECCAK_ROUNDS 24 + +static const u64 sha3_keccakf_rndc[24] =3D { + 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, + 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, + 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, + 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, + 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, + 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, + 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, + 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL +}; + +/* + * Perform a single round of Keccak mixing. + */ +static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *= state) +{ + u64 *st =3D state->st; + u64 t[5], tt, bc[5]; + + /* Theta */ + bc[0] =3D st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20]; + bc[1] =3D st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21]; + bc[2] =3D st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22]; + bc[3] =3D st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23]; + bc[4] =3D st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24]; + + t[0] =3D bc[4] ^ rol64(bc[1], 1); + t[1] =3D bc[0] ^ rol64(bc[2], 1); + t[2] =3D bc[1] ^ rol64(bc[3], 1); + t[3] =3D bc[2] ^ rol64(bc[4], 1); + t[4] =3D bc[3] ^ rol64(bc[0], 1); + + st[0] ^=3D t[0]; + + /* Rho Pi */ + tt =3D st[1]; + st[ 1] =3D rol64(st[ 6] ^ t[1], 44); + st[ 6] =3D rol64(st[ 9] ^ t[4], 20); + st[ 9] =3D rol64(st[22] ^ t[2], 61); + st[22] =3D rol64(st[14] ^ t[4], 39); + st[14] =3D rol64(st[20] ^ t[0], 18); + st[20] =3D rol64(st[ 2] ^ t[2], 62); + st[ 2] =3D rol64(st[12] ^ t[2], 43); + st[12] =3D rol64(st[13] ^ t[3], 25); + st[13] =3D rol64(st[19] ^ t[4], 8); + st[19] =3D rol64(st[23] ^ t[3], 56); + st[23] =3D rol64(st[15] ^ t[0], 41); + st[15] =3D rol64(st[ 4] ^ t[4], 27); + st[ 4] =3D rol64(st[24] ^ t[4], 14); + st[24] =3D rol64(st[21] ^ t[1], 2); + st[21] =3D rol64(st[ 8] ^ t[3], 55); + st[ 8] =3D rol64(st[16] ^ t[1], 45); + st[16] =3D rol64(st[ 5] ^ t[0], 36); + st[ 5] =3D rol64(st[ 3] ^ t[3], 28); + st[ 3] =3D rol64(st[18] ^ t[3], 21); + st[18] =3D rol64(st[17] ^ t[2], 15); + st[17] =3D rol64(st[11] ^ t[1], 10); + st[11] =3D rol64(st[ 7] ^ t[2], 6); + st[ 7] =3D rol64(st[10] ^ t[0], 3); + st[10] =3D rol64( tt ^ t[1], 1); + + /* Chi */ + bc[ 0] =3D ~st[ 1] & st[ 2]; + bc[ 1] =3D ~st[ 2] & st[ 3]; + bc[ 2] =3D ~st[ 3] & st[ 4]; + bc[ 3] =3D ~st[ 4] & st[ 0]; + bc[ 4] =3D ~st[ 0] & st[ 1]; + st[ 0] ^=3D bc[ 0]; + st[ 1] ^=3D bc[ 1]; + st[ 2] ^=3D bc[ 2]; + st[ 3] ^=3D bc[ 3]; + st[ 4] ^=3D bc[ 4]; + + bc[ 0] =3D ~st[ 6] & st[ 7]; + bc[ 1] =3D ~st[ 7] & st[ 8]; + bc[ 2] =3D ~st[ 8] & st[ 9]; + bc[ 3] =3D ~st[ 9] & st[ 5]; + bc[ 4] =3D ~st[ 5] & st[ 6]; + st[ 5] ^=3D bc[ 0]; + st[ 6] ^=3D bc[ 1]; + st[ 7] ^=3D bc[ 2]; + st[ 8] ^=3D bc[ 3]; + st[ 9] ^=3D bc[ 4]; + + bc[ 0] =3D ~st[11] & st[12]; + bc[ 1] =3D ~st[12] & st[13]; + bc[ 2] =3D ~st[13] & st[14]; + bc[ 3] =3D ~st[14] & st[10]; + bc[ 4] =3D ~st[10] & st[11]; + st[10] ^=3D bc[ 0]; + st[11] ^=3D bc[ 1]; + st[12] ^=3D bc[ 2]; + st[13] ^=3D bc[ 3]; + st[14] ^=3D bc[ 4]; + + bc[ 0] =3D ~st[16] & st[17]; + bc[ 1] =3D ~st[17] & st[18]; + bc[ 2] =3D ~st[18] & st[19]; + bc[ 3] =3D ~st[19] & st[15]; + bc[ 4] =3D ~st[15] & st[16]; + st[15] ^=3D bc[ 0]; + st[16] ^=3D bc[ 1]; + st[17] ^=3D bc[ 2]; + st[18] ^=3D bc[ 3]; + st[19] ^=3D bc[ 4]; + + bc[ 0] =3D ~st[21] & st[22]; + bc[ 1] =3D ~st[22] & st[23]; + bc[ 2] =3D ~st[23] & st[24]; + bc[ 3] =3D ~st[24] & st[20]; + bc[ 4] =3D ~st[20] & st[21]; + st[20] ^=3D bc[ 0]; + st[21] ^=3D bc[ 1]; + st[22] ^=3D bc[ 2]; + st[23] ^=3D bc[ 3]; + st[24] ^=3D bc[ 4]; +} + +static void sha3_keccakf_rounds_generic(struct sha3_state *state) +{ + for (int round =3D 0; round < SHA3_KECCAK_ROUNDS; round++) { + sha3_keccakf_one_round_generic(state); + /* Iota */ + state->st[0] ^=3D sha3_keccakf_rndc[round]; + } +} + +/* + * Byteswap the state buckets to CPU-endian if we're not on a little-endian + * machine for the duration of the Keccak mixing function. Note that these + * loops are no-ops on LE machines and will be optimised away. + */ +static void sha3_keccakf_generic(struct sha3_state *state) +{ + for (int i =3D 0; i < ARRAY_SIZE(state->st); i++) + cpu_to_le64s(&state->st[i]); + + sha3_keccakf_rounds_generic(state); + + for (int i =3D 0; i < ARRAY_SIZE(state->st); i++) + le64_to_cpus(&state->st[i]); +} + +static void sha3_absorb_block_generic(struct sha3_ctx *ctx, const u8 *data) +{ + struct sha3_state *state =3D &ctx->state; + unsigned int bsize =3D ctx->block_size; + + for (int i =3D 0; i < bsize / 8; i++) + state->st[i] ^=3D get_unaligned((u64 *)(data + 8 * i)); + sha3_keccakf_generic(state); +} + +/* + * Perform rounds of XOR'ing whole blocks of data into the state buffer and + * then performing a keccak mix step. + */ +static void sha3_absorb_blocks_generic(struct sha3_ctx *ctx, + const u8 *data, size_t nblocks) +{ + do { + sha3_absorb_block_generic(ctx, data); + data +=3D ctx->block_size; + } while (--nblocks); +} + +#ifdef CONFIG_CRYPTO_LIB_SHA3_ARCH +#include "sha3.h" /* $(SRCARCH)/sha3.h */ +#else +#define sha3_keccakf sha3_keccakf_generic +#define sha3_absorb_blocks sha3_absorb_blocks_generic +#endif + +/* + * XOR in partial data that's insufficient to fill a whole block. + */ +static void sha3_absorb_xorle(struct sha3_ctx *ctx, const u8 *data, + unsigned int partial, unsigned int len) +{ + u8 *buf =3D (u8 *)ctx->state.st; + + buf +=3D partial; + for (int i =3D 0; i < len; i++) + *buf++ ^=3D *data++; +} + +/** + * sha3_update() - Update a SHA3 context of any type with message data + * @ctx: the context to update; must have been initialized + * @data: the message data + * @len: the data length in bytes + * + * This can be called any number of times to perform the "keccak sponge + * absorbing" phase. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +void sha3_update(struct sha3_ctx *ctx, const u8 *data, unsigned int len) +{ + unsigned int absorb_offset =3D ctx->absorb_offset; + unsigned int bsize =3D ctx->block_size; + + WARN_ON_ONCE(ctx->end_marked); + + if (absorb_offset && absorb_offset + len >=3D bsize) { + sha3_absorb_xorle(ctx, data, absorb_offset, bsize - absorb_offset); + len -=3D bsize - absorb_offset; + data +=3D bsize - absorb_offset; + sha3_keccakf(&ctx->state); + ctx->absorb_offset =3D 0; + } + + if (len >=3D bsize) { + size_t nblocks =3D len / bsize; + + sha3_absorb_blocks(ctx, data, nblocks); + data +=3D nblocks * bsize; + len -=3D nblocks * bsize; + } + + if (len) { + sha3_absorb_xorle(ctx, data, ctx->absorb_offset, len); + ctx->absorb_offset +=3D len; + } +} +EXPORT_SYMBOL_GPL(sha3_update); + +/** + * sha3_squeeze() - Finalize a SHA3 digest of any type and extract the dig= est + * @ctx: the context to finalize; must have been initialized + * @out: Where to write the resulting message digest + * @out_size: The amount of digest to extract to @out + * + * Finish the computation of a SHA3 message digest of any type and perform= the + * "Keccak sponge squeezing" phase. @out_size amount of digest is written= to + * @out buffer. + * + * This may be called multiple times to extract continuations of the diges= t. + * Note that, for example, two consecutive 16-byte squeezes laid end-to-end + * will yield the same as one 32-byte squeeze. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_size) +{ + unsigned int squeeze_offset =3D ctx->squeeze_offset; + unsigned int bsize =3D ctx->block_size; + u8 *p =3D (u8 *)ctx->state.st, end_marker =3D 0x80; + + if (!ctx->end_marked) { + sha3_absorb_xorle(ctx, &ctx->padding, ctx->absorb_offset, 1); + sha3_absorb_xorle(ctx, &end_marker, bsize - 1, 1); + ctx->end_marked =3D true; + } + + for (;;) { + if (squeeze_offset =3D=3D 0) + sha3_keccakf(&ctx->state); + + unsigned int part =3D umin(out_size, bsize - squeeze_offset); + + if (part > 0) { + memcpy(out, p + squeeze_offset, part); + out_size -=3D part; + out +=3D part; + squeeze_offset +=3D part; + } + if (!out_size) + break; + if (squeeze_offset >=3D bsize) + squeeze_offset =3D 0; + } + + ctx->squeeze_offset =3D squeeze_offset; +} +EXPORT_SYMBOL_GPL(sha3_squeeze); + +/** + * sha3_224() - Convenience wrapper to digest a simple buffer as SHA3-224 + * @in: The data to be digested + * @in_len: The amount of data to be digested in bytes + * @out: The buffer into which the digest will be stored (size not checked) + * + * Convenience wrapper to initialise a SHA3 context for SHA-224, add the i= nput + * data to it, finalise it, extract 28 bytes of digest and clear the conte= xt. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE]) +{ + struct sha3_224_ctx ctx; + + sha3_224_init(&ctx); + sha3_224_update(&ctx, in, in_len); + sha3_224_final(&ctx, out); +} +EXPORT_SYMBOL(sha3_224); + +/** + * sha3_256() - Convenience wrapper to digest a simple buffer as SHA3-256 + * @in: The data to be digested + * @in_len: The amount of data to be digested in bytes + * @out: The buffer into which the digest will be stored (size not checked) + * + * Convenience wrapper to initialise a SHA3 context for SHA-256, add the i= nput + * data to it, finalise it, extract 32 bytes of digest and clear the conte= xt. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE]) +{ + struct sha3_256_ctx ctx; + + sha3_256_init(&ctx); + sha3_256_update(&ctx, in, in_len); + sha3_256_final(&ctx, out); +} +EXPORT_SYMBOL(sha3_256); + +/** + * sha3_384() - Convenience wrapper to digest a simple buffer as SHA3-384 + * @in: The data to be digested + * @in_len: The amount of data to be digested in bytes + * @out: The buffer into which the digest will be stored (size not checked) + * + * Convenience wrapper to initialise a SHA3 context for SHA-384, add the i= nput + * data to it, finalise it, extract 48 bytes of digest and clear the conte= xt. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE]) +{ + struct sha3_384_ctx ctx; + + sha3_384_init(&ctx); + sha3_384_update(&ctx, in, in_len); + sha3_384_final(&ctx, out); +} +EXPORT_SYMBOL(sha3_384); + +/** + * sha3_512() - Convenience wrapper to digest a simple buffer as SHA3-512 + * @in: The data to be digested in bytes + * @in_len: The amount of data to be digested in bytes + * @out: The buffer into which the digest will be stored (size not checked) + * + * Convenience wrapper to initialise a SHA3 context for SHA-512, add the i= nput + * data to it, finalise it, extract 64 bytes of digest and clear the conte= xt. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE]) +{ + struct sha3_512_ctx ctx; + + sha3_512_init(&ctx); + sha3_512_update(&ctx, in, in_len); + sha3_512_final(&ctx, out); +} +EXPORT_SYMBOL(sha3_512); + +/** + * shake128() - Convenience wrapper to apply SHAKE128 to a simple buffer + * @in: The input data to be used + * @in_len: The amount of input data in bytes + * @out: The buffer in which to store the output + * @out_len: The amount of output to store in bytes (variable length) + * + * Convenience wrapper to initialise a SHA3 context for SHAKE128, add the = input + * data to it, finalise it, extract the requested amount of output and cle= ar + * the context. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +void shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len) +{ + struct shake128_ctx ctx; + + shake128_init(&ctx); + shake128_update(&ctx, in, in_len); + shake128_squeeze(&ctx, out, out_len); + shake128_clear(&ctx); +} +EXPORT_SYMBOL(shake128); + +/** + * shake256() - Convenience wrapper to apply SHAKE256 to a simple buffer + * @in: The input data to be used + * @in_len: The amount of input data in bytes + * @out: The buffer in which to store the output + * @out_len: The amount of output to store in bytes (variable length) + * + * Convenience wrapper to initialise a SHA3 context for SHAKE128, add the = input + * data to it, finalise it, extract the requested amount of output and cle= ar + * the context. + * + * Return: None. + * + * Context: May use the FPU/Vector unit registers. + */ +void shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len) +{ + struct shake256_ctx ctx; + + shake256_init(&ctx); + shake256_update(&ctx, in, in_len); + shake256_squeeze(&ctx, out, out_len); + shake256_clear(&ctx); +} +EXPORT_SYMBOL(shake256); + +/* + * Do a quick test using SHAKE256 and a 200 byte digest. + */ +static const u8 sha3_sample[] __initconst =3D + "The quick red fox jumped over the lazy brown dog!\n" + "The quick red fox jumped over the lazy brown dog!\n" + "The quick red fox jumped over the lazy brown dog!\n" + "The quick red fox jumped over the lazy brown dog!\n"; + +static const u8 sha3_sample_shake256_200[] __initconst =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */ + 0xab, 0x06, 0xd4, 0xf9, 0x8b, 0xfd, 0xb2, 0xc4, 0xfe, 0xf1, 0xcc, 0xe2, + 0x40, 0x45, 0xdd, 0x15, 0xcb, 0xdd, 0x02, 0x8d, 0xb7, 0x9f, 0x1e, 0x67, + 0xd6, 0x7f, 0x98, 0x5e, 0x1b, 0x19, 0xf8, 0x01, 0x43, 0x82, 0xcb, 0xd8, + 0x5d, 0x21, 0x64, 0xa8, 0x80, 0xc9, 0x22, 0xe5, 0x07, 0xaf, 0xe2, 0x5d, + 0xcd, 0xc6, 0x23, 0x36, 0x2b, 0xc7, 0xc7, 0x7d, 0x09, 0x9d, 0x68, 0x05, + 0xe4, 0x62, 0x63, 0x1b, 0x67, 0xbc, 0xf8, 0x95, 0x07, 0xd2, 0xe4, 0xd0, + 0xba, 0xa2, 0x67, 0xf5, 0xe3, 0x15, 0xbc, 0x85, 0xa1, 0x50, 0xd6, 0x6f, + 0x6f, 0xd4, 0x54, 0x4c, 0x3f, 0x4f, 0xe5, 0x1f, 0xb7, 0x00, 0x27, 0xfc, + 0x15, 0x33, 0xc2, 0xf9, 0xb3, 0x4b, 0x9e, 0x81, 0xe5, 0x96, 0xbe, 0x05, + 0x6c, 0xac, 0xf9, 0x9f, 0x65, 0x36, 0xbb, 0x11, 0x47, 0x6d, 0xf6, 0x8f, + 0x9f, 0xa2, 0x77, 0x37, 0x3b, 0x18, 0x77, 0xcf, 0x65, 0xc5, 0xa1, 0x7e, + 0x2c, 0x0e, 0x71, 0xf0, 0x4d, 0x18, 0x67, 0xb9, 0xc4, 0x8c, 0x64, 0x3b, + 0x4b, 0x45, 0xea, 0x16, 0xb2, 0x4a, 0xc5, 0xf5, 0x85, 0xdc, 0xd2, 0xd9, + 0x13, 0x77, 0xb3, 0x19, 0xd9, 0x8c, 0x9f, 0x28, 0xe7, 0x64, 0x91, 0x0f, + 0x6f, 0x32, 0xbf, 0xa8, 0xa8, 0xa3, 0xff, 0x99, 0x0e, 0x0b, 0x62, 0x50, + 0xf8, 0x3a, 0xc2, 0xf5, 0x98, 0x21, 0xeb, 0x9d, 0xe8, 0x45, 0xf4, 0x46, + 0x1e, 0x8b, 0xbd, 0x10, 0x59, 0x2c, 0x87, 0xe2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */ +}; + +static int __init sha3_mod_init(void) +{ +#define out_len 200 + u8 out[8 + out_len + 8] =3D {}; + +#ifdef sha3_mod_init_arch + sha3_mod_init_arch(); +#endif + + BUILD_BUG_ON(sizeof(out) !=3D sizeof(sha3_sample_shake256_200)); + + shake256(sha3_sample, sizeof(sha3_sample) - 1, out + 8, out_len); + + if (memcmp(out, sha3_sample_shake256_200, + sizeof(sha3_sample_shake256_200)) !=3D 0) { + pr_err("SHAKE256(200) failed\n"); + for (int i =3D 0; i < out_len;) { + int part =3D min(out_len - i, 32); + + pr_err("%*phN\n", part, out + i); + i +=3D part; + } + return -EBADMSG; + } + return 0; +} +subsys_initcall(sha3_mod_init); + +#ifdef sha3_mod_init_arch +static void __exit sha3_mod_exit(void) +{ +} +module_exit(sha3_mod_exit); +#endif + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm"); From nobody Wed Oct 1 22:33:17 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 703153002CA for ; Fri, 26 Sep 2025 14:20:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896435; cv=none; b=g6UzIAfR44gh3Xle/4JoZU42o3HFgKRnkH3tnQe9ApWif/9VmYKd1dyBM3D8DZguiAqL3vyAmRLCymoQ79w6kpXwVwGx8yoeolmSxXatF2kLP88Zt5nGg3VMFPPZwFnwK8rvnvWjyr0XxJTFbtm6QF7nNybhaNHK+ahozFC0X5M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896435; c=relaxed/simple; bh=OvyvPM10QzpkeCABfp37gXYPwmUBlf1gwnMg79lMkgI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lTgFzwBnwgQbtOqxja9yCYPQ4kkNGNbSJlnnwlxoYZJKAXyvMlukIqgz6Ck3ayOFBlt0txB7ory3cACqIRDxr6H/0O+5dbC2rDvOhz8wQ5bulffskCs0X2I/7dCfncVJY9ygbjPD7CKX25IhxlpMDUisIRwHUP1r6qgMamtcnqw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=crBx3wVh; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="crBx3wVh" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758896431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=a8sXgvjkqO2iF+gXtkEgd4Q33lXn9KH8SUp4XV4jFiY=; b=crBx3wVhAsPHi0nzZXTmlOMq//cipjfwv2qhE64qttYFIrAdm/imtEGIoMXUmFnL568xIV N2emuTKjbyprpz8SuEb6eXgp24KaYrlrxzsBhxwIHQ7UxPtxgVWb4xc3VZ5CGB64w8IbFf NP0vm/9MurlM3Ja3v1IMzsy0rAYoBOE= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-616-FducmU_gOFelpv9Se6-Rew-1; Fri, 26 Sep 2025 10:20:26 -0400 X-MC-Unique: FducmU_gOFelpv9Se6-Rew-1 X-Mimecast-MFC-AGG-ID: FducmU_gOFelpv9Se6-Rew_1758896424 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C5668180057D; Fri, 26 Sep 2025 14:20:24 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.155]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 3BA0719560A2; Fri, 26 Sep 2025 14:20:22 +0000 (UTC) From: David Howells To: Cc: David Howells , Eric Biggers , "Jason A . Donenfeld" , Ard Biesheuvel , Herbert Xu , Stephan Mueller , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 4/8] lib/crypto: Move the SHA3 Iota transform into the single round function Date: Fri, 26 Sep 2025 15:19:47 +0100 Message-ID: <20250926141959.1272455-5-dhowells@redhat.com> In-Reply-To: <20250926141959.1272455-1-dhowells@redhat.com> References: <20250926141959.1272455-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" In crypto/sha3_generic.c, the keccakf() function calls keccakf_round() to do most of the transforms, but not the Iota transform - presumably because that is dependent on round number, whereas the Theta, Rho, Pi and Chi transforms are not. Note that the keccakf_round() function needs to be explicitly non-inlined on certain architectures as gcc's produced output will (or used to) use over 1KiB of stack space if inlined. Now, this code was copied more or less verbatim into lib/crypto/sha3.c, so that has the same aesthetic issue. Fix this there by passing the round number into sha3_keccakf_one_round_generic() and doing the Iota transform there. crypto/sha3_generic.c is left untouched as that will be converted to use lib/crypto/sha3.c at some point. Suggested-by: Eric Biggers Signed-off-by: David Howells cc: Eric Biggers cc: Jason A. Donenfeld cc: Ard Biesheuvel cc: Herbert Xu cc: Stephan Mueller cc: linux-crypto@vger.kernel.org --- lib/crypto/sha3.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index a8eaa25a837f..227d45bd9680 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -48,7 +48,8 @@ static const u64 sha3_keccakf_rndc[24] =3D { /* * Perform a single round of Keccak mixing. */ -static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *= state) +static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *= state, + int round) { u64 *st =3D state->st; u64 t[5], tt, bc[5]; @@ -150,15 +151,15 @@ static SHA3_INLINE void sha3_keccakf_one_round_generi= c(struct sha3_state *state) st[22] ^=3D bc[ 2]; st[23] ^=3D bc[ 3]; st[24] ^=3D bc[ 4]; + + /* Iota */ + state->st[0] ^=3D sha3_keccakf_rndc[round]; } =20 static void sha3_keccakf_rounds_generic(struct sha3_state *state) { - for (int round =3D 0; round < SHA3_KECCAK_ROUNDS; round++) { - sha3_keccakf_one_round_generic(state); - /* Iota */ - state->st[0] ^=3D sha3_keccakf_rndc[round]; - } + for (int round =3D 0; round < SHA3_KECCAK_ROUNDS; round++) + sha3_keccakf_one_round_generic(state, round); } =20 /* From nobody Wed Oct 1 22:33:17 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2A5EF3016EE for ; Fri, 26 Sep 2025 14:20:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896440; cv=none; b=gZsTACDUlGNJNtgMTphWYAVaxhdjk+p5FfmZF/V92cfTMlWboogYeBQ32LYQ5fKzpZN9bTXBqI6ZI3wkKdSXeXjbqmMtq0UOc5ywb2qZ4GM6f1avZmvWFzquw8LF/5Z7lnKi4MEpeJDLgmx7XUnr1GBO4NBy15fNJmBXHBFJxHk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896440; c=relaxed/simple; bh=RstHuA3cBklkJUkifPKThJkJ8whdV1GDYeMseAVOck4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=U9bpbXHpqvxPSTUrtm+R5PlzhnzHE04oZeAwSBqJFkyL6egW4a6qJW1o1RSA+ogAifMA7igGDD2OgjMZOz0WbCWdHrTOTl7s5WvX5pVFcQ/z9+/yHpZtBFW31cRnrJqDB/2PCLQoB57j3GQLX99zXfOwiE1M1qVow935p2DkF3A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=FtOkjWSA; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="FtOkjWSA" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758896436; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ctX6GLC+tbbwUuPLuR9eoCXRO610reOy2EsWFsPbfBk=; b=FtOkjWSAzNn12oDh0oXzdwZZdRGkHh0uOBrEa3ug4s2G9ltNCB9euuoUzbxfOcwIdfcJFh S09b0RpG39MbM5nKGe7o+Vu1MzZ/Xk+jYStEGT0OlwlijdvLtB05Ba9+Drs1JVspmwHoPp mPA0m6kudLa9WOZcTKmng7KYGoXRsqU= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-48-Q9FyEoCxOGSZdnIaNAfKaQ-1; Fri, 26 Sep 2025 10:20:30 -0400 X-MC-Unique: Q9FyEoCxOGSZdnIaNAfKaQ-1 X-Mimecast-MFC-AGG-ID: Q9FyEoCxOGSZdnIaNAfKaQ_1758896429 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 166791800284; Fri, 26 Sep 2025 14:20:29 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.155]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 8A5B719560A2; Fri, 26 Sep 2025 14:20:26 +0000 (UTC) From: David Howells To: Cc: David Howells , Eric Biggers , "Jason A . Donenfeld" , Ard Biesheuvel , Herbert Xu , Stephan Mueller , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 5/8] lib/crypto: Add SHA3 kunit tests Date: Fri, 26 Sep 2025 15:19:48 +0100 Message-ID: <20250926141959.1272455-6-dhowells@redhat.com> In-Reply-To: <20250926141959.1272455-1-dhowells@redhat.com> References: <20250926141959.1272455-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Add a SHA3 kunit test, providing the following: (*) A simple test of each of SHA3-224, SHA3-256, SHA3-384, SHA-512, SHAKE128 and SHAKE256. (*) NIST 0- and 1600-bit test vectors for SHAKE128 and SHAKE256. (*) Output tiling (multiple squeezing) tests for SHAKE256. (*) Standard hash template test for SHA3-256. (*) Standard benchmark test for SHA3-256. gen-hash-testvecs.py is also modified to be able to generate SHAKE hashes because Python's hashlib requires the output digest size supplying for those two algorithms as they produce arbitrary length digests. Signed-off-by: David Howells cc: Eric Biggers cc: Jason A. Donenfeld cc: Ard Biesheuvel cc: Herbert Xu cc: Stephan Mueller cc: linux-crypto@vger.kernel.org --- lib/crypto/tests/Kconfig | 12 + lib/crypto/tests/Makefile | 1 + lib/crypto/tests/sha3_kunit.c | 338 ++++++++++++++++++++++++++++ lib/crypto/tests/sha3_testvecs.h | 231 +++++++++++++++++++ scripts/crypto/gen-hash-testvecs.py | 8 +- 5 files changed, 588 insertions(+), 2 deletions(-) create mode 100644 lib/crypto/tests/sha3_kunit.c create mode 100644 lib/crypto/tests/sha3_testvecs.h diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig index 578af717e13a..becc781352b1 100644 --- a/lib/crypto/tests/Kconfig +++ b/lib/crypto/tests/Kconfig @@ -72,6 +72,18 @@ config CRYPTO_LIB_SHA512_KUNIT_TEST KUnit tests for the SHA-384 and SHA-512 cryptographic hash functions and their corresponding HMACs. =20 +config CRYPTO_LIB_SHA3_KUNIT_TEST + tristate "KUnit tests for SHA-3" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS + select CRYPTO_LIB_BENCHMARK_VISIBLE + select CRYPTO_LIB_SHA3 + help + KUnit tests for the SHA3 cryptographic hash functions, including + SHA3-224, SHA3-256, SHA3-386, SHA3-512, SHAKE128 and SHAKE256. Note + that whilst the SHAKE* hash functions can support arbitrary-length + digests, these tests only check the nominal digest sizes for now. + config CRYPTO_LIB_BENCHMARK_VISIBLE bool =20 diff --git a/lib/crypto/tests/Makefile b/lib/crypto/tests/Makefile index a71fad19922b..9c61b29ac4ca 100644 --- a/lib/crypto/tests/Makefile +++ b/lib/crypto/tests/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_CRYPTO_LIB_POLY1305_KUNIT_TEST) +=3D poly1305_= kunit.o obj-$(CONFIG_CRYPTO_LIB_SHA1_KUNIT_TEST) +=3D sha1_kunit.o obj-$(CONFIG_CRYPTO_LIB_SHA256_KUNIT_TEST) +=3D sha224_kunit.o sha256_kuni= t.o obj-$(CONFIG_CRYPTO_LIB_SHA512_KUNIT_TEST) +=3D sha384_kunit.o sha512_kuni= t.o +obj-$(CONFIG_CRYPTO_LIB_SHA3_KUNIT_TEST) +=3D sha3_kunit.o diff --git a/lib/crypto/tests/sha3_kunit.c b/lib/crypto/tests/sha3_kunit.c new file mode 100644 index 000000000000..ed31cf37018d --- /dev/null +++ b/lib/crypto/tests/sha3_kunit.c @@ -0,0 +1,338 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2025 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ +#include +#include "sha3_testvecs.h" + +#define HASH sha3_256 +#define HASH_CTX sha3_256_ctx +#define HASH_SIZE SHA3_256_DIGEST_SIZE +#define HASH_INIT sha3_256_init +#define HASH_UPDATE sha3_256_update +#define HASH_FINAL sha3_256_final +#include "hash-test-template.h" + +static const u8 test_sha3_sample[] =3D + "The quick red fox jumped over the lazy brown dog!\n" + "The quick red fox jumped over the lazy brown dog!\n" + "The quick red fox jumped over the lazy brown dog!\n" + "The quick red fox jumped over the lazy brown dog!\n"; + +static const u8 test_sha3_224[8 + SHA3_224_DIGEST_SIZE + 8] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */ + 0xd6, 0xe8, 0xd8, 0x80, 0xfa, 0x42, 0x80, 0x70, + 0x7e, 0x7f, 0xd7, 0xd2, 0xd7, 0x7a, 0x35, 0x65, + 0xf0, 0x0b, 0x4f, 0x9f, 0x2a, 0x33, 0xca, 0x0a, + 0xef, 0xa6, 0x4c, 0xb8, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */ +}; + +static const u8 test_sha3_256[8 + SHA3_256_DIGEST_SIZE + 8] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */ + 0xdb, 0x3b, 0xb0, 0xb8, 0x8d, 0x15, 0x78, 0xe5, + 0x78, 0x76, 0x8e, 0x39, 0x7e, 0x89, 0x86, 0xb9, + 0x14, 0x3a, 0x1e, 0xe7, 0x96, 0x7c, 0xf3, 0x25, + 0x70, 0xbd, 0xc3, 0xa9, 0xae, 0x63, 0x71, 0x1d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */ +}; + +static const u8 test_sha3_384[8 + SHA3_384_DIGEST_SIZE + 8] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */ + 0x2d, 0x4b, 0x29, 0x85, 0x19, 0x94, 0xaa, 0x31, + 0x9b, 0x04, 0x9d, 0x6e, 0x79, 0x66, 0xc7, 0x56, + 0x8a, 0x2e, 0x99, 0x84, 0x06, 0xcf, 0x10, 0x2d, + 0xec, 0xf0, 0x03, 0x04, 0x1f, 0xd5, 0x99, 0x63, + 0x2f, 0xc3, 0x2b, 0x0d, 0xd9, 0x45, 0xf7, 0xbb, + 0x0a, 0xc3, 0x46, 0xab, 0xfe, 0x4d, 0x94, 0xc2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */ +}; + +static const u8 test_sha3_512[8 + SHA3_512_DIGEST_SIZE + 8] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */ + 0xdd, 0x71, 0x3b, 0x44, 0xb6, 0x6c, 0xd7, 0x78, + 0xe7, 0x93, 0xa1, 0x4c, 0xd7, 0x24, 0x16, 0xf1, + 0xfd, 0xa2, 0x82, 0x4e, 0xed, 0x59, 0xe9, 0x83, + 0x15, 0x38, 0x89, 0x7d, 0x39, 0x17, 0x0c, 0xb2, + 0xcf, 0x12, 0x80, 0x78, 0xa1, 0x78, 0x41, 0xeb, + 0xed, 0x21, 0x4c, 0xa4, 0x4a, 0x5f, 0x30, 0x1a, + 0x70, 0x98, 0x4f, 0x14, 0xa2, 0xd1, 0x64, 0x1b, + 0xc2, 0x0a, 0xff, 0x3b, 0xe8, 0x26, 0x41, 0x8f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */ +}; + +static const u8 test_shake128[8 + SHAKE128_DEFAULT_SIZE + 8] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */ + 0x41, 0xd6, 0xb8, 0x9c, 0xf8, 0xe8, 0x54, 0xf2, + 0x5c, 0xde, 0x51, 0x12, 0xaf, 0x9e, 0x0d, 0x91, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */ +}; + +static const u8 test_shake256[8 + SHAKE256_DEFAULT_SIZE + 8] =3D { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-before guard */ + 0xab, 0x06, 0xd4, 0xf9, 0x8b, 0xfd, 0xb2, 0xc4, + 0xfe, 0xf1, 0xcc, 0xe2, 0x40, 0x45, 0xdd, 0x15, + 0xcb, 0xdd, 0x02, 0x8d, 0xb7, 0x9f, 0x1e, 0x67, + 0xd6, 0x7f, 0x98, 0x5e, 0x1b, 0x19, 0xf8, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Write-after guard */ +}; + +static void test_sha3_224_basic(struct kunit *test) +{ + u8 out[8 + SHA3_224_DIGEST_SIZE + 8]; + + BUILD_BUG_ON(sizeof(out) !=3D sizeof(test_sha3_224)); + + memset(out, 0, sizeof(out)); + sha3_224(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8); + + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_224, sizeof(test_sha3_224), + "SHA3-224 gives wrong output"); +} + +static void test_sha3_256_basic(struct kunit *test) +{ + u8 out[8 + SHA3_256_DIGEST_SIZE + 8]; + + BUILD_BUG_ON(sizeof(out) !=3D sizeof(test_sha3_256)); + + memset(out, 0, sizeof(out)); + sha3_256(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8); + + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_256, sizeof(test_sha3_256), + "SHA3-256 gives wrong output"); +} + +static void test_sha3_384_basic(struct kunit *test) +{ + u8 out[8 + SHA3_384_DIGEST_SIZE + 8]; + + BUILD_BUG_ON(sizeof(out) !=3D sizeof(test_sha3_384)); + + memset(out, 0, sizeof(out)); + sha3_384(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8); + + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_384, sizeof(test_sha3_384), + "SHA3-384 gives wrong output"); +} + +static void test_sha3_512_basic(struct kunit *test) +{ + u8 out[8 + SHA3_512_DIGEST_SIZE + 8]; + + BUILD_BUG_ON(sizeof(out) !=3D sizeof(test_sha3_512)); + + memset(out, 0, sizeof(out)); + sha3_512(test_sha3_sample, sizeof(test_sha3_sample) - 1, out + 8); + + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_sha3_512, sizeof(test_sha3_512), + "SHA3-512 gives wrong output"); +} + +static void test_shake128_basic(struct kunit *test) +{ + u8 out[8 + SHAKE128_DEFAULT_SIZE + 8]; + + BUILD_BUG_ON(sizeof(out) !=3D sizeof(test_shake128)); + + memset(out, 0, sizeof(out)); + shake128(test_sha3_sample, sizeof(test_sha3_sample) - 1, + out + 8, sizeof(out) - 16); + + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128, sizeof(test_shake128), + "SHAKE128 gives wrong output"); +} + +static void test_shake256_basic(struct kunit *test) +{ + u8 out[8 + SHAKE256_DEFAULT_SIZE + 8]; + + BUILD_BUG_ON(sizeof(out) !=3D sizeof(test_shake256)); + + memset(out, 0, sizeof(out)); + shake256(test_sha3_sample, sizeof(test_sha3_sample) - 1, + out + 8, sizeof(out) - 16); + + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256), + "SHAKE256 gives wrong output"); +} + +/* + * Usable NIST tests. + * + * From: https://csrc.nist.gov/projects/cryptographic-standards-and-guidel= ines/example-values + */ +static const u8 test_nist_1600_sample[] =3D { + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, + 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3 +}; + +static const u8 test_shake128_nist_0[] =3D { + 0x7f, 0x9c, 0x2b, 0xa4, 0xe8, 0x8f, 0x82, 0x7d, + 0x61, 0x60, 0x45, 0x50, 0x76, 0x05, 0x85, 0x3e +}; + +static const u8 test_shake128_nist_1600[] =3D { + 0x13, 0x1a, 0xb8, 0xd2, 0xb5, 0x94, 0x94, 0x6b, + 0x9c, 0x81, 0x33, 0x3f, 0x9b, 0xb6, 0xe0, 0xce, +}; + +static const u8 test_shake256_nist_0[] =3D { + 0x46, 0xb9, 0xdd, 0x2b, 0x0b, 0xa8, 0x8d, 0x13, + 0x23, 0x3b, 0x3f, 0xeb, 0x74, 0x3e, 0xeb, 0x24, + 0x3f, 0xcd, 0x52, 0xea, 0x62, 0xb8, 0x1b, 0x82, + 0xb5, 0x0c, 0x27, 0x64, 0x6e, 0xd5, 0x76, 0x2f +}; + +static const u8 test_shake256_nist_1600[] =3D { + 0xcd, 0x8a, 0x92, 0x0e, 0xd1, 0x41, 0xaa, 0x04, + 0x07, 0xa2, 0x2d, 0x59, 0x28, 0x86, 0x52, 0xe9, + 0xd9, 0xf1, 0xa7, 0xee, 0x0c, 0x1e, 0x7c, 0x1c, + 0xa6, 0x99, 0x42, 0x4d, 0xa8, 0x4a, 0x90, 0x4d, +}; + +static void test_shake128_nist(struct kunit *test) +{ + u8 out[SHAKE128_DEFAULT_SIZE]; + + shake128("", 0, out, sizeof(out)); + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128_nist_0, sizeof(out), + "SHAKE128 gives wrong output for NIST.0"); + + shake128(test_nist_1600_sample, sizeof(test_nist_1600_sample), + out, sizeof(out)); + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake128_nist_1600, sizeof(out), + "SHAKE128 gives wrong output for NIST.1600"); +} + +static void test_shake256_nist(struct kunit *test) +{ + u8 out[SHAKE256_DEFAULT_SIZE]; + + shake256("", 0, out, sizeof(out)); + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256_nist_0, sizeof(out), + "SHAKE256 gives wrong output for NIST.0"); + + shake256(test_nist_1600_sample, sizeof(test_nist_1600_sample), + out, sizeof(out)); + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256_nist_1600, sizeof(out), + "SHAKE256 gives wrong output for NIST.1600"); +} + +/* + * Output tiling test of SHAKE256; equal output tiles barring the last. A + * series of squeezings of the same context should, if laid end-to-end, ma= tch a + * single squeezing of the combined size. + */ +static void test_shake256_tiling(struct kunit *test) +{ + struct shake256_ctx ctx; + u8 out[8 + SHA3_512_DIGEST_SIZE + 8]; + + for (int tile_size =3D 1; tile_size < SHAKE256_DEFAULT_SIZE; tile_size++)= { + int left =3D SHAKE256_DEFAULT_SIZE; + u8 *p =3D out + 8; + + memset(out, 0, sizeof(out)); + shake256_init(&ctx); + shake256_update(&ctx, test_sha3_sample, sizeof(test_sha3_sample) - 1); + while (left > 0) { + int part =3D umin(tile_size, left); + + shake256_squeeze(&ctx, p, part); + p +=3D part; + left -=3D part; + } + + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256), + "SHAKE tile %u gives wrong output", tile_size); + } +} + +/* + * Output tiling test of SHAKE256; output tiles getting gradually smaller = and + * then cycling round to medium sized ones. A series of squeezings of the= same + * context should, if laid end-to-end, match a single squeezing of the com= bined + * size. + */ +static void test_shake256_tiling2(struct kunit *test) +{ + struct shake256_ctx ctx; + u8 out[8 + SHA3_512_DIGEST_SIZE + 8]; + + for (int first_tile_size =3D 3; + first_tile_size < SHAKE256_DEFAULT_SIZE; + first_tile_size++) { + int tile_size =3D first_tile_size; + int left =3D SHAKE256_DEFAULT_SIZE; + u8 *p =3D out + 8; + + memset(out, 0, sizeof(out)); + shake256_init(&ctx); + shake256_update(&ctx, test_sha3_sample, sizeof(test_sha3_sample) - 1); + while (left > 0) { + int part =3D umin(tile_size, left); + + shake256_squeeze(&ctx, p, part); + p +=3D part; + left -=3D part; + tile_size--; + if (tile_size < 1) + tile_size =3D 5; + } + + KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256), + "SHAKE tile %u gives wrong output", tile_size); + } +} + +static struct kunit_case hash_test_cases[] =3D { + KUNIT_CASE(test_sha3_224_basic), + KUNIT_CASE(test_sha3_256_basic), + KUNIT_CASE(test_sha3_384_basic), + KUNIT_CASE(test_sha3_512_basic), + KUNIT_CASE(test_shake128_basic), + KUNIT_CASE(test_shake256_basic), + KUNIT_CASE(test_shake128_nist), + KUNIT_CASE(test_shake256_nist), + KUNIT_CASE(test_shake256_tiling), + KUNIT_CASE(test_shake256_tiling2), + HASH_KUNIT_CASES, + KUNIT_CASE(benchmark_hash), + {}, +}; + +static struct kunit_suite hash_test_suite =3D { + .name =3D "sha3", + .test_cases =3D hash_test_cases, + .suite_init =3D hash_suite_init, + .suite_exit =3D hash_suite_exit, +}; +kunit_test_suite(hash_test_suite); + +MODULE_DESCRIPTION("KUnit tests and benchmark for SHA3-256"); +MODULE_LICENSE("GPL"); diff --git a/lib/crypto/tests/sha3_testvecs.h b/lib/crypto/tests/sha3_testv= ecs.h new file mode 100644 index 000000000000..9c4c403cc6e0 --- /dev/null +++ b/lib/crypto/tests/sha3_testvecs.h @@ -0,0 +1,231 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha3-= 256 */ + +static const struct { + size_t data_len; + u8 digest[SHA3_256_DIGEST_SIZE]; +} hash_testvecs[] =3D { + { + .data_len =3D 0, + .digest =3D { + 0xa7, 0xff, 0xc6, 0xf8, 0xbf, 0x1e, 0xd7, 0x66, + 0x51, 0xc1, 0x47, 0x56, 0xa0, 0x61, 0xd6, 0x62, + 0xf5, 0x80, 0xff, 0x4d, 0xe4, 0x3b, 0x49, 0xfa, + 0x82, 0xd8, 0x0a, 0x4b, 0x80, 0xf8, 0x43, 0x4a, + }, + }, + { + .data_len =3D 1, + .digest =3D { + 0x11, 0x03, 0xe7, 0x84, 0x51, 0x50, 0x86, 0x35, + 0x71, 0x8a, 0x70, 0xe3, 0xc4, 0x26, 0x7b, 0x21, + 0x02, 0x13, 0xa0, 0x81, 0xe8, 0xe6, 0x14, 0x25, + 0x07, 0x34, 0xe5, 0xc5, 0x40, 0x06, 0xf2, 0x8b, + }, + }, + { + .data_len =3D 2, + .digest =3D { + 0x2f, 0x6f, 0x6d, 0x47, 0x48, 0x52, 0x11, 0xb9, + 0xe4, 0x3d, 0xc8, 0x71, 0xcf, 0xb2, 0xee, 0xae, + 0x5b, 0xf4, 0x12, 0x84, 0x5b, 0x1c, 0xec, 0x6c, + 0xc1, 0x66, 0x88, 0xaa, 0xc3, 0x40, 0xbd, 0x7e, + }, + }, + { + .data_len =3D 3, + .digest =3D { + 0xec, 0x02, 0xe8, 0x81, 0x4f, 0x84, 0x41, 0x69, + 0x06, 0xd8, 0xdc, 0x1d, 0x01, 0x78, 0xd7, 0xcb, + 0x39, 0xdf, 0xd3, 0x12, 0x1c, 0x99, 0xfd, 0xf3, + 0x5c, 0x83, 0xc9, 0xc2, 0x7a, 0x7b, 0x6a, 0x05, + }, + }, + { + .data_len =3D 16, + .digest =3D { + 0xff, 0x6f, 0xc3, 0x41, 0xc3, 0x5f, 0x34, 0x6d, + 0xa7, 0xdf, 0x3e, 0xc2, 0x8b, 0x29, 0xb6, 0xf1, + 0xf8, 0x67, 0xfd, 0xcd, 0xb1, 0x9f, 0x38, 0x08, + 0x1d, 0x8d, 0xd9, 0xc2, 0x43, 0x66, 0x18, 0x6c, + }, + }, + { + .data_len =3D 32, + .digest =3D { + 0xe4, 0xb1, 0x06, 0x17, 0xf8, 0x8b, 0x91, 0x95, + 0xe7, 0x57, 0x66, 0xac, 0x08, 0xb2, 0x03, 0x3e, + 0xf7, 0x84, 0x1f, 0xe3, 0x25, 0xa3, 0x11, 0xd2, + 0x11, 0xa4, 0x78, 0x74, 0x2a, 0x43, 0x20, 0xa5, + }, + }, + { + .data_len =3D 48, + .digest =3D { + 0xeb, 0x57, 0x5f, 0x20, 0xa3, 0x6b, 0xc7, 0xb4, + 0x66, 0x2a, 0xa0, 0x30, 0x3b, 0x52, 0x00, 0xc9, + 0xce, 0x6a, 0xd8, 0x1e, 0xbe, 0xed, 0xa1, 0xd1, + 0xbe, 0x63, 0xc7, 0xe1, 0xe2, 0x66, 0x67, 0x0c, + }, + }, + { + .data_len =3D 49, + .digest =3D { + 0xf0, 0x67, 0xad, 0x66, 0xbe, 0xec, 0x5a, 0xfd, + 0x29, 0xd2, 0x4f, 0x1d, 0xb2, 0x24, 0xb8, 0x90, + 0x05, 0x28, 0x0e, 0x66, 0x67, 0x74, 0x2d, 0xee, + 0x66, 0x25, 0x11, 0xd1, 0x76, 0xa2, 0xfc, 0x3a, + }, + }, + { + .data_len =3D 63, + .digest =3D { + 0x57, 0x56, 0x21, 0xb3, 0x2d, 0x2d, 0xe1, 0x9d, + 0xbf, 0x2c, 0x82, 0xa8, 0xad, 0x7e, 0x6c, 0x46, + 0xfb, 0x30, 0xeb, 0xce, 0xcf, 0xed, 0x2d, 0x65, + 0xe7, 0xe4, 0x96, 0x69, 0xe0, 0x48, 0xd2, 0xb6, + }, + }, + { + .data_len =3D 64, + .digest =3D { + 0x7b, 0xba, 0x67, 0x15, 0xe5, 0x21, 0xc4, 0x69, + 0xd3, 0xef, 0x5c, 0x97, 0x9f, 0x5b, 0xba, 0x9c, + 0xfa, 0x55, 0x64, 0xec, 0xb5, 0x37, 0x53, 0x1b, + 0x3f, 0x4c, 0x0a, 0xed, 0x51, 0x98, 0x2b, 0x52, + }, + }, + { + .data_len =3D 65, + .digest =3D { + 0x44, 0xb6, 0x6b, 0x83, 0x09, 0x83, 0x55, 0x83, + 0xde, 0x1f, 0xcc, 0x33, 0xef, 0xdc, 0x05, 0xbb, + 0x3b, 0x63, 0x76, 0x45, 0xe4, 0x8e, 0x14, 0x7a, + 0x2d, 0xae, 0x90, 0xce, 0x68, 0xc3, 0xa4, 0xf2, + }, + }, + { + .data_len =3D 127, + .digest =3D { + 0x50, 0x3e, 0x99, 0x4e, 0x28, 0x2b, 0xc9, 0xf4, + 0xf5, 0xeb, 0x2b, 0x16, 0x04, 0x2d, 0xf5, 0xbe, + 0xc0, 0x91, 0x41, 0x2a, 0x8e, 0x69, 0x5e, 0x39, + 0x53, 0x2c, 0xc1, 0x18, 0xa5, 0xeb, 0xd8, 0xda, + }, + }, + { + .data_len =3D 128, + .digest =3D { + 0x90, 0x0b, 0xa6, 0x92, 0x84, 0x30, 0xaf, 0xee, + 0x38, 0x59, 0x83, 0x83, 0xe9, 0xfe, 0xab, 0x86, + 0x79, 0x1b, 0xcd, 0xe7, 0x0a, 0x0f, 0x58, 0x53, + 0x36, 0xab, 0x12, 0xe1, 0x5c, 0x97, 0xc1, 0xfb, + }, + }, + { + .data_len =3D 129, + .digest =3D { + 0x2b, 0x52, 0x1e, 0x54, 0xbe, 0x38, 0x4c, 0x3e, + 0x73, 0x37, 0x18, 0xf5, 0x25, 0x2c, 0xc8, 0xc7, + 0xda, 0x7e, 0xb6, 0x47, 0x9d, 0xf4, 0x46, 0xce, + 0xfa, 0x80, 0x20, 0x6b, 0xbd, 0xfd, 0x2a, 0xd8, + }, + }, + { + .data_len =3D 256, + .digest =3D { + 0x45, 0xf0, 0xf5, 0x9b, 0xd9, 0x91, 0x26, 0xd5, + 0x91, 0x3b, 0xf8, 0x87, 0x8b, 0x34, 0x02, 0x31, + 0x64, 0xab, 0xf4, 0x1c, 0x6e, 0x34, 0x72, 0xdf, + 0x32, 0x6d, 0xe5, 0xd2, 0x67, 0x5e, 0x86, 0x93, + }, + }, + { + .data_len =3D 511, + .digest =3D { + 0xb3, 0xaf, 0x71, 0x64, 0xfa, 0xd4, 0xf1, 0x07, + 0x38, 0xef, 0x04, 0x8e, 0x89, 0xf4, 0x02, 0xd2, + 0xa5, 0xaf, 0x3b, 0xf5, 0x67, 0x56, 0xcf, 0xa9, + 0x8e, 0x43, 0xf5, 0xb5, 0xe3, 0x91, 0x8e, 0xe7, + }, + }, + { + .data_len =3D 513, + .digest =3D { + 0x51, 0xac, 0x0a, 0x65, 0xb7, 0x96, 0x20, 0xcf, + 0x88, 0xf6, 0x97, 0x35, 0x89, 0x0d, 0x31, 0x0f, + 0xbe, 0x17, 0xbe, 0x62, 0x03, 0x67, 0xc0, 0xee, + 0x4f, 0xc1, 0xe3, 0x7f, 0x6f, 0xab, 0xac, 0xb4, + }, + }, + { + .data_len =3D 1000, + .digest =3D { + 0x7e, 0xea, 0xa8, 0xd7, 0xde, 0x20, 0x1b, 0x58, + 0x24, 0xd8, 0x26, 0x40, 0x36, 0x5f, 0x3f, 0xaa, + 0xe5, 0x5a, 0xea, 0x98, 0x58, 0xd4, 0xd6, 0xfc, + 0x20, 0x4c, 0x5c, 0x4f, 0xaf, 0x56, 0xc7, 0xc3, + }, + }, + { + .data_len =3D 3333, + .digest =3D { + 0x61, 0xb1, 0xb1, 0x3e, 0x0e, 0x7e, 0x90, 0x3d, + 0x31, 0x54, 0xbd, 0xc9, 0x0d, 0x53, 0x62, 0xf1, + 0xcd, 0x18, 0x80, 0xf9, 0x91, 0x75, 0x41, 0xb3, + 0x51, 0x39, 0x57, 0xa7, 0xa8, 0x1e, 0xfb, 0xc9, + }, + }, + { + .data_len =3D 4096, + .digest =3D { + 0xab, 0x29, 0xda, 0x10, 0xc4, 0x11, 0x2d, 0x5c, + 0xd1, 0xce, 0x1c, 0x95, 0xfa, 0xc6, 0xc7, 0xb0, + 0x1b, 0xd1, 0xdc, 0x6f, 0xa0, 0x9d, 0x1b, 0x23, + 0xfb, 0x6e, 0x90, 0x97, 0xd0, 0x75, 0x44, 0x7a, + }, + }, + { + .data_len =3D 4128, + .digest =3D { + 0x02, 0x45, 0x95, 0xf4, 0x19, 0xb5, 0x93, 0x29, + 0x90, 0xf2, 0x63, 0x3f, 0x89, 0xe8, 0xa5, 0x31, + 0x76, 0xf2, 0x89, 0x79, 0x66, 0xd3, 0x96, 0xdf, + 0x33, 0xd1, 0xa6, 0x17, 0x73, 0xb1, 0xd0, 0x45, + }, + }, + { + .data_len =3D 4160, + .digest =3D { + 0xd1, 0x8e, 0x22, 0xea, 0x44, 0x87, 0x6e, 0x9d, + 0xfb, 0x36, 0x02, 0x20, 0x63, 0xb7, 0x69, 0x45, + 0x25, 0x41, 0x69, 0xe0, 0x9b, 0x87, 0xcf, 0xa3, + 0x51, 0xbb, 0xfc, 0x8d, 0xf7, 0x29, 0xa7, 0xea, + }, + }, + { + .data_len =3D 4224, + .digest =3D { + 0x11, 0x86, 0x7d, 0x84, 0xf9, 0x8c, 0x6e, 0xc4, + 0x64, 0x36, 0xc6, 0xf3, 0x42, 0x92, 0x31, 0x2b, + 0x1e, 0x12, 0xe6, 0x4d, 0xbe, 0xfa, 0x77, 0x3f, + 0x89, 0x41, 0x33, 0x58, 0x1c, 0x98, 0x16, 0x0a, + }, + }, + { + .data_len =3D 16384, + .digest =3D { + 0xb2, 0xba, 0x0c, 0x8c, 0x9d, 0xbb, 0x1e, 0xb0, + 0x03, 0xb5, 0xdf, 0x4f, 0xf5, 0x35, 0xdb, 0xec, + 0x60, 0xf2, 0x5b, 0xb6, 0xd0, 0x49, 0xd3, 0xed, + 0x55, 0xc0, 0x7a, 0xd7, 0xaf, 0xa1, 0xea, 0x53, + }, + }, +}; + +static const u8 hash_testvec_consolidated[SHA3_256_DIGEST_SIZE] =3D { + 0x3b, 0x33, 0x67, 0xf8, 0xea, 0x92, 0x78, 0x62, + 0xdd, 0xbe, 0x72, 0x15, 0xbd, 0x6f, 0xfa, 0xe5, + 0x5e, 0xab, 0x9f, 0xb1, 0xe4, 0x23, 0x7c, 0x2c, + 0x80, 0xcf, 0x09, 0x75, 0xf8, 0xe2, 0xfa, 0x30, +}; diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-= testvecs.py index fc063f2ee95f..a5b0abd8dabe 100755 --- a/scripts/crypto/gen-hash-testvecs.py +++ b/scripts/crypto/gen-hash-testvecs.py @@ -61,6 +61,10 @@ def hash_update(ctx, data): ctx.update(data) =20 def hash_final(ctx): + if ctx.name =3D=3D "shake_128": + return ctx.digest(16) + if ctx.name =3D=3D "shake_256": + return ctx.digest(32) return ctx.digest() =20 def compute_hash(alg, data): @@ -122,7 +126,7 @@ def gen_hmac_testvecs(alg): ctx.update(mac) print_static_u8_array_definition( f'hmac_testvec_consolidated[{alg.upper()}_DIGEST_SIZE]', - ctx.digest()) + hash_final(ctx)) =20 BLAKE2S_KEY_SIZE =3D 32 BLAKE2S_HASH_SIZE =3D 32 @@ -164,5 +168,5 @@ if alg =3D=3D 'blake2s': gen_additional_blake2s_testvecs() elif alg =3D=3D 'poly1305': gen_additional_poly1305_testvecs() -else: +elif alg !=3D 'shake128' and alg !=3D 'shake256': gen_hmac_testvecs(alg) From nobody Wed Oct 1 22:33:17 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C9E2A302176 for ; Fri, 26 Sep 2025 14:20:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896441; cv=none; b=UENvSF29raAgrxUcLWzv7JpAXqQBLPZBiPRl1pVohm5kh7zNmBzo7mmKHAbpM/VhWYnJZYpzZj/UrTXFC3ZNSlsHMUymKIRtlzAWgRyjNH/WWxerRWcZALXwQdBwanQIp6SBJ+PuUG/Gb9eRdKGibmngHHvI2/X7Ayr45nd+YnA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896441; c=relaxed/simple; bh=gEmtJX2boAjTH7pg8qkCqbmv3qDYkIFzPpRG4+BI1pQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=exQrhn594/WdfRCD6BcG5HtCmwr8RXVJWqhASUmdZMJmo+rKaqoDk5TR7OhpEe5K1ifb8874qN+wx0Al4c21/yaCZf+e/E4j1eHRiZqTZu96b6HouLQwKElOoIYRhkCTESPo8RVuKfE6FCeqAUOoqJGc4O/lVYjd+uCXbDlw7hE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=hIO4rQEy; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="hIO4rQEy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758896437; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=niM2zll9qN3FE5+Kw/1evuO7pOFd4rYAY/Rez06/6Qk=; b=hIO4rQEymtimLsDjFQKxNcvIjn4h11ddMZRxancYqFgexQRMGYI29YqkdfewOJN54qvEOl d+gb+VkvSRvhVucWSHGxM47Toi6amK5V9D7CGTQwapVZejlJvVjYRr5t1KotCoSVvwyQIg khjaAS+wf4J1W6B6+UUJsUYWyOBkGmE= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-639-KJlWO5JEMZSaBvAxBZjHyg-1; Fri, 26 Sep 2025 10:20:34 -0400 X-MC-Unique: KJlWO5JEMZSaBvAxBZjHyg-1 X-Mimecast-MFC-AGG-ID: KJlWO5JEMZSaBvAxBZjHyg_1758896433 Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1BFEE1800295; Fri, 26 Sep 2025 14:20:33 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.155]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 843B919560A2; Fri, 26 Sep 2025 14:20:30 +0000 (UTC) From: David Howells To: Cc: David Howells , Eric Biggers , "Jason A . Donenfeld" , Ard Biesheuvel , Herbert Xu , Stephan Mueller , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 6/8] crypto/sha3: Use lib/crypto/sha3 Date: Fri, 26 Sep 2025 15:19:49 +0100 Message-ID: <20250926141959.1272455-7-dhowells@redhat.com> In-Reply-To: <20250926141959.1272455-1-dhowells@redhat.com> References: <20250926141959.1272455-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 Content-Type: text/plain; charset="utf-8" Switch crypto/sha3_generic.c to use lib/crypto/sha3. Note that this makes use of the internal general API rather implementing a separate set of init/update/finup handlers for each algorithm. Signed-off-by: David Howells cc: Eric Biggers cc: Jason A. Donenfeld cc: Ard Biesheuvel cc: Herbert Xu cc: Stephan Mueller cc: linux-crypto@vger.kernel.org --- Documentation/crypto/sha3.rst | 8 +- arch/arm64/crypto/sha3-ce-glue.c | 25 ++-- crypto/sha3_generic.c | 201 +++---------------------------- include/crypto/sha3.h | 6 +- lib/crypto/sha3.c | 35 +++--- 5 files changed, 52 insertions(+), 223 deletions(-) diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst index ae4902895882..82c9abe45614 100644 --- a/Documentation/crypto/sha3.rst +++ b/Documentation/crypto/sha3.rst @@ -157,7 +157,7 @@ further algorithms or APIs as the engine in the same in= all cases. The algorithm APIs all wrap the common context structure:: =20 struct sha3_ctx { - struct sha3_state state; + u64 st[SHA3_STATE_SIZE / 8]; u8 block_size; u8 padding; u8 absorb_offset; @@ -165,13 +165,9 @@ algorithm APIs all wrap the common context structure:: bool end_marked; }; =20 - struct sha3_state { - u64 st[SHA3_STATE_SIZE / 8]; - }; - The fields are as follows: =20 - * ``state.st`` + * ``st`` =20 An array of 25 64-bit state buckets that are used to hold the mathemati= cal state of the Keccak engine. Data is XOR'd onto part of this, the engin= e is diff --git a/arch/arm64/crypto/sha3-ce-glue.c b/arch/arm64/crypto/sha3-ce-g= lue.c index 426d8044535a..f6cdff4cd103 100644 --- a/arch/arm64/crypto/sha3-ce-glue.c +++ b/arch/arm64/crypto/sha3-ce-glue.c @@ -28,13 +28,18 @@ MODULE_ALIAS_CRYPTO("sha3-256"); MODULE_ALIAS_CRYPTO("sha3-384"); MODULE_ALIAS_CRYPTO("sha3-512"); =20 +static struct sha3_ctx *crypto_sha3_desc(struct shash_desc *desc) +{ + return shash_desc_ctx(desc); +} + asmlinkage int sha3_ce_transform(u64 *st, const u8 *data, int blocks, int md_len); =20 static int arm64_sha3_update(struct shash_desc *desc, const u8 *data, unsigned int len) { - struct sha3_state *sctx =3D shash_desc_ctx(desc); + struct sha3_ctx *ctx =3D crypto_sha3_desc(desc); struct crypto_shash *tfm =3D desc->tfm; unsigned int bs, ds; int blocks; @@ -47,7 +52,7 @@ static int arm64_sha3_update(struct shash_desc *desc, con= st u8 *data, int rem; =20 kernel_neon_begin(); - rem =3D sha3_ce_transform(sctx->st, data, blocks, ds); + rem =3D sha3_ce_transform(ctx->state.st, data, blocks, ds); kernel_neon_end(); data +=3D (blocks - rem) * bs; blocks =3D rem; @@ -58,7 +63,7 @@ static int arm64_sha3_update(struct shash_desc *desc, con= st u8 *data, static int arm64_sha3_finup(struct shash_desc *desc, const u8 *src, unsign= ed int len, u8 *out) { - struct sha3_state *sctx =3D shash_desc_ctx(desc); + struct sha3_ctx *ctx =3D crypto_sha3_desc(desc); struct crypto_shash *tfm =3D desc->tfm; __le64 *digest =3D (__le64 *)out; u8 block[SHA3_224_BLOCK_SIZE]; @@ -74,15 +79,15 @@ static int arm64_sha3_finup(struct shash_desc *desc, co= nst u8 *src, unsigned int block[bs - 1] |=3D 0x80; =20 kernel_neon_begin(); - sha3_ce_transform(sctx->st, block, 1, ds); + sha3_ce_transform(sctx->state.st, block, 1, ds); kernel_neon_end(); memzero_explicit(block , sizeof(block)); =20 for (i =3D 0; i < ds / 8; i++) - put_unaligned_le64(sctx->st[i], digest++); + put_unaligned_le64(sctx->state.st[i], digest++); =20 if (ds & 4) - put_unaligned_le32(sctx->st[i], (__le32 *)digest); + put_unaligned_le32(sctx->state.st[i], (__le32 *)digest); =20 return 0; } @@ -92,7 +97,7 @@ static struct shash_alg algs[] =3D { { .init =3D crypto_sha3_init, .update =3D arm64_sha3_update, .finup =3D arm64_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, + .descsize =3D sizeof(struct sha3_ctx), .base.cra_name =3D "sha3-224", .base.cra_driver_name =3D "sha3-224-ce", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, @@ -104,7 +109,7 @@ static struct shash_alg algs[] =3D { { .init =3D crypto_sha3_init, .update =3D arm64_sha3_update, .finup =3D arm64_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, + .descsize =3D sizeof(struct sha3_ctx), .base.cra_name =3D "sha3-256", .base.cra_driver_name =3D "sha3-256-ce", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, @@ -116,7 +121,7 @@ static struct shash_alg algs[] =3D { { .init =3D crypto_sha3_init, .update =3D arm64_sha3_update, .finup =3D arm64_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, + .descsize =3D sizeof(struct sha3_ctx), .base.cra_name =3D "sha3-384", .base.cra_driver_name =3D "sha3-384-ce", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, @@ -128,7 +133,7 @@ static struct shash_alg algs[] =3D { { .init =3D crypto_sha3_init, .update =3D arm64_sha3_update, .finup =3D arm64_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, + .descsize =3D sizeof(struct sha3_ctx), .base.cra_name =3D "sha3-512", .base.cra_driver_name =3D "sha3-512-ce", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c index 41d1e506e6de..6917a1aeb8e5 100644 --- a/crypto/sha3_generic.c +++ b/crypto/sha3_generic.c @@ -13,156 +13,19 @@ #include #include #include -#include =20 -/* - * On some 32-bit architectures (h8300), GCC ends up using - * over 1 KB of stack if we inline the round calculation into the loop - * in keccakf(). On the other hand, on 64-bit architectures with plenty - * of [64-bit wide] general purpose registers, not inlining it severely - * hurts performance. So let's use 64-bitness as a heuristic to decide - * whether to inline or not. - */ -#ifdef CONFIG_64BIT -#define SHA3_INLINE inline -#else -#define SHA3_INLINE noinline -#endif - -#define KECCAK_ROUNDS 24 - -static const u64 keccakf_rndc[24] =3D { - 0x0000000000000001ULL, 0x0000000000008082ULL, 0x800000000000808aULL, - 0x8000000080008000ULL, 0x000000000000808bULL, 0x0000000080000001ULL, - 0x8000000080008081ULL, 0x8000000000008009ULL, 0x000000000000008aULL, - 0x0000000000000088ULL, 0x0000000080008009ULL, 0x000000008000000aULL, - 0x000000008000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, - 0x8000000000008003ULL, 0x8000000000008002ULL, 0x8000000000000080ULL, - 0x000000000000800aULL, 0x800000008000000aULL, 0x8000000080008081ULL, - 0x8000000000008080ULL, 0x0000000080000001ULL, 0x8000000080008008ULL -}; - -/* update the state with given number of rounds */ - -static SHA3_INLINE void keccakf_round(u64 st[25]) -{ - u64 t[5], tt, bc[5]; - - /* Theta */ - bc[0] =3D st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20]; - bc[1] =3D st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21]; - bc[2] =3D st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22]; - bc[3] =3D st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23]; - bc[4] =3D st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24]; - - t[0] =3D bc[4] ^ rol64(bc[1], 1); - t[1] =3D bc[0] ^ rol64(bc[2], 1); - t[2] =3D bc[1] ^ rol64(bc[3], 1); - t[3] =3D bc[2] ^ rol64(bc[4], 1); - t[4] =3D bc[3] ^ rol64(bc[0], 1); - - st[0] ^=3D t[0]; - - /* Rho Pi */ - tt =3D st[1]; - st[ 1] =3D rol64(st[ 6] ^ t[1], 44); - st[ 6] =3D rol64(st[ 9] ^ t[4], 20); - st[ 9] =3D rol64(st[22] ^ t[2], 61); - st[22] =3D rol64(st[14] ^ t[4], 39); - st[14] =3D rol64(st[20] ^ t[0], 18); - st[20] =3D rol64(st[ 2] ^ t[2], 62); - st[ 2] =3D rol64(st[12] ^ t[2], 43); - st[12] =3D rol64(st[13] ^ t[3], 25); - st[13] =3D rol64(st[19] ^ t[4], 8); - st[19] =3D rol64(st[23] ^ t[3], 56); - st[23] =3D rol64(st[15] ^ t[0], 41); - st[15] =3D rol64(st[ 4] ^ t[4], 27); - st[ 4] =3D rol64(st[24] ^ t[4], 14); - st[24] =3D rol64(st[21] ^ t[1], 2); - st[21] =3D rol64(st[ 8] ^ t[3], 55); - st[ 8] =3D rol64(st[16] ^ t[1], 45); - st[16] =3D rol64(st[ 5] ^ t[0], 36); - st[ 5] =3D rol64(st[ 3] ^ t[3], 28); - st[ 3] =3D rol64(st[18] ^ t[3], 21); - st[18] =3D rol64(st[17] ^ t[2], 15); - st[17] =3D rol64(st[11] ^ t[1], 10); - st[11] =3D rol64(st[ 7] ^ t[2], 6); - st[ 7] =3D rol64(st[10] ^ t[0], 3); - st[10] =3D rol64( tt ^ t[1], 1); - - /* Chi */ - bc[ 0] =3D ~st[ 1] & st[ 2]; - bc[ 1] =3D ~st[ 2] & st[ 3]; - bc[ 2] =3D ~st[ 3] & st[ 4]; - bc[ 3] =3D ~st[ 4] & st[ 0]; - bc[ 4] =3D ~st[ 0] & st[ 1]; - st[ 0] ^=3D bc[ 0]; - st[ 1] ^=3D bc[ 1]; - st[ 2] ^=3D bc[ 2]; - st[ 3] ^=3D bc[ 3]; - st[ 4] ^=3D bc[ 4]; - - bc[ 0] =3D ~st[ 6] & st[ 7]; - bc[ 1] =3D ~st[ 7] & st[ 8]; - bc[ 2] =3D ~st[ 8] & st[ 9]; - bc[ 3] =3D ~st[ 9] & st[ 5]; - bc[ 4] =3D ~st[ 5] & st[ 6]; - st[ 5] ^=3D bc[ 0]; - st[ 6] ^=3D bc[ 1]; - st[ 7] ^=3D bc[ 2]; - st[ 8] ^=3D bc[ 3]; - st[ 9] ^=3D bc[ 4]; - - bc[ 0] =3D ~st[11] & st[12]; - bc[ 1] =3D ~st[12] & st[13]; - bc[ 2] =3D ~st[13] & st[14]; - bc[ 3] =3D ~st[14] & st[10]; - bc[ 4] =3D ~st[10] & st[11]; - st[10] ^=3D bc[ 0]; - st[11] ^=3D bc[ 1]; - st[12] ^=3D bc[ 2]; - st[13] ^=3D bc[ 3]; - st[14] ^=3D bc[ 4]; - - bc[ 0] =3D ~st[16] & st[17]; - bc[ 1] =3D ~st[17] & st[18]; - bc[ 2] =3D ~st[18] & st[19]; - bc[ 3] =3D ~st[19] & st[15]; - bc[ 4] =3D ~st[15] & st[16]; - st[15] ^=3D bc[ 0]; - st[16] ^=3D bc[ 1]; - st[17] ^=3D bc[ 2]; - st[18] ^=3D bc[ 3]; - st[19] ^=3D bc[ 4]; - - bc[ 0] =3D ~st[21] & st[22]; - bc[ 1] =3D ~st[22] & st[23]; - bc[ 2] =3D ~st[23] & st[24]; - bc[ 3] =3D ~st[24] & st[20]; - bc[ 4] =3D ~st[20] & st[21]; - st[20] ^=3D bc[ 0]; - st[21] ^=3D bc[ 1]; - st[22] ^=3D bc[ 2]; - st[23] ^=3D bc[ 3]; - st[24] ^=3D bc[ 4]; -} - -static void keccakf(u64 st[25]) +static struct sha3_ctx *crypto_sha3_desc(struct shash_desc *desc) { - int round; - - for (round =3D 0; round < KECCAK_ROUNDS; round++) { - keccakf_round(st); - /* Iota */ - st[0] ^=3D keccakf_rndc[round]; - } + return shash_desc_ctx(desc); } =20 int crypto_sha3_init(struct shash_desc *desc) { - struct sha3_state *sctx =3D shash_desc_ctx(desc); + struct sha3_ctx *ctx =3D crypto_sha3_desc(desc); =20 - memset(sctx->st, 0, sizeof(sctx->st)); + memset(ctx, 0, sizeof(*ctx)); + ctx->block_size =3D crypto_shash_blocksize(desc->tfm); + ctx->padding =3D 0x06; return 0; } EXPORT_SYMBOL(crypto_sha3_init); @@ -170,51 +33,21 @@ EXPORT_SYMBOL(crypto_sha3_init); static int crypto_sha3_update(struct shash_desc *desc, const u8 *data, unsigned int len) { - unsigned int rsiz =3D crypto_shash_blocksize(desc->tfm); - struct sha3_state *sctx =3D shash_desc_ctx(desc); - unsigned int rsizw =3D rsiz / 8; - - do { - int i; + struct sha3_ctx *ctx =3D crypto_sha3_desc(desc); =20 - for (i =3D 0; i < rsizw; i++) - sctx->st[i] ^=3D get_unaligned_le64(data + 8 * i); - keccakf(sctx->st); - - data +=3D rsiz; - len -=3D rsiz; - } while (len >=3D rsiz); + sha3_update(ctx, data, len); return len; } =20 static int crypto_sha3_finup(struct shash_desc *desc, const u8 *src, unsigned int len, u8 *out) { - unsigned int digest_size =3D crypto_shash_digestsize(desc->tfm); - unsigned int rsiz =3D crypto_shash_blocksize(desc->tfm); - struct sha3_state *sctx =3D shash_desc_ctx(desc); - __le64 block[SHA3_224_BLOCK_SIZE / 8] =3D {}; - __le64 *digest =3D (__le64 *)out; - unsigned int rsizw =3D rsiz / 8; - u8 *p; - int i; - - p =3D memcpy(block, src, len); - p[len++] =3D 0x06; - p[rsiz - 1] |=3D 0x80; - - for (i =3D 0; i < rsizw; i++) - sctx->st[i] ^=3D le64_to_cpu(block[i]); - memzero_explicit(block, sizeof(block)); - - keccakf(sctx->st); - - for (i =3D 0; i < digest_size / 8; i++) - put_unaligned_le64(sctx->st[i], digest++); - - if (digest_size & 4) - put_unaligned_le32(sctx->st[i], (__le32 *)digest); + struct sha3_ctx *ctx =3D crypto_sha3_desc(desc); =20 + if (len && src) + sha3_update(ctx, src, len); + sha3_squeeze(ctx, out, crypto_shash_digestsize(desc->tfm)); + sha3_clear(ctx); return 0; } =20 @@ -223,7 +56,7 @@ static struct shash_alg algs[] =3D { { .init =3D crypto_sha3_init, .update =3D crypto_sha3_update, .finup =3D crypto_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, + .descsize =3D sizeof(struct sha3_ctx), .base.cra_name =3D "sha3-224", .base.cra_driver_name =3D "sha3-224-generic", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, @@ -234,7 +67,7 @@ static struct shash_alg algs[] =3D { { .init =3D crypto_sha3_init, .update =3D crypto_sha3_update, .finup =3D crypto_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, + .descsize =3D sizeof(struct sha3_ctx), .base.cra_name =3D "sha3-256", .base.cra_driver_name =3D "sha3-256-generic", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, @@ -245,7 +78,7 @@ static struct shash_alg algs[] =3D { { .init =3D crypto_sha3_init, .update =3D crypto_sha3_update, .finup =3D crypto_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, + .descsize =3D sizeof(struct sha3_ctx), .base.cra_name =3D "sha3-384", .base.cra_driver_name =3D "sha3-384-generic", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, @@ -256,7 +89,7 @@ static struct shash_alg algs[] =3D { { .init =3D crypto_sha3_init, .update =3D crypto_sha3_update, .finup =3D crypto_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, + .descsize =3D sizeof(struct sha3_ctx), .base.cra_name =3D "sha3-512", .base.cra_driver_name =3D "sha3-512-generic", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h index 41bc211afa0b..183261995fa1 100644 --- a/include/crypto/sha3.h +++ b/include/crypto/sha3.h @@ -38,10 +38,6 @@ =20 struct shash_desc; =20 -struct sha3_state { - u64 st[SHA3_STATE_SIZE / 8]; -}; - /* * The SHA3 context structure and state buffer. * @@ -52,7 +48,7 @@ struct sha3_state { * byteswap step is a no-op. */ struct sha3_ctx { - struct sha3_state state; + u64 st[SHA3_STATE_SIZE / 8]; u8 block_size; /* Block size in bytes */ u8 padding; /* Padding byte */ u8 absorb_offset; /* Next state byte to absorb into */ diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index 227d45bd9680..398669c4d7ca 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -48,10 +48,10 @@ static const u64 sha3_keccakf_rndc[24] =3D { /* * Perform a single round of Keccak mixing. */ -static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_state *= state, +static SHA3_INLINE void sha3_keccakf_one_round_generic(struct sha3_ctx *ct= x, int round) { - u64 *st =3D state->st; + u64 *st =3D ctx->st; u64 t[5], tt, bc[5]; =20 /* Theta */ @@ -153,13 +153,13 @@ static SHA3_INLINE void sha3_keccakf_one_round_generi= c(struct sha3_state *state, st[24] ^=3D bc[ 4]; =20 /* Iota */ - state->st[0] ^=3D sha3_keccakf_rndc[round]; + ctx->st[0] ^=3D sha3_keccakf_rndc[round]; } =20 -static void sha3_keccakf_rounds_generic(struct sha3_state *state) +static void sha3_keccakf_rounds_generic(struct sha3_ctx *ctx) { for (int round =3D 0; round < SHA3_KECCAK_ROUNDS; round++) - sha3_keccakf_one_round_generic(state, round); + sha3_keccakf_one_round_generic(ctx, round); } =20 /* @@ -167,25 +167,24 @@ static void sha3_keccakf_rounds_generic(struct sha3_s= tate *state) * machine for the duration of the Keccak mixing function. Note that these * loops are no-ops on LE machines and will be optimised away. */ -static void sha3_keccakf_generic(struct sha3_state *state) +static void sha3_keccakf_generic(struct sha3_ctx *ctx) { - for (int i =3D 0; i < ARRAY_SIZE(state->st); i++) - cpu_to_le64s(&state->st[i]); + for (int i =3D 0; i < ARRAY_SIZE(ctx->st); i++) + cpu_to_le64s(&ctx->st[i]); =20 - sha3_keccakf_rounds_generic(state); + sha3_keccakf_rounds_generic(ctx); =20 - for (int i =3D 0; i < ARRAY_SIZE(state->st); i++) - le64_to_cpus(&state->st[i]); + for (int i =3D 0; i < ARRAY_SIZE(ctx->st); i++) + le64_to_cpus(&ctx->st[i]); } =20 static void sha3_absorb_block_generic(struct sha3_ctx *ctx, const u8 *data) { - struct sha3_state *state =3D &ctx->state; unsigned int bsize =3D ctx->block_size; =20 for (int i =3D 0; i < bsize / 8; i++) - state->st[i] ^=3D get_unaligned((u64 *)(data + 8 * i)); - sha3_keccakf_generic(state); + ctx->st[i] ^=3D get_unaligned((u64 *)(data + 8 * i)); + sha3_keccakf_generic(ctx); } =20 /* @@ -214,7 +213,7 @@ static void sha3_absorb_blocks_generic(struct sha3_ctx = *ctx, static void sha3_absorb_xorle(struct sha3_ctx *ctx, const u8 *data, unsigned int partial, unsigned int len) { - u8 *buf =3D (u8 *)ctx->state.st; + u8 *buf =3D (u8 *)ctx->st; =20 buf +=3D partial; for (int i =3D 0; i < len; i++) @@ -245,7 +244,7 @@ void sha3_update(struct sha3_ctx *ctx, const u8 *data, = unsigned int len) sha3_absorb_xorle(ctx, data, absorb_offset, bsize - absorb_offset); len -=3D bsize - absorb_offset; data +=3D bsize - absorb_offset; - sha3_keccakf(&ctx->state); + sha3_keccakf(ctx); ctx->absorb_offset =3D 0; } =20 @@ -286,7 +285,7 @@ void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t= out_size) { unsigned int squeeze_offset =3D ctx->squeeze_offset; unsigned int bsize =3D ctx->block_size; - u8 *p =3D (u8 *)ctx->state.st, end_marker =3D 0x80; + u8 *p =3D (u8 *)ctx->st, end_marker =3D 0x80; =20 if (!ctx->end_marked) { sha3_absorb_xorle(ctx, &ctx->padding, ctx->absorb_offset, 1); @@ -296,7 +295,7 @@ void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t= out_size) =20 for (;;) { if (squeeze_offset =3D=3D 0) - sha3_keccakf(&ctx->state); + sha3_keccakf(ctx); =20 unsigned int part =3D umin(out_size, bsize - squeeze_offset); From nobody Wed Oct 1 22:33:17 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 637E3305964 for ; Fri, 26 Sep 2025 14:20:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896459; cv=none; b=Jk5jVhQuc2VhBK5nMdsjM30zII0L/9XBPrICWlPu9HYxh00d43X2M1BejaFx88O1loj/ZpCv+KlZHtSkG+KbL0lmjON03HJtJDBoXCfUpPJUcCrqONiHxLAR2UwXIZJuBOomq1yiKu5h5cNfsULz0hzFle20T1TRkUmAM5ae93w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896459; c=relaxed/simple; bh=kqqGOhpz0a/MgJMid5qITPh41468A2ybGVrDemtdS4s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=AtDTZ5TMzoUJd32orOl686HFRvqxxwAgjAVI7nXbIgfPzGQfQoXPibcvYNeb6ys1mBZ7qZTjE5e8UPGnGK/sjNOeT6vWaBaZL2PTbeJQmd+ej/VyQz1MxPPOmaeMd8HeOL8IVi3toBa4Ueh6x4ZnJJc8lau/nTsB78grk4gn5E8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=LuiEYZjP; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="LuiEYZjP" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758896456; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yV37y+MHgEeU8QeaEoc7GtsZWjYLys4curv5++kbhTw=; b=LuiEYZjPr8ECoceR1XqEwfH6P14cNmBXDk7F8ws2jaAR/VFc7eEyNc+UcpHzX64/igVVE2 BqJnlCwwA6n4aiYKYSXwVDPtfDW8mN/0a5cDUY2KzpdDJqR3xNrhAvq9bQ3mEl2Wzl567k 43+WyyZRPfMlLNG5Gvlnb7wycaCYd7E= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-45-P1B5m6TmMwasNz--h5L-dA-1; Fri, 26 Sep 2025 10:20:45 -0400 X-MC-Unique: P1B5m6TmMwasNz--h5L-dA-1 X-Mimecast-MFC-AGG-ID: P1B5m6TmMwasNz--h5L-dA_1758896436 Received: from mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.111]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C3E42180057E; Fri, 26 Sep 2025 14:20:36 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.155]) by mx-prod-int-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9D86E1800982; Fri, 26 Sep 2025 14:20:34 +0000 (UTC) From: David Howells To: Cc: David Howells , Eric Biggers , "Jason A . Donenfeld" , Ard Biesheuvel , Herbert Xu , Stephan Mueller , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 7/8] crypto/sha3: Add SHAKE128/256 support Date: Fri, 26 Sep 2025 15:19:50 +0100 Message-ID: <20250926141959.1272455-8-dhowells@redhat.com> In-Reply-To: <20250926141959.1272455-1-dhowells@redhat.com> References: <20250926141959.1272455-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.111 Content-Type: text/plain; charset="utf-8" SHAKE128/256 'digest' algos need to be available for the ML-DSA pre-digest, which is a selectable algorithm and need to be available through the same API as, say, SHA3-512 and SHA512 both. Resqueezability (probably) isn't required for this and they'll produce the default number of bytes as the digest size. Signed-off-by: David Howells cc: Eric Biggers cc: Jason A. Donenfeld cc: Ard Biesheuvel cc: Herbert Xu cc: Stephan Mueller cc: linux-crypto@vger.kernel.org --- crypto/sha3_generic.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c index 6917a1aeb8e5..4fae066ec3f5 100644 --- a/crypto/sha3_generic.c +++ b/crypto/sha3_generic.c @@ -95,6 +95,28 @@ static struct shash_alg algs[] =3D { { .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, .base.cra_blocksize =3D SHA3_512_BLOCK_SIZE, .base.cra_module =3D THIS_MODULE, +}, { + .digestsize =3D SHAKE128_DEFAULT_SIZE, + .init =3D crypto_sha3_init, + .update =3D crypto_sha3_update, + .finup =3D crypto_sha3_finup, + .descsize =3D sizeof(struct sha3_ctx), + .base.cra_name =3D "shake128", + .base.cra_driver_name =3D "shake128-generic", + .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, + .base.cra_blocksize =3D SHAKE128_BLOCK_SIZE, + .base.cra_module =3D THIS_MODULE, +}, { + .digestsize =3D SHAKE256_DEFAULT_SIZE, + .init =3D crypto_sha3_init, + .update =3D crypto_sha3_update, + .finup =3D crypto_sha3_finup, + .descsize =3D sizeof(struct sha3_ctx), + .base.cra_name =3D "shake256", + .base.cra_driver_name =3D "shake256-generic", + .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, + .base.cra_blocksize =3D SHAKE256_BLOCK_SIZE, + .base.cra_module =3D THIS_MODULE, } }; =20 static int __init sha3_generic_mod_init(void) @@ -121,3 +143,7 @@ MODULE_ALIAS_CRYPTO("sha3-384"); MODULE_ALIAS_CRYPTO("sha3-384-generic"); MODULE_ALIAS_CRYPTO("sha3-512"); MODULE_ALIAS_CRYPTO("sha3-512-generic"); +MODULE_ALIAS_CRYPTO("shake128"); +MODULE_ALIAS_CRYPTO("shake128-generic"); +MODULE_ALIAS_CRYPTO("shake256"); +MODULE_ALIAS_CRYPTO("shake256-generic"); From nobody Wed Oct 1 22:33:17 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8BBD81FE45A for ; Fri, 26 Sep 2025 14:20:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896448; cv=none; b=RsgKbCjXzwLKDJ4f8N1Rsbg/n5Ian8edfxyVvVhJS8gZ4QqxB0AVuKgdjOQq33Uae+JwLsr4XJELt0eOQX8S0dLIRJ5NBsO1hwF4vfTSOkwCP8fpwbJwFexbZ3YFYywy4WY4oNnA8q8QiJBFmUMivNgq8+JF09FWPNDm8a08UrA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1758896448; c=relaxed/simple; bh=ySiSiNeZc9FNWHxIUaJv0xF7RkGpsemiZKhULj53bSc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e4Zh65tMYst3EQBy5i1QJf+Gld9BuInHHRsYzZN1ChTbO1i6b7DeHLxWNoanDpvcVVEmO+Ngr3L7MrHIAxvrmtmIXaEzhcK470TnDl1eGCBUcFXgXLYH1dAvzVhvkfVlpGTuTx4irnJIBlSDupZGhEahcGAu5Vz5C44+q/jpwfQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=YajRShO8; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="YajRShO8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1758896445; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=4KUnTBzsGr+xU5+H4r3Ghz1bUcQIQV9Qsi5HH5seaJo=; b=YajRShO8KohJGtTOHgnvG9bS4KgUpNOtCBR9xZBMQ9e89+FRqAfcQMI6Y3DUCZf9WyI8T3 mVUw6jzT3adu6dVFF/z2VdEJYeiwiLFBeiYtStwnFa1jnurNCUUAeWsc3eIxgszJkYl9DV vjC97Mw4o1ey/ps3bFPPwc3x0P1g288= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-482-TIP_uSxTMn2bVX1ho6DLow-1; Fri, 26 Sep 2025 10:20:42 -0400 X-MC-Unique: TIP_uSxTMn2bVX1ho6DLow-1 X-Mimecast-MFC-AGG-ID: TIP_uSxTMn2bVX1ho6DLow_1758896440 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id C3BFC1800378; Fri, 26 Sep 2025 14:20:40 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.155]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 86FC1180141C; Fri, 26 Sep 2025 14:20:38 +0000 (UTC) From: David Howells To: Cc: David Howells , Eric Biggers , "Jason A . Donenfeld" , Ard Biesheuvel , Herbert Xu , Stephan Mueller , linux-crypto@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v3 8/8] crypto: SHAKE tests Date: Fri, 26 Sep 2025 15:19:51 +0100 Message-ID: <20250926141959.1272455-9-dhowells@redhat.com> In-Reply-To: <20250926141959.1272455-1-dhowells@redhat.com> References: <20250926141959.1272455-1-dhowells@redhat.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" --- crypto/sha3_generic.c | 14 ++++++++-- crypto/testmgr.c | 14 ++++++++++ crypto/testmgr.h | 59 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 2 deletions(-) diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c index 4fae066ec3f5..61ba1cf6eadb 100644 --- a/crypto/sha3_generic.c +++ b/crypto/sha3_generic.c @@ -30,6 +30,16 @@ int crypto_sha3_init(struct shash_desc *desc) } EXPORT_SYMBOL(crypto_sha3_init); =20 +static int crypto_shake_init(struct shash_desc *desc) +{ + struct sha3_ctx *ctx =3D crypto_sha3_desc(desc); + + memset(ctx, 0, sizeof(*ctx)); + ctx->block_size =3D crypto_shash_blocksize(desc->tfm); + ctx->padding =3D 0x1f; + return 0; +} + static int crypto_sha3_update(struct shash_desc *desc, const u8 *data, unsigned int len) { @@ -97,7 +107,7 @@ static struct shash_alg algs[] =3D { { .base.cra_module =3D THIS_MODULE, }, { .digestsize =3D SHAKE128_DEFAULT_SIZE, - .init =3D crypto_sha3_init, + .init =3D crypto_shake_init, .update =3D crypto_sha3_update, .finup =3D crypto_sha3_finup, .descsize =3D sizeof(struct sha3_ctx), @@ -108,7 +118,7 @@ static struct shash_alg algs[] =3D { { .base.cra_module =3D THIS_MODULE, }, { .digestsize =3D SHAKE256_DEFAULT_SIZE, - .init =3D crypto_sha3_init, + .init =3D crypto_shake_init, .update =3D crypto_sha3_update, .finup =3D crypto_sha3_finup, .descsize =3D sizeof(struct sha3_ctx), diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 9dca41e7ee73..988bda74371e 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -5511,6 +5511,20 @@ static const struct alg_test_desc alg_test_descs[] = =3D { .suite =3D { .hash =3D __VECS(sha512_tv_template) } + }, { + .alg =3D "shake128", + .test =3D alg_test_hash, + .fips_allowed =3D 1, + .suite =3D { + .hash =3D __VECS(shake128_tv_template) + } + }, { + .alg =3D "shake256", + .test =3D alg_test_hash, + .fips_allowed =3D 1, + .suite =3D { + .hash =3D __VECS(shake256_tv_template) + } }, { .alg =3D "sm3", .test =3D alg_test_hash, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 268231227282..c0eca7f72aa0 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -4690,6 +4690,65 @@ static const struct hash_testvec sha3_512_tv_templat= e[] =3D { }; =20 =20 +/* From: https://csrc.nist.gov/projects/cryptographic-standards-and-guidel= ines/example-values */ +static const struct hash_testvec shake128_tv_template[] =3D { + { + .plaintext =3D "", + .psize =3D 0, + .digest =3D + "\x7f\x9c\x2b\xa4\xe8\x8f\x82\x7d\x61\x60\x45\x50\x76\x05\x85\x3e", + }, { + .plaintext =3D + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3", + .psize =3D 200, + .digest =3D + "\x13\x1a\xb8\xd2\xb5\x94\x94\x6b\x9c\x81\x33\x3f\x9b\xb6\xe0\xce", + } +}; + +/* From: https://csrc.nist.gov/projects/cryptographic-standards-and-guidel= ines/example-values */ +static const struct hash_testvec shake256_tv_template[] =3D { + { + .plaintext =3D "", + .psize =3D 0, + .digest =3D + "\x46\xb9\xdd\x2b\x0b\xa8\x8d\x13\x23\x3b\x3f\xeb\x74\x3e\xeb\x24" + "\x3f\xcd\x52\xea\x62\xb8\x1b\x82\xb5\x0c\x27\x64\x6e\xd5\x76\x2f" + }, { + .plaintext =3D + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3" + "\xa3\xa3\xa3\xa3\xa3\xa3\xa3\xa3", + .psize =3D 200, + .digest =3D + "\xcd\x8a\x92\x0e\xd1\x41\xaa\x04\x07\xa2\x2d\x59\x28\x86\x52\xe9" + "\xd9\xf1\xa7\xee\x0c\x1e\x7c\x1c\xa6\x99\x42\x4d\xa8\x4a\x90\x4d", + } +}; + + /* * MD5 test vectors from RFC1321 */