From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A6B18191F9C; Mon, 20 Oct 2025 00:53:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921612; cv=none; b=URITJsuWDWVxsAMrNWcPIyKk8dPyuWbt5xeleJsCxxsA/8fB35GU558uXPeT5n3xJCsLBMKGeTHsr3ACWw0rSI2g8qijMG08Yl/EvtFy5P/vo+8Xl5OuQUCFVs+nb8NWEbzVD9LsiwhML2W22+Xe1Li9IyarALKylrYpPScHIRM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921612; c=relaxed/simple; bh=Y9Gh5NX+Xkq+eNV4N4mdP/PaI0Z1KJcE1oP/YqXj9K4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pkYS2+DWF8m4bsvIGz44JXDs0H2j4A9J0UgpKpkCtTfx5bUa9+F38yUD39n1y59C/fFEN28dooYV3xoJ/EqkIq9Wy0/wvcjl008j7Cfa1Wfo14iM97b36P5X1wgTdepCgZ7xE7mgrFIDFwstfGKMD7Pr/3gS65fgxpzrV9SHTT8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NBOZRs3E; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NBOZRs3E" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D3551C4AF09; Mon, 20 Oct 2025 00:53:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921612; bh=Y9Gh5NX+Xkq+eNV4N4mdP/PaI0Z1KJcE1oP/YqXj9K4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NBOZRs3E1gzSfg8V/39IG+n9ZwkE5r4um/mONt1VG59Z72gZiYvq58iD3U056ONN/ LwL4JQiL/xjwShE9dXDUeVVnBtzcldXunITVcYU7JHlEnq3e5gfhkCTcW0XRCDqeU9 3KWzvkRHwhRJgNEdHkIuAUIlw2vDAJx/LEOH6ll6Yt5vihODVzZ10/EQoHCUbLfhrT 2a6yW9jP9qh7CdRObBczszygoV2l8BLngr9suXD7wCO2Etb5xjftdzzgWa0trwrZ1Q BS710aDApMwShoFhhbz5sCc1JglsWK+VXhd4oftKW/pvzVNFMv1qdC35132kgxboJ6 u9DBQ7edEzpmg== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Harald Freudenberger , Eric Biggers , Holger Dengler , Herbert Xu , Stephan Mueller Subject: [PATCH 01/17] s390/sha3: Rename conflicting functions Date: Sun, 19 Oct 2025 17:50:22 -0700 Message-ID: <20251020005038.661542-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" From: David Howells Rename the s390 sha3_* functions to have an "s390_" prefix to avoid conflict with generic code. Signed-off-by: David Howells Acked-By: Harald Freudenberger cc: Eric Biggers cc: "Jason A. Donenfeld" cc: Ard Biesheuvel cc: Holger Dengler cc: Herbert Xu cc: Stephan Mueller cc: linux-crypto@vger.kernel.org cc: linux-s390@vger.kernel.org Link: https://lore.kernel.org/r/20251017144311.817771-2-dhowells@redhat.com Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- 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 03bb4f4bab701..fd5ecae60a572 100644 --- a/arch/s390/crypto/sha3_256_s390.c +++ b/arch/s390/crypto/sha3_256_s390.c @@ -17,11 +17,11 @@ #include #include =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 sctx->first_message_part =3D test_facility(86); if (!sctx->first_message_part) @@ -30,11 +30,11 @@ static int sha3_256_init(struct shash_desc *desc) sctx->func =3D CPACF_KIMD_SHA3_256; =20 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 { u8 *u8; u64 *u64; @@ -48,11 +48,11 @@ static int sha3_256_export(struct shash_desc *desc, voi= d *out) for (i =3D 0; i < SHA3_STATE_SIZE / 8; i++) put_unaligned(le64_to_cpu(sctx->sha3.state[i]), p.u64++); 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 { const u8 *u8; const u64 *u64; @@ -66,26 +66,26 @@ static int sha3_256_import(struct shash_desc *desc, con= st void *in) sctx->func =3D CPACF_KIMD_SHA3_256; =20 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 { .cra_name =3D "sha3-256", .cra_driver_name =3D "sha3-256-s390", @@ -94,26 +94,26 @@ static struct shash_alg sha3_256_alg =3D { .cra_blocksize =3D SHA3_256_BLOCK_SIZE, .cra_module =3D THIS_MODULE, } }; =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 { .cra_name =3D "sha3-224", .cra_driver_name =3D "sha3-224-s390", diff --git a/arch/s390/crypto/sha3_512_s390.c b/arch/s390/crypto/sha3_512_s= 390.c index a5c9690eecb19..f4b52a3a04339 100644 --- a/arch/s390/crypto/sha3_512_s390.c +++ b/arch/s390/crypto/sha3_512_s390.c @@ -16,11 +16,11 @@ #include #include =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 sctx->first_message_part =3D test_facility(86); if (!sctx->first_message_part) @@ -29,11 +29,11 @@ static int sha3_512_init(struct shash_desc *desc) sctx->func =3D CPACF_KIMD_SHA3_512; =20 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 { u8 *u8; u64 *u64; @@ -47,11 +47,11 @@ static int sha3_512_export(struct shash_desc *desc, voi= d *out) for (i =3D 0; i < SHA3_STATE_SIZE / 8; i++) put_unaligned(le64_to_cpu(sctx->sha3.state[i]), p.u64++); 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 { const u8 *u8; const u64 *u64; @@ -65,26 +65,26 @@ static int sha3_512_import(struct shash_desc *desc, con= st void *in) sctx->func =3D CPACF_KIMD_SHA3_512; =20 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 { .cra_name =3D "sha3-512", .cra_driver_name =3D "sha3-512-s390", @@ -95,26 +95,26 @@ 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 { .cra_name =3D "sha3-384", .cra_driver_name =3D "sha3-384-s390", --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 23E2E1A76BC; Mon, 20 Oct 2025 00:53:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921613; cv=none; b=IrD+95Uf7qhViYsjo4CWrrNUVD5UG/OXeG+wyNzpQ5v21lLj/LWpWqOMxolP7jDw3178Ea1gD/ZQHzsRD513OWLyjFrdh3pvKIVtHXeoIYsCDDgnUcX9nl+ITBgV4BIjyBQ+1hyTy6x79SAf1pgiizPrWacTNeDZoNyRaG3ObJk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921613; c=relaxed/simple; bh=TSUPKbwNLbb7mhNbu9L6HinZjxHA1TP1J2/JSwQ69+o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lt/3jG6vtfp2xNXwQQMB/NgWqwnnYMQOpQUoV/bcuiRaHHAtOZxRxRZJ+UleyqdJNX6S1R//0P+ObjDAEdx6A4j6yanDK8QCjjX8vo2M/1F9ROB0HUuO7bNbYelaHGryhxnprKW56M4EblpMuCnJWoO6SgITNH2VhIIQp53FBGI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=o3rU/5QW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="o3rU/5QW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5B6E1C113D0; Mon, 20 Oct 2025 00:53:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921612; bh=TSUPKbwNLbb7mhNbu9L6HinZjxHA1TP1J2/JSwQ69+o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=o3rU/5QWIxEz/SJlv0INtTPIO8SahTbcLR5YnA1j8KGobBvcuYKZyMZj/6uFoEhmr dmc/KBdlm1jdOKogUbfx2oCPDiwiMsReEhsEkvMr8nXrNotGlxBVH+PWZNIl6zPHXX UviGV9j0yHXwJOJp8S/VzCqeRTDMqPKUj0AlPMobVLo2TSGjHd9vGJqc+DyVaqxwVa LKRGVl/SV574HPIgAlNslrefv4kKsPXiH+IRGipWIbrMPoQtDVOR/KgZCpNk56+7A5 y5UPX61iygmt9y1F5M8ITlF6BwmY9k1bFaJbDxvnG244+mPh6+gztopsvoa/LWZQCR cJ+B1wJmtA2Rw== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers , Catalin Marinas , Will Deacon , Herbert Xu , Stephan Mueller Subject: [PATCH 02/17] arm64/sha3: Rename conflicting functions Date: Sun, 19 Oct 2025 17:50:23 -0700 Message-ID: <20251020005038.661542-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" From: David Howells 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 Link: https://lore.kernel.org/r/20251017144311.817771-3-dhowells@redhat.com Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- 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 b4f1001046c9a..426d8044535ab 100644 --- a/arch/arm64/crypto/sha3-ce-glue.c +++ b/arch/arm64/crypto/sha3-ce-glue.c @@ -29,11 +29,11 @@ MODULE_ALIAS_CRYPTO("sha3-384"); MODULE_ALIAS_CRYPTO("sha3-512"); =20 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); struct crypto_shash *tfm =3D desc->tfm; unsigned int bs, ds; @@ -53,12 +53,12 @@ static int sha3_update(struct shash_desc *desc, const u= 8 *data, blocks =3D rem; } while (blocks); 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; __le64 *digest =3D (__le64 *)out; u8 block[SHA3_224_BLOCK_SIZE]; @@ -88,48 +88,48 @@ static int sha3_finup(struct shash_desc *desc, const u8= *src, unsigned int len, } =20 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", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, .base.cra_blocksize =3D SHA3_224_BLOCK_SIZE, .base.cra_module =3D THIS_MODULE, .base.cra_priority =3D 200, }, { .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", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, .base.cra_blocksize =3D SHA3_256_BLOCK_SIZE, .base.cra_module =3D THIS_MODULE, .base.cra_priority =3D 200, }, { .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", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, .base.cra_blocksize =3D SHA3_384_BLOCK_SIZE, .base.cra_module =3D THIS_MODULE, .base.cra_priority =3D 200, }, { .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", .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, .base.cra_blocksize =3D SHA3_512_BLOCK_SIZE, --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 555671B81D3; Mon, 20 Oct 2025 00:53:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921613; cv=none; b=GFV0ZEyIVRT2Ut2XPRnTahFQuVkl5BWcNTppUrXqUl4u7NkE6wQblizMiJh0AGkJhseyKqHrtUNAGlKcjq4BpByNd5GvaFIlU8p8Vr/AUhRKbVwnG88m9wXxCo1qytHLHNToOAwa89LSMEH8h9L+JxoQ8qr5hWB8Z5UVA26KnqU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921613; c=relaxed/simple; bh=sgZdv9/jC61EwAyz3+5yPn188L13C/HYwtzknEucV2Q=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Y3RPo+Rq+AjL4OQQ7TeQmYb6or5/oSi77Fm75xj8Wa4DjS4nSNxqYFITdVCZ+eE2vU8NibI1/UkA0L1u6f8yeaog1WMAVB3J8ieL6KAFTTTrZId3QQISnUu4nby7bJwUC1cKlvKnfOSVal9165+gVQew+u5ChfxIiaDgEHgF6j8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=awA0qsyB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="awA0qsyB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D7A8EC19422; Mon, 20 Oct 2025 00:53:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921613; bh=sgZdv9/jC61EwAyz3+5yPn188L13C/HYwtzknEucV2Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=awA0qsyBkDffZ3ll3L/Xb8c76xfkuBADiDXlFTU+rEPGDvB+kJjfBomaaj+zgVpI7 ibgRbrNVh5uSfMq8U+LK4pYHz2TerksDNqMHfZDBbQtzrK1JqXouPoROWylESIXDbc d29FltE2N/XImrp5VviHh7BTZqCetTkY91z1W/Y11MWwBpdXpBzMsdx72AYeXqPlME 7xXbZnR9bD1nkPV2NE89xlqPm1xUHcPddZjlPkRt+6vFUvNqPmr3/433ohJSsyAE9T H8xoKl1YdyJrgSInHqNeIj1zw5eKHWO2IJPXb+Cx9Dt3H8+JDXMYImzdj3KTCgAUlK 8nEiKEmekkEBw== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers , Herbert Xu , Stephan Mueller Subject: [PATCH 03/17] lib/crypto: Add SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE256 Date: Sun, 19 Oct 2025 17:50:24 -0700 Message-ID: <20251020005038.661542-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" From: David Howells Add SHA3, providing SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128 and SHAKE256 to lib/crypto. 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 v4) - Doc fixes: - Fix the description of the algorithm to be closer to the NIST spec's terminology. - Don't talk of finialising the context for XOFs. - Don't say "Return: None". - Declare the "Context" to be "Any context" and make no mention of the fact that it might use the FPU. - Change "initialise" to "initialize". - Don't warn that the context is relatively large for stack use. - Use size_t for size parameters/variables. - Make the module_exit unconditional. 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. Link: https://lore.kernel.org/r/20251017144311.817771-4-dhowells@redhat.com Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- Documentation/crypto/index.rst | 1 + Documentation/crypto/sha3.rst | 241 ++++++++++++++++ include/crypto/sha3.h | 433 +++++++++++++++++++++++++++- lib/crypto/Kconfig | 7 + lib/crypto/Makefile | 6 + lib/crypto/sha3.c | 511 +++++++++++++++++++++++++++++++++ 6 files changed, 1198 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 100b47d049c04..4ee667c446f99 100644 --- a/Documentation/crypto/index.rst +++ b/Documentation/crypto/index.rst @@ -25,5 +25,6 @@ for cryptographic use cases, as well as programming examp= les. api api-samples descore-readme device_drivers/index krb5 + sha3 diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst new file mode 100644 index 0000000000000..3255618ea2ec3 --- /dev/null +++ b/Documentation/crypto/sha3.rst @@ -0,0 +1,241 @@ +.. 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 variants all based on the same basic algorithm (the Keccak spo= nge +function and permutation). The differences between them are: the "rate" (= how +much of the common state buffer gets updated with new data between invocat= ions +of the Keccak function and analogous to the "block size"), what domain +separation suffix/padding gets appended to the message and how much data is +extracted at the end. The Keccak sponge function 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 + +If selectable algorithms are required then the crypto_hash API may 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 { ... }; + +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, size_t len); + void sha3_256_update(struct sha3_256_ctx *ctx, + const u8 *data, size_t len); + void sha3_384_update(struct sha3_384_ctx *ctx, + const u8 *data, size_t len); + void sha3_512_update(struct sha3_512_ctx *ctx, + const u8 *data, size_t len); + void shake128_update(struct shake128_ctx *ctx, + const u8 *data, size_t len); + void shake256_update(struct shake256_ctx *ctx, + const u8 *data, size_t 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:: + + void sha3_224_final(struct sha3_224_ctx *ctx, + u8 out[SHA3_224_DIGEST_SIZE]); + void sha3_256_final(struct sha3_256_ctx *ctx, + u8 out[SHA3_256_DIGEST_SIZE]); + void sha3_384_final(struct sha3_384_ctx *ctx, + u8 out[SHA3_384_DIGEST_SIZE]); + void 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 append the domain separation suffix= 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 and is analogous to the "rate" in= the + algorithm definition. + + * ``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 domain separation suffix and any padding h= ave + been appended to the state to prevent multiple squeezings from XOF + algorithms from re-appending this. + +Note that the size of the digest is *not* included here as that's only nee= ded +at finalisation time for digest algorithms and can be supplied then. It i= s not +relevant to XOFs. + +To make use of the context, the following internal functions are provided:: + + void sha3_update(struct sha3_ctx *ctx, const u8 *data, size_t 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 appended to/absorbed into the state, output to be +extracted/squeezed from the state and for the state to be cleared. Note t= hat +there is no "final" function, per se, but that can be constructed by squee= zing +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.h diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h index 41e1b83a6d918..a54117cb1546b 100644 --- a/include/crypto/sha3.h +++ b/include/crypto/sha3.h @@ -1,13 +1,16 @@ /* 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) #define SHA3_224_EXPORT_SIZE SHA3_STATE_SIZE + SHA3_224_BLOCK_SIZE + 1 =20 @@ -21,16 +24,444 @@ =20 #define SHA3_512_DIGEST_SIZE (512 / 8) #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 + * used to calculate the block size/rate analogously to the above.. + */ +#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; =20 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 initialized again. + * + * 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, size_t 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 initialize + * + * Initialize a SHA3 context for the production of a SHA3-224 digest of a + * message. + * + * 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. + * + * Context: Any context. + */ +static inline void sha3_224_update(struct sha3_224_ctx *ctx, const u8 *dat= a, size_t 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 initialized + * @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. + * + * Context: Any context. + */ +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 initialize + * + * Initialize a SHA3 context for the production of a SHA3-256 digest of a + * message. + * + * 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. + * + * Context: Any context. + */ +static inline void sha3_256_update(struct sha3_256_ctx *ctx, const u8 *dat= a, size_t 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 initialized + * @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. + * + * Context: Any context. + */ +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 initialize + * + * Initialize a SHA3 context for the production of a SHA3-384 digest of a + * message. + * + * 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. + * + * Context: Any context. + */ +static inline void sha3_384_update(struct sha3_384_ctx *ctx, const u8 *dat= a, size_t 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 initialized + * @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. + * + * Context: Any context. + */ +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 initialize + * + * Initialize a SHA3 context for the production of a SHA3-512 digest of a + * message. + * + * 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. + * + * Context: Any context. + */ +static inline void sha3_512_update(struct sha3_512_ctx *ctx, const u8 *dat= a, size_t 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 initialized + * @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. + * + * Context: Any context. + */ +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 initialize + * + * Initialize 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. + * + * Context: Any context. + */ +static inline void shake128_update(struct shake128_ctx *ctx, const u8 *dat= a, size_t 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: Any context. + */ +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 + * initialized again. + * + * 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 initialize + * + * Initialize 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. + * + * Context: Any context. + */ +static inline void shake256_update(struct shake256_ctx *ctx, const u8 *dat= a, size_t 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: Any context. + */ +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 + * initialized again. + * + * 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 eea17e36a22be..1caf3fbe24bff 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -182,10 +182,17 @@ config CRYPTO_LIB_SHA512_ARCH default y if RISCV && 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO default y if S390 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 source "lib/crypto/tests/Kconfig" =20 diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index bded351aeacef..b7fa51bfeebb5 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -266,10 +266,16 @@ libsha512-$(CONFIG_X86) +=3D x86/sha512-ssse3-asm.o \ x86/sha512-avx2-asm.o 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 =20 obj-$(CONFIG_CRYPTO_LIB_SM3) +=3D libsm3.o diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c new file mode 100644 index 0000000000000..5f847a5eecdc7 --- /dev/null +++ b/lib/crypto/sha3.c @@ -0,0 +1,511 @@ +// 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; + size_t bsize =3D ctx->block_size; + + for (size_t 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, + size_t partial, size_t len) +{ + u8 *buf =3D (u8 *)ctx->state.st; + + buf +=3D partial; + for (size_t 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. + * + * Context: May use the FPU/Vector unit registers. + */ +void sha3_update(struct sha3_ctx *ctx, const u8 *data, size_t len) +{ + size_t absorb_offset =3D ctx->absorb_offset; + size_t 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. + * + * Context: May use the FPU/Vector unit registers. + */ +void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_size) +{ + size_t squeeze_offset =3D ctx->squeeze_offset; + size_t 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); + + size_t 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. + * + * 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. + * + * 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. + * + * 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. + * + * 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. + * + * 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. + * + * 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 (size_t i =3D 0; i < out_len;) { + size_t part =3D min(out_len - i, 32); + + pr_err("%*phN\n", (int)part, out + i); + i +=3D part; + } + return -EBADMSG; + } + return 0; +} +subsys_initcall(sha3_mod_init); + +static void __exit sha3_mod_exit(void) +{ +} +module_exit(sha3_mod_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm"); --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 D6D421D5CDE; Mon, 20 Oct 2025 00:53:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921614; cv=none; b=T6w4UtjcK4ydER4ia449githKCuCDKOiFTd4yKv2WbqZaSgL3aqIIys6sril6RFdWGByuVwalxohXhk97coCL9aLM7J89MRILMrfyU6lDAN91wIyViS9JKUzi9WZWKWGikk7lhnWPLZD5yYG7D/q432viEfeZd4R43kIZGvQSg4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921614; c=relaxed/simple; bh=m4BeHgL3buDxrxSoDsgZ+7mjmPnxE72GJARRG8xIu+Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QsamaPobHt1sjOdFJeo+9y51X4N6OjAMGM434VR7+CJdO1EVgUEz2S6RQUKEkw9sw8WQMuqEM3H2KtdxAch2b772eyd3VXE1q/mlde/Sh19cS6hLk4qc0o3/AdlQ+4k4ds+2S0ZT3B4W0Ga6VGjqP7AuExl0F1c1TZUgKYrDx9c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rBDV/pVM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rBDV/pVM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 57AAAC113D0; Mon, 20 Oct 2025 00:53:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921613; bh=m4BeHgL3buDxrxSoDsgZ+7mjmPnxE72GJARRG8xIu+Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rBDV/pVMzGjHxm865ok1NZc5G0dnVmrH5vjolGOawgHxav/kKUrk6XzA1D4ecY0xk HXmHZMhs53VAs8kTrnqZZZc73jstRhleO2L9s3EFJu2Ofpt8OutVure1oPYyvHkNuG ochoya4yqoev0bLsEzNfOKdio6vxwAFucZngTY8rNPZf/s3mreh2JvVu8+pPd0z+la 4ECJTJwqB3Q7YwpMFBy3T6/rRREWZ3qUiC9Uic5Vb5SZ/G/aUe3WmA0Sy8JkMYW4ey CeEZv1IOGjAIMKOCvsV4dAB/O2Y+W7Thdfv4evOrH/v6BQgj8ESXqpCwYmfFD7pIcN c3eu3h8Lwg0UA== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers , Herbert Xu , Stephan Mueller Subject: [PATCH 04/17] lib/crypto: Move the SHA3 Iota transform into the single round function Date: Sun, 19 Oct 2025 17:50:25 -0700 Message-ID: <20251020005038.661542-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" From: David Howells 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 Link: https://lore.kernel.org/r/20251017144311.817771-5-dhowells@redhat.com Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- 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 5f847a5eecdc7..2c292b0b3db34 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -46,11 +46,12 @@ static const u64 sha3_keccakf_rndc[24] =3D { }; =20 /* * 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]; =20 /* Theta */ @@ -148,19 +149,19 @@ static SHA3_INLINE void sha3_keccakf_one_round_generi= c(struct sha3_state *state) 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]; + + /* 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 /* * 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 --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 937131E32B9; Mon, 20 Oct 2025 00:53:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921614; cv=none; b=kROJwC73j9AMQvcG3xDdl5XumH+IlrjhtNL3zAipjsCGSxpmj1/RgO8vmX0dyF85W7gizypuwwfdHejAlhDVxv67YZH00JfAoCyfvvEQN7AgDV1DdWU5MrKksVsqDdYvvd6CSeckFbGc8OdWGijLsIqsv2P4mXbzbs7SZP3u8iI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921614; c=relaxed/simple; bh=8J/l5clsQLjNb4xoIs+An0Q9J7n0JsdEQzQp/mLlHfk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GHUF8j6mhIqW8TPCzTVYp1goi4RJ6DE8538QLb9KccrmOaXZSkkhhlbqyf580V3QLwB/ogFlipIXnjB+9F7xKTEV/OWglM3OF22h/GcFw7QSlNky9M1IEjqi8gVmBzswjrlbGIXjrkbfa8yez1oLSlbsUgz343+M79y9eZ8hpX8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=de7vG5CB; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="de7vG5CB" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C52F2C16AAE; Mon, 20 Oct 2025 00:53:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921614; bh=8J/l5clsQLjNb4xoIs+An0Q9J7n0JsdEQzQp/mLlHfk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=de7vG5CBXS367B5Nn0/5tzcW9K6EOqjknfycXLRHTcUlcZ4dQTAUhXoq84ri6ayLO 1+R++WEoVwVko1cesJtODwGRJx9pE4VcYQGLE9TewgnKVTZP6Pxv8ZsMnKnqcQZLMg bZ8umZknHA7HQ4lST2FSW5zOTiVitOceQG79WjyuwBmyk63tQ3xAzJLDkNX2pS62ap jUatLBPEmbS1xB/q2zT36xY9JjWIu/kXJ+BuKtyvLj4S9sCalRvVLv2S9h73KCUXQu eMFhWwUCKLJ5rlKqHUrfvOVM+mHOAAQekI6ATsgNQHR7tEn/ydzPAyv1FHRLotDAUw WwQN7CywF0nAw== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers , Herbert Xu , Stephan Mueller Subject: [PATCH 05/17] lib/crypto: Add SHA3 kunit tests Date: Sun, 19 Oct 2025 17:50:26 -0700 Message-ID: <20251020005038.661542-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" From: David Howells 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 in a number of ways: (1) To be able to generate SHAKE* testvecs because Python's hashlib requires the output digest size supplying for those two algorithms as they produce arbitrary length digests. (2) To change '-' in the algo name into '_' when generating symbols from it. (3) To not generate HMAC for SHA3 or SHAKE as support for that isn't currently implemented. 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 v5) - Fix gen-hash-testvecs.py to correctly handle algo names that contain a dash. - Fix gen-hash-testvecs.py to not generate HMAC for SHA3-* or SHAKE* as these don't currently have HMAC variants. - Fix algo names to be correct. - Fix kunit module description as it now tests all SHA3 variants. Link: https://lore.kernel.org/r/20251017144311.817771-6-dhowells@redhat.com Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- lib/crypto/tests/Kconfig | 11 + lib/crypto/tests/Makefile | 1 + lib/crypto/tests/sha3_kunit.c | 342 ++++++++++++++++++++++++++++ lib/crypto/tests/sha3_testvecs.h | 231 +++++++++++++++++++ scripts/crypto/gen-hash-testvecs.py | 10 +- 5 files changed, 593 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 578af717e13a7..67538968edabb 100644 --- a/lib/crypto/tests/Kconfig +++ b/lib/crypto/tests/Kconfig @@ -70,10 +70,21 @@ config CRYPTO_LIB_SHA512_KUNIT_TEST select CRYPTO_LIB_SHA512 help 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 and XOF functions, + including SHA3-224, SHA3-256, SHA3-384, SHA3-512, SHAKE128 and + SHAKE256. + config CRYPTO_LIB_BENCHMARK_VISIBLE bool =20 config CRYPTO_LIB_BENCHMARK bool "Include benchmarks in KUnit tests for cryptographic functions" diff --git a/lib/crypto/tests/Makefile b/lib/crypto/tests/Makefile index a71fad19922ba..9c61b29ac4ca1 100644 --- a/lib/crypto/tests/Makefile +++ b/lib/crypto/tests/Makefile @@ -5,5 +5,6 @@ obj-$(CONFIG_CRYPTO_LIB_CURVE25519_KUNIT_TEST) +=3D curve25= 519_kunit.o obj-$(CONFIG_CRYPTO_LIB_MD5_KUNIT_TEST) +=3D md5_kunit.o 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 0000000000000..032fa3950afe4 --- /dev/null +++ b/lib/crypto/tests/sha3_kunit.c @@ -0,0 +1,342 @@ +// 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" + +/* + * Sample message and the output generated for various algorithms by passi= ng it + * into "openssl sha3-224" etc.. + */ +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"); +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 0000000000000..9c4c403cc6e06 --- /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 fc063f2ee95f1..cb6f6cfbedeb2 100755 --- a/scripts/crypto/gen-hash-testvecs.py +++ b/scripts/crypto/gen-hash-testvecs.py @@ -59,10 +59,14 @@ def hash_init(alg): =20 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): ctx =3D hash_init(alg) hash_update(ctx, data) @@ -85,11 +89,11 @@ def print_c_struct_u8_array_field(name, value): print('\t\t},') =20 def alg_digest_size_const(alg): if alg =3D=3D 'blake2s': return 'BLAKE2S_HASH_SIZE' - return f'{alg.upper()}_DIGEST_SIZE' + return f'{alg.upper().replace('-', '_')}_DIGEST_SIZE' =20 def gen_unkeyed_testvecs(alg): print('') print('static const struct {') print('\tsize_t data_len;') @@ -120,11 +124,11 @@ def gen_hmac_testvecs(alg): key =3D rand_bytes(key_len) mac =3D hmac.digest(key, data[:data_len], 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 =20 def gen_additional_blake2s_testvecs(): @@ -162,7 +166,9 @@ print(f'/* This file was generated by: {sys.argv[0]} {"= ".join(sys.argv[1:])} */ gen_unkeyed_testvecs(alg) if alg =3D=3D 'blake2s': gen_additional_blake2s_testvecs() elif alg =3D=3D 'poly1305': gen_additional_poly1305_testvecs() +elif alg.startswith('sha3-') or alg.startswith('shake'): + pass # no HMAC else: gen_hmac_testvecs(alg) --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 DB15A1EB193; Mon, 20 Oct 2025 00:53:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921615; cv=none; b=J6o9/sEuWHN4EgAXsv7HdcqC4sLvCbnrg98kS7L+GFm6LdF9RPdu+mXS0ntHt1jcZOXFbdWs97hFsXyaJBNK/F76Q6vjLjoRKJ1dFGPteCtTSxx7PttjXbdfJcJGOEAfyoG+oXjXtSwmn6Rt7a7I11BVB+V4XV0rZN9MXFwAuRg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921615; c=relaxed/simple; bh=sNfiHzZBvEsZv8KJ6ym8WqKRimzL6B5akfZG5UKLVY0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EgRf7O5Njq71oaVLBCvOblQFILCbNHAJWGkB5SDlHx3a9UL5LRzmmxCbWWoEp/TAshtsCPniHTLfAwXZruXoHsOnEc1u+LlN1T9tbYyf90QDDjNr+XnjT0GgYszfhOC+9mAIlbyZh1NoEQ0Uf/YGkPwIf1uaBRtluHsgVkmNopg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=B+1/pb7/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="B+1/pb7/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3E1EEC113D0; Mon, 20 Oct 2025 00:53:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921614; bh=sNfiHzZBvEsZv8KJ6ym8WqKRimzL6B5akfZG5UKLVY0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B+1/pb7/WHY0BbmCnFWu9ck8/blkeG9BhHkAJWASM6Cj74Mv9oCEUDeDIDlLkFp+3 On4VrnUQzZ0UBl6dMT5QlqCvWhbEYI2zDNgrsOIFYXKM71seCNw5tgjBBzubIpUuD5 SP1Mkz/jR76paC46zOSymIVpi847dht/kP+m96LQRdE/hc2McrvSoTmu98NEkdTAfO pa+Fp9v0+6myx6kuTNr6DdrJ/kjclGqnQm9/htHrtYHpKoF01Tbrdv8FUSvUSBabiX 2GQyfSJfPMSsIzDKLYeMGKYaj5ujP6tTNrPm9FC9AVsIl8YggN1OQsmK2FHjZ5Tk5V e9TfUryjC8esg== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 06/17] lib/crypto: sha3: Fix libsha3 build condition Date: Sun, 19 Oct 2025 17:50:27 -0700 Message-ID: <20251020005038.661542-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" The correct condition is there but is commented out. Fix it. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- lib/crypto/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index b7fa51bfeebb5..2f15cef850507 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -266,13 +266,12 @@ libsha512-$(CONFIG_X86) +=3D x86/sha512-ssse3-asm.o \ x86/sha512-avx2-asm.o 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_CRYPTO_LIB_SHA3) +=3D libsha3.o +libsha3-y :=3D sha3.o =20 ##########################################################################= ###### =20 obj-$(CONFIG_MPILIB) +=3D mpi/ =20 --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 0433F1F09A3; Mon, 20 Oct 2025 00:53:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921615; cv=none; b=KUPao+g9Jc6JgeAg2l+qbp36YjWHArf1dqWdJEThybi4avw8jcMHrRtiqosZ/0S3FM49QsKiS66so/p3OFnZmNZzfOmcQRlovFr9uZ4F2NycJj40rvxwxeGLAmx4ZtXll7N8q+q/f0lDjRC9tWgAwPq8e8FYid+ddsFhz/lulR0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921615; c=relaxed/simple; bh=OaQGEhSD9l9BZYpyT3Hv3bwzyb+UiSiWBVKTKVVAllo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Tg+OzQ5NO/oIClSKJrVS6DfxkA3nbcdXueeIfUznezVdxUkZGZaNfI/8PFXwDMR6KjybEwjyGwemQxbn/ByrUco6dz/1YeChWm6UPdI4QldeJ62sUfgF8ekNc/AKmmfXgANjdw/bmylz40dmI7cPUxYA+61/27O4UxNMZTg2Di8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=YX5RdWEl; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="YX5RdWEl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9D195C116D0; Mon, 20 Oct 2025 00:53:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921614; bh=OaQGEhSD9l9BZYpyT3Hv3bwzyb+UiSiWBVKTKVVAllo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YX5RdWElee1yHQDh5fsUq6GWg1Nyxlvce5OuFgBg/ky8IQPLykEwhhWoLE5IhtVLg 5hLsqTrpveFOqYKjfgsyqajSVX2R/iWNoP7ETZfTawxlkIOYRQEqDeFlE91g8WqR8V FJf9Kkm2JL3ouQz6OUTors7MU11lcrhzYH9QJzGpX5MftLgDDcKm1KD19dbzTMNrBR FED8CKqORxuobkwstChIcHDajbNukiay28cUsmaON2H8ZqaxUQIZY4gn2Mr9Ra4ZAF gVUe+9uzBP1ALLonpQfDnX7eAAZtnz8zsKJwghxufKpKsurRq7j/84rXSrR1QuxX03 35s6H2ghg/ytQ== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 07/17] lib/crypto: sha3: Use appropriate conversions in sha3_keccakf_generic() Date: Sun, 19 Oct 2025 17:50:28 -0700 Message-ID: <20251020005038.661542-8-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" For converting from little endian to CPU endian, use le64_to_cpus(). For converting from CPU endian to little endian, use cpu_to_le64s(). No functional change, but this makes the code clearer. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- lib/crypto/sha3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index 2c292b0b3db34..8f08e7b8f4521 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -168,16 +168,16 @@ static void sha3_keccakf_rounds_generic(struct sha3_s= tate *state) * 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]); + le64_to_cpus(&state->st[i]); =20 sha3_keccakf_rounds_generic(state); =20 for (int i =3D 0; i < ARRAY_SIZE(state->st); i++) - le64_to_cpus(&state->st[i]); + cpu_to_le64s(&state->st[i]); } =20 static void sha3_absorb_block_generic(struct sha3_ctx *ctx, const u8 *data) { struct sha3_state *state =3D &ctx->state; --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 A45B920468E; Mon, 20 Oct 2025 00:53:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921615; cv=none; b=NJaZ0Lh6HfEuNktfqPXq0SQiSKcYzB1kXwCS6d3m3QXiW0zDTJo6QNSOiAB4TRDel67wT5PrKD1s3vE1K2JhKLwPjoLEd2oAA5fxJ0I2RpA4Nc+KNhQndeidU4BGHR6oe+nap0to8gAcZhsxI27Y00w4PcalzqP3XlLUSIKZhsw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921615; c=relaxed/simple; bh=Hauj1v8AzIcWYsh5CTOeRlzypb0Dv3HdLIY/wCgEtzU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dzzfj9DFAmPfN+zx4WrpK/HkqRkh6IyfHo1kWFTi8dD511eeTEbS0d8kFOmyHGRkSCMPijCxt48Ul3/IA6Gis5QEVKWC6CI2NchRmQNDd/Bqgzm+ONmw64bC+DK0ITNKtGhoaONE7dpcvzdoK0VNVXu4fe+26irWQnHP0f2Yz/8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EDmcNoYS; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EDmcNoYS" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 08420C4AF09; Mon, 20 Oct 2025 00:53:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921615; bh=Hauj1v8AzIcWYsh5CTOeRlzypb0Dv3HdLIY/wCgEtzU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EDmcNoYSTLKuVAnezV8raI05zhSi+N8DFRp5eUI+SDDMEQx4A3Mi+XXEyv8kGwS9H mfsiBZOBedmzyu4nmcPr4bmk+suPDgv0bollZO8GCcnM9d3HW/XHoLopB7XAPRttT8 ILXgXsR82tNvVEzfu/dSwY2hS1dVzqtgPmQF5jWfTKlFV5ARz+6VvMp6ycsodwMBqH 7h6cn3vxwdujzqKx9Kwtmz9g0HC1wQdeph9vx1px3QV8Sp0T/5JVBSKDmLVdJ+i0NR 7eGFPwi5GdBWcyMgbJ+lnupzJRhvo7uxeFOT0KqAMY5/y9vsCt8VK1UHi+T48wFc+c S9X4Wqc+dep2Q== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 08/17] lib/crypto: sha3: Drop unfinished SHAKE support from gen-hash-testvecs.py Date: Sun, 19 Oct 2025 17:50:29 -0700 Message-ID: <20251020005038.661542-9-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" The SHAKE testing doesn't actually use gen-hash-testvecs.py, so remove the unfinished SHAKE support from it. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- scripts/crypto/gen-hash-testvecs.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-= testvecs.py index cb6f6cfbedeb2..ba241cb1ed2fd 100755 --- a/scripts/crypto/gen-hash-testvecs.py +++ b/scripts/crypto/gen-hash-testvecs.py @@ -59,14 +59,10 @@ def hash_init(alg): =20 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): ctx =3D hash_init(alg) hash_update(ctx, data) @@ -166,9 +162,9 @@ print(f'/* This file was generated by: {sys.argv[0]} {"= ".join(sys.argv[1:])} */ gen_unkeyed_testvecs(alg) if alg =3D=3D 'blake2s': gen_additional_blake2s_testvecs() elif alg =3D=3D 'poly1305': gen_additional_poly1305_testvecs() -elif alg.startswith('sha3-') or alg.startswith('shake'): +elif alg.startswith('sha3-'): pass # no HMAC else: gen_hmac_testvecs(alg) --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 18E06212550; Mon, 20 Oct 2025 00:53:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921616; cv=none; b=abbHy+nqfdAdcGqf1V1UKwH5mQiXx/WgBJssNvHuaoScDkZKSyyEIZNSVRwZRZyzwJf1OqmNtwVk5U6QzNyp2j4z+ZyeFCgglwiwhpPoqCDoOsPIjks27dbJFeJiiGNDm5VM9ZeQMdkFHwYfudS8mq7rmKUwSdBqYbMOn1DP9OE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921616; c=relaxed/simple; bh=3ORQ9KVdJyyMj/gc8QaYuJQuZsbtFtyURkNerD2o3uc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UnpVfMlR5Sr3WXTVV/hnapC5CRWRhSspAZRnS6VDPV7MVjdFxC1F8mDNLZxL9YTkqvIaFEs7ftgIURCSewkJ/ivRPmK3FDUjiGmn5XlkvbUr2GKSOyjxDVVGtGCg3wFyZTjMxM8XjXKnTo1KEFIg9/UraqPFeWEujOkQwT/UoUc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oit5HcfN; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="oit5HcfN" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 67FB4C116C6; Mon, 20 Oct 2025 00:53:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921615; bh=3ORQ9KVdJyyMj/gc8QaYuJQuZsbtFtyURkNerD2o3uc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oit5HcfNshrDSHmVtH2/S/JLASBzI/Ti9cISjcCNnHc0K2pLTZdIR6fE3rYorCHej Gmd04rN/u71NvIzZYDXIk++NB69tceE4IS7mShbKhrBOLtZHcpOdGUTck4J5oLdQ9p lpnw0LdnIzk1JSekGDXjKb4yf6MO7qiJBJvrQFlASLbLIpt68bP/oC6m6at7lVP3qB 6hQbY2Rb89WT38+go/KYUS7yCW+xety/MFf8ddQw0hz6YJhcNl0869T+umw6XWXHl6 CixfqdyCd8099VjnSNoO5X8GyOSzQtytnCziqKW+gx/SmSebt+XRESHpxseeEi4X7w 7XDhQQ6PXT+yA== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 09/17] lib/crypto: sha3: Consistently use EXPORT_SYMBOL_GPL Date: Sun, 19 Oct 2025 17:50:30 -0700 Message-ID: <20251020005038.661542-10-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" Consistently use EXPORT_SYMBOL_GPL in sha3.c, instead of a mix of EXPORT_SYMBOL and EXPORT_SYMBOL_GPL. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- lib/crypto/sha3.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index 8f08e7b8f4521..f8167037138c7 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -329,11 +329,11 @@ void sha3_224(const u8 *in, size_t in_len, u8 out[SHA= 3_224_DIGEST_SIZE]) =20 sha3_224_init(&ctx); sha3_224_update(&ctx, in, in_len); sha3_224_final(&ctx, out); } -EXPORT_SYMBOL(sha3_224); +EXPORT_SYMBOL_GPL(sha3_224); =20 /** * 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 @@ -350,11 +350,11 @@ void sha3_256(const u8 *in, size_t in_len, u8 out[SHA= 3_256_DIGEST_SIZE]) =20 sha3_256_init(&ctx); sha3_256_update(&ctx, in, in_len); sha3_256_final(&ctx, out); } -EXPORT_SYMBOL(sha3_256); +EXPORT_SYMBOL_GPL(sha3_256); =20 /** * 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 @@ -371,11 +371,11 @@ void sha3_384(const u8 *in, size_t in_len, u8 out[SHA= 3_384_DIGEST_SIZE]) =20 sha3_384_init(&ctx); sha3_384_update(&ctx, in, in_len); sha3_384_final(&ctx, out); } -EXPORT_SYMBOL(sha3_384); +EXPORT_SYMBOL_GPL(sha3_384); =20 /** * 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 @@ -392,11 +392,11 @@ void sha3_512(const u8 *in, size_t in_len, u8 out[SHA= 3_512_DIGEST_SIZE]) =20 sha3_512_init(&ctx); sha3_512_update(&ctx, in, in_len); sha3_512_final(&ctx, out); } -EXPORT_SYMBOL(sha3_512); +EXPORT_SYMBOL_GPL(sha3_512); =20 /** * 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 @@ -416,11 +416,11 @@ void shake128(const u8 *in, size_t in_len, u8 *out, s= ize_t out_len) shake128_init(&ctx); shake128_update(&ctx, in, in_len); shake128_squeeze(&ctx, out, out_len); shake128_clear(&ctx); } -EXPORT_SYMBOL(shake128); +EXPORT_SYMBOL_GPL(shake128); =20 /** * 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 @@ -440,11 +440,11 @@ void shake256(const u8 *in, size_t in_len, u8 *out, s= ize_t out_len) shake256_init(&ctx); shake256_update(&ctx, in, in_len); shake256_squeeze(&ctx, out, out_len); shake256_clear(&ctx); } -EXPORT_SYMBOL(shake256); +EXPORT_SYMBOL_GPL(shake256); =20 /* * Do a quick test using SHAKE256 and a 200 byte digest. */ static const u8 sha3_sample[] __initconst =3D --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 2C93321420B; Mon, 20 Oct 2025 00:53:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921616; cv=none; b=D3dAUYxkqVVglpgMt4jFEM+GrJNCmdLWSIFFmIkcnxaBuZBbp4EEjFreMA3aWX1ap+VBGsNq2lrsqJEATXR6t3ZcgItOE+BkC8ExMM9shYve4umQeUq19LncfAC835j4vKmbK0WEvxqelQf0fyS/Ye1hSzPXr65ejOoAgyCAxB8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921616; c=relaxed/simple; bh=3YHFqqatVYAdaji7NuRqfLy3KJyI82DMyXan+tUouMk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g36MsHZ9je/G4EiKo+1dFPbDNrNU44DquE9wjNogR8kEGdCM4Myt4lHUCaVeeCtuIa6vmCwFW0R0JTzjVd92IfMNZGOUnZ6uXQoMmc59eWdhl4E5Lcp1XQZchgiLr8qeT1sonYSiDyes739PFYGwmMeMf5xonCbNDDCcx3XVSUM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=hnQJfJFP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="hnQJfJFP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C7AE3C4CEE7; Mon, 20 Oct 2025 00:53:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921616; bh=3YHFqqatVYAdaji7NuRqfLy3KJyI82DMyXan+tUouMk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hnQJfJFPkl3b6tm6hDp/45/sno1hoDbgxW9aDdnf7oMWNkSgJmr2jsgMvGVmop59c NrdPxaaW5RoltBBjF5Bz7crHZbjaaTJakuXJF5Y+1nMPy+Z0HO3K7FpEE5mrl01zu4 ylMaV3TWfnCDsrYUnZmByiXjVig5OqH5FEmSnax/9oSpnZ8elAWPGtpHVlMlLF3gdM y4Rm/hVbUTU8kELs+EiSUyfOVuT8bdpqasiK7CW1vfojsJbbD3MriveBVm89i+cQoT CdQtbJbcVVQBjBBzgCiazr/iCA+fl2s/svYCKNUGWvQpj1ItziYfpgwpdD0T7shZGP sYqz0s5WLLqsQ== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 10/17] lib/crypto: sha3: Replace redundant ad-hoc test with FIPS test Date: Sun, 19 Oct 2025 17:50:31 -0700 Message-ID: <20251020005038.661542-11-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" Since SHA-3 is a FIPS-approved algorithm, add a FIPS cryptographic algorithm self-test to it, following the example of SHA-1 and SHA-2. Make it replace the existing ad-hoc test. The actual correctness tests are in the KUnit test suite; the boot-time testing is just for FIPS. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- Documentation/crypto/sha3.rst | 12 ++++-- lib/crypto/fips.h | 7 ++++ lib/crypto/sha3.c | 63 +++++++---------------------- scripts/crypto/gen-fips-testvecs.py | 4 ++ 4 files changed, 33 insertions(+), 53 deletions(-) diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst index 3255618ea2ec3..6d7a07e088e9a 100644 --- a/Documentation/crypto/sha3.rst +++ b/Documentation/crypto/sha3.rst @@ -9,11 +9,11 @@ SHA-3 Algorithm collection - Overview - Basic API - Extendable-Output Functions - Convenience API - Internal API - - Testing + - Testing - References - API Function Reference =20 =20 Overview @@ -219,14 +219,18 @@ extracted/squeezed from the state and for the state t= o be cleared. Note that there is no "final" function, per se, but that can be constructed by squee= zing and clearing. =20 =20 Testing -------- +=3D=3D=3D=3D=3D=3D=3D =20 -The sha3 module does a basic sanity test on initialisation, but there is a= lso a -kunit test module available. +To test the SHA-3 code, use sha3_kunit. + +Since the SHA-3 algorithms are FIPS-approved, when the kernel is booted in= FIPS +mode the SHA-3 library also performs a simple self-test. This is purely t= o meet +a FIPS requirement. Normal testing done by kernel developers and integrat= ors +should use the much more comprehensive KUnit test suite instead. =20 =20 References =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 diff --git a/lib/crypto/fips.h b/lib/crypto/fips.h index 78a1bdd33a151..023410c2e0dbc 100644 --- a/lib/crypto/fips.h +++ b/lib/crypto/fips.h @@ -34,5 +34,12 @@ static const u8 fips_test_hmac_sha512_value[] __initcons= t __maybe_unused =3D { 0x92, 0x7e, 0x3c, 0xbd, 0xb1, 0x3c, 0x49, 0x98, 0x44, 0x9c, 0x8f, 0xee, 0x3f, 0x02, 0x71, 0x51, 0x57, 0x0b, 0x15, 0x38, 0x95, 0xd8, 0xa3, 0x81, 0xba, 0xb3, 0x15, 0x37, 0x5c, 0x6d, 0x57, 0x2b, }; + +static const u8 fips_test_sha3_256_value[] __initconst __maybe_unused =3D { + 0x77, 0xc4, 0x8b, 0x69, 0x70, 0x5f, 0x0a, 0xb1, + 0xb1, 0xa5, 0x82, 0x0a, 0x22, 0x2b, 0x49, 0x31, + 0xba, 0x9b, 0xb6, 0xaa, 0x32, 0xa7, 0x97, 0x00, + 0x98, 0xdb, 0xff, 0xe7, 0xc6, 0xde, 0xb5, 0x82, +}; diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index f8167037138c7..83fbfa1169cdb 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -15,10 +15,11 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include #include #include +#include "fips.h" =20 /* * 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 @@ -442,71 +443,35 @@ void shake256(const u8 *in, size_t in_len, u8 *out, s= ize_t out_len) shake256_squeeze(&ctx, out, out_len); shake256_clear(&ctx); } EXPORT_SYMBOL_GPL(shake256); =20 -/* - * 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 */ -}; - +#if defined(sha3_mod_init_arch) || defined(CONFIG_CRYPTO_FIPS) 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 (size_t i =3D 0; i < out_len;) { - size_t part =3D min(out_len - i, 32); - - pr_err("%*phN\n", (int)part, out + i); - i +=3D part; - } - return -EBADMSG; + if (fips_enabled) { + /* + * FIPS cryptographic algorithm self-test. As per the FIPS + * Implementation Guidance, testing any SHA-3 algorithm + * satisfies the test requirement for all of them. + */ + u8 hash[SHA3_256_DIGEST_SIZE]; + + sha3_256(fips_test_data, sizeof(fips_test_data), hash); + if (memcmp(fips_test_sha3_256_value, hash, sizeof(hash)) !=3D 0) + panic("sha3: FIPS self-test failed\n"); } return 0; } subsys_initcall(sha3_mod_init); =20 static void __exit sha3_mod_exit(void) { } module_exit(sha3_mod_exit); +#endif =20 MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm"); diff --git a/scripts/crypto/gen-fips-testvecs.py b/scripts/crypto/gen-fips-= testvecs.py index 2956f88b764ae..db873f88619ac 100755 --- a/scripts/crypto/gen-fips-testvecs.py +++ b/scripts/crypto/gen-fips-testvecs.py @@ -3,10 +3,11 @@ # # Script that generates lib/crypto/fips.h # # Copyright 2025 Google LLC =20 +import hashlib import hmac =20 fips_test_data =3D b"fips test data\0\0" fips_test_key =3D b"fips test key\0\0\0" =20 @@ -28,5 +29,8 @@ print_static_u8_array_definition("fips_test_key", fips_te= st_key) =20 for alg in 'sha1', 'sha256', 'sha512': ctx =3D hmac.new(fips_test_key, digestmod=3Dalg) ctx.update(fips_test_data) print_static_u8_array_definition(f'fips_test_hmac_{alg}_value', ctx.di= gest()) + +print_static_u8_array_definition(f'fips_test_sha3_256_value', + hashlib.sha3_256(fips_test_data).digest()) --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 98BC7220F5E; Mon, 20 Oct 2025 00:53:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921616; cv=none; b=mUyXs54uP3YZKD/OmC561AxAlLCT02q0Ar01+cEvFuBgyJs8hWV3m9Upib+JM+X0Y4D/QAmnd26TymLo3pCQfvQcqYG6gqBpFwzqjrF4UlEhdXwXqTEkX7qNT4HtJO88MJ6h5eluc80f/PZoYBJ1/9130xW3677FyXxqqbgrXAM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921616; c=relaxed/simple; bh=RVyv+yeclwxuXntAMdmLEYWORjMLZXN8g4rEQIwL7y8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p/opUyFYLN0nduB819OJmdZNP04t9nBQKaxZNryQZ0BYkB7OPufY76nDMKkcGVH6WPQYb8PoaadklX4NZwTVCD3BuSPg8lesnPBcbQDCCDciNDo74Idm07pjK25QtJqYsd1Mmr2kLobSFfNadvWXAtueMOqhviCAeCc/03EPIh8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=gAbeiMxm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="gAbeiMxm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 32F39C16AAE; Mon, 20 Oct 2025 00:53:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921616; bh=RVyv+yeclwxuXntAMdmLEYWORjMLZXN8g4rEQIwL7y8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gAbeiMxm4V2sqtKRFzIVUZQCNjBUiIrPm2eDvrASABAU/GtItYLxCgObge73LrlVi wpTxgWSju/yMJB+MS6zB2qR3tn3zZdIn1d9xfWv0v5kkWqTZ3eEgYk6S/KHxPMB20/ RPh6jaSIGQiEtPDdRcjsRAGJszM13mSq7eofmJbUQJSE+wBxUdsz/AA31sOF4qu2xp DjzxhT8KhNi4Ywg1rEJ//xg/v4RRxpIeW0wt9NsvII9Sh/zZK3hntwg96aeGivaj/v idmdwWWuIlbqb6Nrc3/W/lgt25IuePiMtEfH9suBEZElvuQBwF0ihyAur40mv6m4pP 62QZU2DD22T7g== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 11/17] lib/crypto: sha3: Simplify the API Date: Sun, 19 Oct 2025 17:50:32 -0700 Message-ID: <20251020005038.661542-12-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" Instead of having separate types and functions for each of the six SHA-3 algorithms, instead divide them into two groups: the digests and the XOFs. The digests use sha3_ctx and the XOFs use shake_ctx. The internal context is now called __sha3_ctx. The result is a simpler, smaller API that is more convenient for users that need to support multiple SHA-3 variants, e.g. crypto/sha3.c. It still preserves the property that the digests can't be incorrectly treated as XOFs and vice versa. It does result in the explicit array bounds for the output digests being lost from the incremental API. However, explicit array bounds don't really work properly in C anyway. They're nice to have as hints, but not worth duplicating all the update and final functions for. Note that the BLAKE2s and BLAKE2b code uses this same solution. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- Documentation/crypto/sha3.rst | 194 +++++------------ include/crypto/sha3.h | 386 +++++++++------------------------- lib/crypto/sha3.c | 87 +++----- lib/crypto/tests/sha3_kunit.c | 20 +- 4 files changed, 184 insertions(+), 503 deletions(-) diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst index 6d7a07e088e9a..c27da98c89b7f 100644 --- a/Documentation/crypto/sha3.rst +++ b/Documentation/crypto/sha3.rst @@ -5,14 +5,13 @@ 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 =20 .. Contents: =20 - Overview - - Basic API - - Extendable-Output Functions + - Digests + - Extendable-Output Functions - Convenience API - - Internal API - Testing - References - API Function Reference =20 =20 @@ -39,95 +38,75 @@ and two Extendable-Output Functions (XOF): =20 - SHAKE128 - SHAKE256 =20 If selectable algorithms are required then the crypto_hash API may 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 { ... }; - -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, size_t len); - void sha3_256_update(struct sha3_256_ctx *ctx, - const u8 *data, size_t len); - void sha3_384_update(struct sha3_384_ctx *ctx, - const u8 *data, size_t len); - void sha3_512_update(struct sha3_512_ctx *ctx, - const u8 *data, size_t len); - void shake128_update(struct shake128_ctx *ctx, - const u8 *data, size_t len); - void shake256_update(struct shake256_ctx *ctx, - const u8 *data, size_t len); +instead. + + +Digests +=3D=3D=3D=3D=3D=3D=3D + +The SHA-3 digest API uses the following struct:: + + struct sha3_ctx { ... }; + +There are a collection of initialization functions, one for each algorithm= :: + + void sha3_224_init(struct sha3_ctx *ctx); + void sha3_256_init(struct sha3_ctx *ctx); + void sha3_384_init(struct sha3_ctx *ctx); + void sha3_512_init(struct sha3_ctx *ctx); + +Data is then added with:: + + void sha3_update(struct sha3_ctx *ctx, const u8 *in, size_t in_len); =20 The update function may be called multiple times if need be to add non-contiguous data. =20 -For digest algorithms, the digest is finalised and extracted with the -algorithm-specific function:: +Finally, the digest is generated using:: =20 - void sha3_224_final(struct sha3_224_ctx *ctx, - u8 out[SHA3_224_DIGEST_SIZE]); - void sha3_256_final(struct sha3_256_ctx *ctx, - u8 out[SHA3_256_DIGEST_SIZE]); - void sha3_384_final(struct sha3_384_ctx *ctx, - u8 out[SHA3_384_DIGEST_SIZE]); - void 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. + void sha3_final(struct sha3_ctx *ctx, u8 *out); =20 +which also zeroizes the context. The length of the digest is determined b= y the +initialization function that was called. =20 Extendable-Output Functions ---------------------------- +=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=3D + +The SHA-3 extendable-output function (XOF) API uses the following struct:: =20 -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:: + struct shake_ctx { ... }; =20 - 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); +Initialization is done with one of:: + + void shake128_init(struct shake_ctx *ctx); + void shake256_init(struct shake_ctx *ctx); + +Data is then added with:: + + void shake_update(struct shake_ctx *ctx, const u8 *in, size_t in_len); + +The update function may be called multiple times if need be to add +non-contiguous data. + +Finally, the output is extracted using:: + + void shake_squeeze(struct shake_ctx *ctx, u8 *out, size_t out_len); =20 and telling it how much data should be extracted. The squeeze function ma= y be called multiple times but it will only append the domain separation suffix= on the first invocation. =20 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. =20 -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); +Once all the desired output has been extracted, zeroize the context:: =20 + void shake_zeroize_ctx(struct shake_ctx *ctx); =20 Convenience API =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 It only a single contiguous buffer of input needs to be added and only a s= ingle @@ -141,87 +120,10 @@ function for each algorithm supported:: 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); =20 =20 -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 and is analogous to the "rate" in= the - algorithm definition. - - * ``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 domain separation suffix and any padding h= ave - been appended to the state to prevent multiple squeezings from XOF - algorithms from re-appending this. - -Note that the size of the digest is *not* included here as that's only nee= ded -at finalisation time for digest algorithms and can be supplied then. It i= s not -relevant to XOFs. - -To make use of the context, the following internal functions are provided:: - - void sha3_update(struct sha3_ctx *ctx, const u8 *data, size_t 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 appended to/absorbed into the state, output to be -extracted/squeezed from the state and for the state to be cleared. Note t= hat -there is no "final" function, per se, but that can be constructed by squee= zing -and clearing. - - Testing =3D=3D=3D=3D=3D=3D=3D =20 To test the SHA-3 code, use sha3_kunit. =20 @@ -239,7 +141,7 @@ References =20 =20 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 =20 -.. kernel-doc:: crypto/lib/sha3.c +.. kernel-doc:: lib/crypto/sha3.c .. kernel-doc:: include/crypto/sha3.h diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h index a54117cb1546b..58d2b3e0663e8 100644 --- a/include/crypto/sha3.h +++ b/include/crypto/sha3.h @@ -36,427 +36,231 @@ =20 #define SHA3_STATE_SIZE 200 =20 struct shash_desc; =20 +int crypto_sha3_init(struct shash_desc *desc); + struct sha3_state { u64 st[SHA3_STATE_SIZE / 8]; }; =20 -/* - * The SHA3 context structure and state buffer. +/** + * Internal context, shared by the digests (SHA3-*) and the XOFs (SHAKE*). * * 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_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 */ }; =20 -int crypto_sha3_init(struct shash_desc *desc); +void __sha3_update(struct __sha3_ctx *ctx, const u8 *in, size_t in_len); +void __sha3_squeeze(struct __sha3_ctx *ctx, u8 *out, size_t out_len); + +/** Context for SHA3-224, SHA3-256, SHA3-384, or SHA3-512 */ +struct sha3_ctx { + struct __sha3_ctx ctx; + u8 digest_size; /* Digest size in bytes */ +}; =20 /** - * 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 initialized again. - * - * Context: Any context. + * Zeroize a sha3_ctx. This is already called by sha3_final(). Call this + * explicitly when abandoning a context without calling sha3_final(). */ -static inline void sha3_clear(struct sha3_ctx *ctx) +static inline void sha3_zeroize_ctx(struct sha3_ctx *ctx) { memzero_explicit(ctx, sizeof(*ctx)); } =20 -void sha3_update(struct sha3_ctx *ctx, const u8 *data, size_t 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; +/** Context for SHAKE128 or SHAKE256 */ +struct shake_ctx { + struct __sha3_ctx ctx; }; =20 -/** - * sha3_224_init() - Set a SHA3 context for SHA3-224 - * @ctx: the context to initialize - * - * Initialize a SHA3 context for the production of a SHA3-224 digest of a - * message. - * - * 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. - * - * Context: Any context. - */ -static inline void sha3_224_update(struct sha3_224_ctx *ctx, const u8 *dat= a, size_t len) +/** Zeroize a shake_ctx. Call this after the last squeeze. */ +static inline void shake_zeroize_ctx(struct shake_ctx *ctx) { - return sha3_update(&ctx->ctx, data, len); + memzero_explicit(ctx, sizeof(*ctx)); } =20 /** - * sha3_224_final() - Finalise a SHA3-224 hash and extract the digest - * @ctx: The context to finalise; must have been initialized - * @out: Where to write the resulting message digest + * sha3_224_init() - Initialize a context for SHA3-224 + * @ctx: The context to initialize * - * 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. + * This begins a new SHA3-224 message digest computation. * * Context: Any context. */ -static inline void sha3_224_final(struct sha3_224_ctx *ctx, u8 out[SHA3_22= 4_DIGEST_SIZE]) +static inline void sha3_224_init(struct sha3_ctx *ctx) { - sha3_squeeze(&ctx->ctx, out, SHA3_224_DIGEST_SIZE); - sha3_clear(&ctx->ctx); + *ctx =3D (struct sha3_ctx){ + .digest_size =3D SHA3_224_DIGEST_SIZE, + .ctx.block_size =3D SHA3_224_BLOCK_SIZE, + .ctx.padding =3D 0x06, + }; } =20 -/* - * 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 initialize + * sha3_256_init() - Initialize a context for SHA3-256 + * @ctx: The context to initialize * - * Initialize a SHA3 context for the production of a SHA3-256 digest of a - * message. + * This begins a new SHA3-256 message digest computation. * * Context: Any context. */ -static inline void sha3_256_init(struct sha3_256_ctx *ctx) +static inline void sha3_256_init(struct sha3_ctx *ctx) { - *ctx =3D (struct sha3_256_ctx){ + *ctx =3D (struct sha3_ctx){ + .digest_size =3D SHA3_256_DIGEST_SIZE, .ctx.block_size =3D SHA3_256_BLOCK_SIZE, .ctx.padding =3D 0x06, }; } =20 /** - * 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. - * - * Context: Any context. - */ -static inline void sha3_256_update(struct sha3_256_ctx *ctx, const u8 *dat= a, size_t 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 initialized - * @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. - * - * Context: Any context. - */ -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 initialize + * sha3_384_init() - Initialize a context for SHA3-384 + * @ctx: The context to initialize * - * Initialize a SHA3 context for the production of a SHA3-384 digest of a - * message. + * This begins a new SHA3-384 message digest computation. * * Context: Any context. */ -static inline void sha3_384_init(struct sha3_384_ctx *ctx) +static inline void sha3_384_init(struct sha3_ctx *ctx) { - *ctx =3D (struct sha3_384_ctx){ + *ctx =3D (struct sha3_ctx){ + .digest_size =3D SHA3_384_DIGEST_SIZE, .ctx.block_size =3D SHA3_384_BLOCK_SIZE, .ctx.padding =3D 0x06, }; } =20 /** - * 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. - * - * Context: Any context. - */ -static inline void sha3_384_update(struct sha3_384_ctx *ctx, const u8 *dat= a, size_t 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 initialized - * @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. - * - * Context: Any context. - */ -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 initialize + * sha3_512_init() - Initialize a context for SHA3-512 + * @ctx: The context to initialize * - * Initialize a SHA3 context for the production of a SHA3-512 digest of a - * message. + * This begins a new SHA3-512 message digest computation. * * Context: Any context. */ -static inline void sha3_512_init(struct sha3_512_ctx *ctx) +static inline void sha3_512_init(struct sha3_ctx *ctx) { - *ctx =3D (struct sha3_512_ctx){ + *ctx =3D (struct sha3_ctx){ + .digest_size =3D SHA3_512_DIGEST_SIZE, .ctx.block_size =3D SHA3_512_BLOCK_SIZE, .ctx.padding =3D 0x06, }; } =20 /** - * 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 + * sha3_update() - Update a SHA-3 digest context with input data + * @ctx: The context to update; must have been initialized + * @in: The input data + * @in_len: Length of the input data in bytes * - * This can be called any number of times to add data to the hash, perform= ing - * the "keccak sponge absorbing" phase. + * This can be called any number of times to add data to a SHA3-224, SHA3-= 256, + * SHA3-384, or SHA3-512 digest (depending on which init function was call= ed). * * Context: Any context. */ -static inline void sha3_512_update(struct sha3_512_ctx *ctx, const u8 *dat= a, size_t len) +static inline void sha3_update(struct sha3_ctx *ctx, + const u8 *in, size_t in_len) { - return sha3_update(&ctx->ctx, data, len); + __sha3_update(&ctx->ctx, in, in_len); } =20 /** - * sha3_512_final() - Finalise a SHA3-512 hash and extract the digest - * @ctx: The context to finalise; must have been initialized - * @out: Where to write the resulting message digest + * sha3_final() - Finish computing a SHA-3 message digest + * @ctx: The context to finalize; must have been initialized + * @out: (output) The resulting SHA3-224, SHA3-256, SHA3-384, or SHA3-512 + * message digest, matching the init function that was called. Note that + * the size differs for each one; see SHA3_*_DIGEST_SIZE. * - * 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. + * After finishing, this zeroizes @ctx. So the caller does not need to do= it. * * Context: Any context. */ -static inline void sha3_512_final(struct sha3_512_ctx *ctx, u8 out[SHA3_51= 2_DIGEST_SIZE]) +static inline void sha3_final(struct sha3_ctx *ctx, u8 *out) { - sha3_squeeze(&ctx->ctx, out, SHA3_512_DIGEST_SIZE); - sha3_clear(&ctx->ctx); + __sha3_squeeze(&ctx->ctx, out, ctx->digest_size); + sha3_zeroize_ctx(ctx); } =20 -/* - * Context wrapper for SHAKE128. - */ -struct shake128_ctx { - struct sha3_ctx ctx; -}; - /** - * shake128_init() - Set a SHA3 context for SHAKE128 + * shake128_init() - Initialize a context for SHAKE128 * @ctx: The context to initialize * - * Initialize 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. + * This begins a new SHAKE128 extendable-output function (XOF) computation. * * Context: Any context. */ -static inline void shake128_init(struct shake128_ctx *ctx) +static inline void shake128_init(struct shake_ctx *ctx) { - *ctx =3D (struct shake128_ctx){ + *ctx =3D (struct shake_ctx){ .ctx.block_size =3D SHAKE128_BLOCK_SIZE, .ctx.padding =3D 0x1f, }; } =20 /** - * 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. - * - * Context: Any context. - */ -static inline void shake128_update(struct shake128_ctx *ctx, const u8 *dat= a, size_t 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: Any context. - */ -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 - * initialized again. - * - * 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 + * shake256_init() - Initialize a context for SHAKE256 * @ctx: The context to initialize * - * Initialize 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. + * This begins a new SHAKE256 extendable-output function (XOF) computation. * * Context: Any context. */ -static inline void shake256_init(struct shake256_ctx *ctx) +static inline void shake256_init(struct shake_ctx *ctx) { - *ctx =3D (struct shake256_ctx){ + *ctx =3D (struct shake_ctx){ .ctx.block_size =3D SHAKE256_BLOCK_SIZE, .ctx.padding =3D 0x1f, }; } =20 /** - * 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. - * - * Context: Any context. - */ -static inline void shake256_update(struct shake256_ctx *ctx, const u8 *dat= a, size_t 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. + * shake_update() - Update a SHAKE context with input data + * @ctx: The context to update; must have been initialized + * @in: The input data + * @in_len: Length of the input data in bytes * - * 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. + * This can be called any number of times to add more input data to SHAKE1= 28 or + * SHAKE256. This cannot be called after squeezing has begun. * * Context: Any context. */ -static inline void shake256_squeeze(struct shake256_ctx *ctx, u8 *out, siz= e_t out_size) +static inline void shake_update(struct shake_ctx *ctx, + const u8 *in, size_t in_len) { - return sha3_squeeze(&ctx->ctx, out, out_size); + __sha3_update(&ctx->ctx, in, in_len); } =20 /** - * shake256_clear() - Explicitly clear the entire SHAKE256 context - * @ctx: the context to clear + * shake_squeeze() - Generate output from SHAKE128 or SHAKE256 + * @ctx: The context to squeeze; must have been initialized + * @out: Where to write the resulting output data + * @out_len: The amount of data to extract to @out in bytes * - * Explicitly clear the entire context; after this, the context must be - * initialized again. + * This may be called multiple times. A number of consecutive squeezes la= id + * end-to-end will yield the same output as one big squeeze generating the= same + * total amount of output. More input cannot be provided after squeezing = has + * begun. After all squeezing has been completed, call shake_zeroize_ctx(= ). * * Context: Any context. */ -static inline void shake256_clear(struct shake256_ctx *ctx) +static inline void shake_squeeze(struct shake_ctx *ctx, + u8 *out, size_t out_len) { - sha3_clear(&ctx->ctx); + return __sha3_squeeze(&ctx->ctx, out, out_len); } =20 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]); diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index 83fbfa1169cdb..6c13a43b0f868 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -177,11 +177,11 @@ static void sha3_keccakf_generic(struct sha3_state *s= tate) =20 for (int i =3D 0; i < ARRAY_SIZE(state->st); i++) cpu_to_le64s(&state->st[i]); } =20 -static void sha3_absorb_block_generic(struct sha3_ctx *ctx, const u8 *data) +static void sha3_absorb_block_generic(struct __sha3_ctx *ctx, const u8 *da= ta) { struct sha3_state *state =3D &ctx->state; size_t bsize =3D ctx->block_size; =20 for (size_t i =3D 0; i < bsize / 8; i++) @@ -191,11 +191,11 @@ static void sha3_absorb_block_generic(struct sha3_ctx= *ctx, const u8 *data) =20 /* * 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, +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; @@ -210,32 +210,21 @@ static void sha3_absorb_blocks_generic(struct sha3_ct= x *ctx, #endif =20 /* * XOR in partial data that's insufficient to fill a whole block. */ -static void sha3_absorb_xorle(struct sha3_ctx *ctx, const u8 *data, +static void sha3_absorb_xorle(struct __sha3_ctx *ctx, const u8 *data, size_t partial, size_t len) { u8 *buf =3D (u8 *)ctx->state.st; =20 buf +=3D partial; for (size_t i =3D 0; i < len; i++) *buf++ ^=3D *data++; } =20 -/** - * 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. - * - * Context: May use the FPU/Vector unit registers. - */ -void sha3_update(struct sha3_ctx *ctx, const u8 *data, size_t len) +void __sha3_update(struct __sha3_ctx *ctx, const u8 *data, size_t len) { size_t absorb_offset =3D ctx->absorb_offset; size_t bsize =3D ctx->block_size; =20 WARN_ON_ONCE(ctx->end_marked); @@ -259,29 +248,13 @@ void sha3_update(struct sha3_ctx *ctx, const u8 *data= , size_t len) if (len) { sha3_absorb_xorle(ctx, data, ctx->absorb_offset, len); ctx->absorb_offset +=3D len; } } -EXPORT_SYMBOL_GPL(sha3_update); +EXPORT_SYMBOL_GPL(__sha3_update); =20 -/** - * 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. - * - * Context: May use the FPU/Vector unit registers. - */ -void sha3_squeeze(struct sha3_ctx *ctx, u8 *out, size_t out_size) +void __sha3_squeeze(struct __sha3_ctx *ctx, u8 *out, size_t out_len) { size_t squeeze_offset =3D ctx->squeeze_offset; size_t bsize =3D ctx->block_size; u8 *p =3D (u8 *)ctx->state.st, end_marker =3D 0x80; =20 @@ -293,27 +266,27 @@ 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); =20 - size_t part =3D umin(out_size, bsize - squeeze_offset); + size_t part =3D umin(out_len, bsize - squeeze_offset); =20 if (part > 0) { memcpy(out, p + squeeze_offset, part); - out_size -=3D part; + out_len -=3D part; out +=3D part; squeeze_offset +=3D part; } - if (!out_size) + if (!out_len) break; if (squeeze_offset >=3D bsize) squeeze_offset =3D 0; } =20 ctx->squeeze_offset =3D squeeze_offset; } -EXPORT_SYMBOL_GPL(sha3_squeeze); +EXPORT_SYMBOL_GPL(__sha3_squeeze); =20 /** * 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 @@ -324,15 +297,15 @@ EXPORT_SYMBOL_GPL(sha3_squeeze); * * 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; + struct sha3_ctx ctx; =20 sha3_224_init(&ctx); - sha3_224_update(&ctx, in, in_len); - sha3_224_final(&ctx, out); + sha3_update(&ctx, in, in_len); + sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_224); =20 /** * sha3_256() - Convenience wrapper to digest a simple buffer as SHA3-256 @@ -345,15 +318,15 @@ EXPORT_SYMBOL_GPL(sha3_224); * * 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; + struct sha3_ctx ctx; =20 sha3_256_init(&ctx); - sha3_256_update(&ctx, in, in_len); - sha3_256_final(&ctx, out); + sha3_update(&ctx, in, in_len); + sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_256); =20 /** * sha3_384() - Convenience wrapper to digest a simple buffer as SHA3-384 @@ -366,15 +339,15 @@ EXPORT_SYMBOL_GPL(sha3_256); * * 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; + struct sha3_ctx ctx; =20 sha3_384_init(&ctx); - sha3_384_update(&ctx, in, in_len); - sha3_384_final(&ctx, out); + sha3_update(&ctx, in, in_len); + sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_384); =20 /** * sha3_512() - Convenience wrapper to digest a simple buffer as SHA3-512 @@ -387,15 +360,15 @@ EXPORT_SYMBOL_GPL(sha3_384); * * 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; + struct sha3_ctx ctx; =20 sha3_512_init(&ctx); - sha3_512_update(&ctx, in, in_len); - sha3_512_final(&ctx, out); + sha3_update(&ctx, in, in_len); + sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_512); =20 /** * shake128() - Convenience wrapper to apply SHAKE128 to a simple buffer @@ -410,16 +383,16 @@ EXPORT_SYMBOL_GPL(sha3_512); * * 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; + struct shake_ctx ctx; =20 shake128_init(&ctx); - shake128_update(&ctx, in, in_len); - shake128_squeeze(&ctx, out, out_len); - shake128_clear(&ctx); + shake_update(&ctx, in, in_len); + shake_squeeze(&ctx, out, out_len); + shake_zeroize_ctx(&ctx); } EXPORT_SYMBOL_GPL(shake128); =20 /** * shake256() - Convenience wrapper to apply SHAKE256 to a simple buffer @@ -434,16 +407,16 @@ EXPORT_SYMBOL_GPL(shake128); * * 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; + struct shake_ctx ctx; =20 shake256_init(&ctx); - shake256_update(&ctx, in, in_len); - shake256_squeeze(&ctx, out, out_len); - shake256_clear(&ctx); + shake_update(&ctx, in, in_len); + shake_squeeze(&ctx, out, out_len); + shake_zeroize_ctx(&ctx); } EXPORT_SYMBOL_GPL(shake256); =20 #if defined(sha3_mod_init_arch) || defined(CONFIG_CRYPTO_FIPS) static int __init sha3_mod_init(void) diff --git a/lib/crypto/tests/sha3_kunit.c b/lib/crypto/tests/sha3_kunit.c index 032fa3950afe4..c2e0c37d8a543 100644 --- a/lib/crypto/tests/sha3_kunit.c +++ b/lib/crypto/tests/sha3_kunit.c @@ -5,15 +5,15 @@ */ #include #include "sha3_testvecs.h" =20 #define HASH sha3_256 -#define HASH_CTX sha3_256_ctx +#define HASH_CTX sha3_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 +#define HASH_UPDATE sha3_update +#define HASH_FINAL sha3_final #include "hash-test-template.h" =20 /* * Sample message and the output generated for various algorithms by passi= ng it * into "openssl sha3-224" etc.. @@ -252,24 +252,25 @@ static void test_shake256_nist(struct kunit *test) * 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; + struct shake_ctx ctx; u8 out[8 + SHA3_512_DIGEST_SIZE + 8]; =20 for (int tile_size =3D 1; tile_size < SHAKE256_DEFAULT_SIZE; tile_size++)= { int left =3D SHAKE256_DEFAULT_SIZE; u8 *p =3D out + 8; =20 memset(out, 0, sizeof(out)); shake256_init(&ctx); - shake256_update(&ctx, test_sha3_sample, sizeof(test_sha3_sample) - 1); + shake_update(&ctx, test_sha3_sample, + sizeof(test_sha3_sample) - 1); while (left > 0) { int part =3D umin(tile_size, left); =20 - shake256_squeeze(&ctx, p, part); + shake_squeeze(&ctx, p, part); p +=3D part; left -=3D part; } =20 KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256), @@ -283,11 +284,11 @@ static void test_shake256_tiling(struct kunit *test) * 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; + struct shake_ctx ctx; u8 out[8 + SHA3_512_DIGEST_SIZE + 8]; =20 for (int first_tile_size =3D 3; first_tile_size < SHAKE256_DEFAULT_SIZE; first_tile_size++) { @@ -295,15 +296,16 @@ static void test_shake256_tiling2(struct kunit *test) int left =3D SHAKE256_DEFAULT_SIZE; u8 *p =3D out + 8; =20 memset(out, 0, sizeof(out)); shake256_init(&ctx); - shake256_update(&ctx, test_sha3_sample, sizeof(test_sha3_sample) - 1); + shake_update(&ctx, test_sha3_sample, + sizeof(test_sha3_sample) - 1); while (left > 0) { int part =3D umin(tile_size, left); =20 - shake256_squeeze(&ctx, p, part); + shake_squeeze(&ctx, p, part); p +=3D part; left -=3D part; tile_size--; if (tile_size < 1) tile_size =3D 5; --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 ECA192222D1; Mon, 20 Oct 2025 00:53:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921617; cv=none; b=gvTucNfv882jLBrfxSDpYrXLDQud6PeJPgHTwPkXAwKHFqyCtwgFU/QwnMlSvuu9dhwnt0EnZWw2iK0mbDuiiCTFs9BDaqW7JyhoNcrW33W/pUucSzxuu/jar0IanCUfR4chAX8VCvgGlgrdlXbIwQrP1Abqmaveh0tDIi3Cvng= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921617; c=relaxed/simple; bh=cOfo+vQJHwt2jR/1l9Mz7dS2z0ta/WcLrt8/j3uJDXU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ENqoUsBXzZkjnZWtFc3qQJkkPu+tBukPDoyRYSfdoriPLxkplGUXE56l3iGxQ+k77A6pJatjk9kiXGn7EtzSyscVR6POjpIYq8MrK4QpENhqlaewwmMCnIhcBpUS0GzQ5n9zPD4OJml19vX1ZHzd3n4MskJkCbXVIDqT62H0ZEY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=HOhzAKtF; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="HOhzAKtF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 928DAC116C6; Mon, 20 Oct 2025 00:53:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921616; bh=cOfo+vQJHwt2jR/1l9Mz7dS2z0ta/WcLrt8/j3uJDXU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HOhzAKtFKZVFysTC8yxErFpISUC2VMzxJyDD4hdrcz3uTIj089WiV2ODOJ9CcZikf Wnrdg6pzK3qd37l9VMFqSh+HhqYmIraNWDgxnLHKmXDbxW4QOAo9e3aqgzI681X7F8 2T/xNT/n69e2pc5tgrP9nGk7sY5Gnj/HKo8uIcEmP5fh7e45rxM6BKOVYluW8bvVQx HTDb0ijna/p2XtzNmpeqGJC6af59j1w9wiqAKySaKq8+wgm9Glj3HxO4bH5IIJrckn zIPtzRoCL+L4Aa5u6mwEvZBRdFjBdfyqPlBGW73nCvNYIBFc6kyZa+4+tpZouJTEg/ PhF3qfNlsLBOQ== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 12/17] lib/crypto: sha3: Document one-shot functions in header and improve docs Date: Sun, 19 Oct 2025 17:50:33 -0700 Message-ID: <20251020005038.661542-13-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" Move kerneldoc for the one-shot functions to the header for the following reasons: - This style is already used in sha1.h, sha2.h, and crypto_shash. And all the inline functions in sha3.h already. - The header is where people who want to call the code usually look. - This way the documentation won't have to be moved each time a function is changed to or from an inline function. Also revise this documentation to fix some errors, be more user focused (rather than focusing on implementation details like whether a context is allocated and zeroized), and be a bit more consistent with sha2.h. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- include/crypto/sha3.h | 75 +++++++++++++++++++++++++++++++++++++++++++ lib/crypto/sha3.c | 70 ---------------------------------------- 2 files changed, 75 insertions(+), 70 deletions(-) diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h index 58d2b3e0663e8..80acdb266b8e3 100644 --- a/include/crypto/sha3.h +++ b/include/crypto/sha3.h @@ -259,13 +259,88 @@ static inline void shake_squeeze(struct shake_ctx *ct= x, u8 *out, size_t out_len) { return __sha3_squeeze(&ctx->ctx, out, out_len); } =20 +/** + * sha3_224() - Compute SHA3-224 digest in one shot + * @in: The input data to be digested + * @in_len: Length of the input data in bytes + * @out: The buffer into which the digest will be stored + * + * Convenience function that computes a SHA3-224 digest. Use this instead= of + * the incremental API if you're able to provide all the input at once. + * + * Context: Any context. + */ void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE]); + +/** + * sha3_256() - Compute SHA3-256 digest in one shot + * @in: The input data to be digested + * @in_len: Length of the input data in bytes + * @out: The buffer into which the digest will be stored + * + * Convenience function that computes a SHA3-256 digest. Use this instead= of + * the incremental API if you're able to provide all the input at once. + * + * Context: Any context. + */ void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE]); + +/** + * sha3_384() - Compute SHA3-384 digest in one shot + * @in: The input data to be digested + * @in_len: Length of the input data in bytes + * @out: The buffer into which the digest will be stored + * + * Convenience function that computes a SHA3-384 digest. Use this instead= of + * the incremental API if you're able to provide all the input at once. + * + * Context: Any context. + */ void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE]); + +/** + * sha3_512() - Compute SHA3-512 digest in one shot + * @in: The input data to be digested + * @in_len: Length of the input data in bytes + * @out: The buffer into which the digest will be stored + * + * Convenience function that computes a SHA3-512 digest. Use this instead= of + * the incremental API if you're able to provide all the input at once. + * + * Context: Any context. + */ void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE]); + +/** + * shake128() - Compute SHAKE128 in one shot + * @in: The input data to be used + * @in_len: Length of the input data in bytes + * @out: The buffer into which the output will be stored + * @out_len: Length of the output to produce in bytes + * + * Convenience function that computes SHAKE128 in one shot. Use this inst= ead of + * the incremental API if you're able to provide all the input at once as = well + * as receive all the output at once. All output lengths are supported. + * + * Context: Any context. + */ void shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len); + +/** + * shake256() - Compute SHAKE256 in one shot + * @in: The input data to be used + * @in_len: Length of the input data in bytes + * @out: The buffer into which the output will be stored + * @out_len: Length of the output to produce in bytes + * + * Convenience function that computes SHAKE256 in one shot. Use this inst= ead of + * the incremental API if you're able to provide all the input at once as = well + * as receive all the output at once. All output lengths are supported. + * + * Context: Any context. + */ void shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len); =20 #endif /* __CRYPTO_SHA3_H__ */ diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index 6c13a43b0f868..6705c1b48da48 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -284,107 +284,50 @@ void __sha3_squeeze(struct __sha3_ctx *ctx, u8 *out,= size_t out_len) =20 ctx->squeeze_offset =3D squeeze_offset; } EXPORT_SYMBOL_GPL(__sha3_squeeze); =20 -/** - * 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. - * - * 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_ctx ctx; =20 sha3_224_init(&ctx); sha3_update(&ctx, in, in_len); sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_224); =20 -/** - * 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. - * - * 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_ctx ctx; =20 sha3_256_init(&ctx); sha3_update(&ctx, in, in_len); sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_256); =20 -/** - * 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. - * - * 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_ctx ctx; =20 sha3_384_init(&ctx); sha3_update(&ctx, in, in_len); sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_384); =20 -/** - * 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. - * - * 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_ctx ctx; =20 sha3_512_init(&ctx); sha3_update(&ctx, in, in_len); sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_512); =20 -/** - * 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. - * - * Context: May use the FPU/Vector unit registers. - */ void shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len) { struct shake_ctx ctx; =20 shake128_init(&ctx); @@ -392,23 +335,10 @@ void shake128(const u8 *in, size_t in_len, u8 *out, s= ize_t out_len) shake_squeeze(&ctx, out, out_len); shake_zeroize_ctx(&ctx); } EXPORT_SYMBOL_GPL(shake128); =20 -/** - * 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. - * - * Context: May use the FPU/Vector unit registers. - */ void shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len) { struct shake_ctx ctx; =20 shake256_init(&ctx); --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 D8A0A22A7E0; Mon, 20 Oct 2025 00:53:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921617; cv=none; b=Pde0DEsMTMqv8gMj1p4i1k40RfJaDfVF74XBO557S8d700yyKrifrcpg2IdKWVsAcL2gZDmMSodNndw2lQL9nbLSzvV7L/TTujKFdHvitS4lp9IhE6kiazbxpNGerQKZxTjEYuMaGKbuaFMUIB8MAidHwlTCI0SfGNx2zUrY5Wg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921617; c=relaxed/simple; bh=Ocy9eV0L13nS4ER5Z553g2xK+fvNl2zjeQzulMWNTqs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=d17jTmdadWSdHUxT7Lvuh4n3m3P+/EPmg1EXaXvmmEm6POQLJKHesPmIInnzKsG1gdENX1YHIsCZvB2eQc6FQOlebe3ehRYSo3Wdb2CwYUVxqmmdMhhI8HDCfo0Sa2PSXBn59/ciXWR/ZAy8CcnGH/GeQTum4XGGkpxcf+eyh5U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=d1889XQw; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="d1889XQw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F1E7AC116B1; Mon, 20 Oct 2025 00:53:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921617; bh=Ocy9eV0L13nS4ER5Z553g2xK+fvNl2zjeQzulMWNTqs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=d1889XQwlMFMZELdIY0pVdzdGDHKZMMIpa1KwIwJxItnBfErqrrYXn0Mi5bTrkO4u 2R4ON00DsyPINlQD9Q1p9BOqrd7GxCO7KmKCDgEmc0wXPmFXVu8K5t1hOFU9iwGzhv SlMGoDxgTI5jxSqdF2zZZSWzQKb90cQR2z2h3B5rgy76Fn6ADuW3aqyCJHepGaHoQU A2pF5Il18C4YeyDQhSITVFCkKv9nzR2Dwtm7uLDDQaHmx0ip9ObuOgplpqu3KkPrM7 kJRahMDUX4opNuo2rEdSemNh5X0jltrnArbX/IjXF3BDRFu2cbtiY8brPAjKrujwNe 1pLJZ4TuTQ3Yw== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 13/17] crypto: arm64/sha3 - Update sha3_ce_transform() to prepare for library Date: Sun, 19 Oct 2025 17:50:34 -0700 Message-ID: <20251020005038.661542-14-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" - Use size_t lengths, to match the library. - Pass the block size instead of digest size, and add support for the block size that SHAKE128 uses. This allows the code to be used with SHAKE128 and SHAKE256, which don't have the concept of a digest size. SHAKE256 has the same block size as SHA3-256, but SHAKE128 has a unique block size. Thus, there are now 5 supported block sizes. Don't bother changing the "glue" code arm64_ce_transform() too much, as it gets deleted when the SHA-3 code is migrated into lib/crypto/ anyway. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- arch/arm64/crypto/sha3-ce-core.S | 66 ++++++++++++++++---------------- arch/arm64/crypto/sha3-ce-glue.c | 11 +++--- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/arch/arm64/crypto/sha3-ce-core.S b/arch/arm64/crypto/sha3-ce-c= ore.S index 9c77313f5a608..62477848821d9 100644 --- a/arch/arm64/crypto/sha3-ce-core.S +++ b/arch/arm64/crypto/sha3-ce-core.S @@ -35,11 +35,15 @@ .macro xar, rd, rn, rm, imm6 .inst 0xce800000 | .L\rd | (.L\rn << 5) | ((\imm6) << 10) | (.L\rm << 16) .endm =20 /* - * int sha3_ce_transform(u64 *st, const u8 *data, int blocks, int dg_size) + * size_t sha3_ce_transform(struct sha3_state *state, const u8 *data, + * size_t nblocks, size_t block_size) + * + * block_size is assumed to be one of 72 (SHA3-512), 104 (SHA3-384), 136 + * (SHA3-256 and SHAKE256), 144 (SHA3-224), or 168 (SHAKE128). */ .text SYM_FUNC_START(sha3_ce_transform) /* load state */ add x8, x0, #32 @@ -49,62 +53,58 @@ SYM_FUNC_START(sha3_ce_transform) ld1 {v12.1d-v15.1d}, [x8], #32 ld1 {v16.1d-v19.1d}, [x8], #32 ld1 {v20.1d-v23.1d}, [x8], #32 ld1 {v24.1d}, [x8] =20 -0: sub w2, w2, #1 +0: sub x2, x2, #1 mov w8, #24 adr_l x9, .Lsha3_rcon =20 /* load input */ ld1 {v25.8b-v28.8b}, [x1], #32 - ld1 {v29.8b-v31.8b}, [x1], #24 + ld1 {v29.8b}, [x1], #8 eor v0.8b, v0.8b, v25.8b eor v1.8b, v1.8b, v26.8b eor v2.8b, v2.8b, v27.8b eor v3.8b, v3.8b, v28.8b eor v4.8b, v4.8b, v29.8b - eor v5.8b, v5.8b, v30.8b - eor v6.8b, v6.8b, v31.8b - - tbnz x3, #6, 2f // SHA3-512 =20 ld1 {v25.8b-v28.8b}, [x1], #32 - ld1 {v29.8b-v30.8b}, [x1], #16 - eor v7.8b, v7.8b, v25.8b - eor v8.8b, v8.8b, v26.8b - eor v9.8b, v9.8b, v27.8b - eor v10.8b, v10.8b, v28.8b - eor v11.8b, v11.8b, v29.8b - eor v12.8b, v12.8b, v30.8b + eor v5.8b, v5.8b, v25.8b + eor v6.8b, v6.8b, v26.8b + eor v7.8b, v7.8b, v27.8b + eor v8.8b, v8.8b, v28.8b + cmp x3, #72 + b.eq 3f /* SHA3-512 (block_size=3D72)? */ =20 - tbnz x3, #4, 1f // SHA3-384 or SHA3-224 + ld1 {v25.8b-v28.8b}, [x1], #32 + eor v9.8b, v9.8b, v25.8b + eor v10.8b, v10.8b, v26.8b + eor v11.8b, v11.8b, v27.8b + eor v12.8b, v12.8b, v28.8b + cmp x3, #104 + b.eq 3f /* SHA3-384 (block_size=3D104)? */ =20 - // SHA3-256 ld1 {v25.8b-v28.8b}, [x1], #32 eor v13.8b, v13.8b, v25.8b eor v14.8b, v14.8b, v26.8b eor v15.8b, v15.8b, v27.8b eor v16.8b, v16.8b, v28.8b - b 3f - -1: tbz x3, #2, 3f // bit 2 cleared? SHA-384 + cmp x3, #144 + b.lt 3f /* SHA3-256 or SHAKE256 (block_size=3D136)? */ + b.eq 2f /* SHA3-224 (block_size=3D144)? */ =20 - // SHA3-224 + /* SHAKE128 (block_size=3D168) */ ld1 {v25.8b-v28.8b}, [x1], #32 - ld1 {v29.8b}, [x1], #8 - eor v13.8b, v13.8b, v25.8b - eor v14.8b, v14.8b, v26.8b - eor v15.8b, v15.8b, v27.8b - eor v16.8b, v16.8b, v28.8b - eor v17.8b, v17.8b, v29.8b + eor v17.8b, v17.8b, v25.8b + eor v18.8b, v18.8b, v26.8b + eor v19.8b, v19.8b, v27.8b + eor v20.8b, v20.8b, v28.8b b 3f - - // SHA3-512 -2: ld1 {v25.8b-v26.8b}, [x1], #16 - eor v7.8b, v7.8b, v25.8b - eor v8.8b, v8.8b, v26.8b +2: + ld1 {v25.8b}, [x1], #8 /* SHA3-224 (block_size=3D144) */ + eor v17.8b, v17.8b, v25.8b =20 3: sub w8, w8, #1 =20 eor3 v29.16b, v4.16b, v9.16b, v14.16b eor3 v26.16b, v1.16b, v6.16b, v11.16b @@ -183,21 +183,21 @@ SYM_FUNC_START(sha3_ce_transform) =20 eor v0.16b, v0.16b, v31.16b =20 cbnz w8, 3b cond_yield 4f, x8, x9 - cbnz w2, 0b + cbnz x2, 0b =20 /* save state */ 4: st1 { v0.1d- v3.1d}, [x0], #32 st1 { v4.1d- v7.1d}, [x0], #32 st1 { v8.1d-v11.1d}, [x0], #32 st1 {v12.1d-v15.1d}, [x0], #32 st1 {v16.1d-v19.1d}, [x0], #32 st1 {v20.1d-v23.1d}, [x0], #32 st1 {v24.1d}, [x0] - mov w0, w2 + mov x0, x2 ret SYM_FUNC_END(sha3_ce_transform) =20 .section ".rodata", "a" .align 8 diff --git a/arch/arm64/crypto/sha3-ce-glue.c b/arch/arm64/crypto/sha3-ce-g= lue.c index 426d8044535ab..f4eae798371ef 100644 --- a/arch/arm64/crypto/sha3-ce-glue.c +++ b/arch/arm64/crypto/sha3-ce-glue.c @@ -26,30 +26,29 @@ MODULE_LICENSE("GPL v2"); MODULE_ALIAS_CRYPTO("sha3-224"); MODULE_ALIAS_CRYPTO("sha3-256"); MODULE_ALIAS_CRYPTO("sha3-384"); MODULE_ALIAS_CRYPTO("sha3-512"); =20 -asmlinkage int sha3_ce_transform(u64 *st, const u8 *data, int blocks, - int md_len); +asmlinkage size_t sha3_ce_transform(struct sha3_state *state, const u8 *da= ta, + size_t nblocks, size_t block_size); =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 crypto_shash *tfm =3D desc->tfm; - unsigned int bs, ds; + unsigned int bs; int blocks; =20 - ds =3D crypto_shash_digestsize(tfm); bs =3D crypto_shash_blocksize(tfm); blocks =3D len / bs; len -=3D blocks * bs; do { int rem; =20 kernel_neon_begin(); - rem =3D sha3_ce_transform(sctx->st, data, blocks, ds); + rem =3D sha3_ce_transform(sctx, data, blocks, bs); kernel_neon_end(); data +=3D (blocks - rem) * bs; blocks =3D rem; } while (blocks); return len; @@ -72,11 +71,11 @@ static int arm64_sha3_finup(struct shash_desc *desc, co= nst u8 *src, unsigned int block[len++] =3D 0x06; memset(block + len, 0, bs - len); block[bs - 1] |=3D 0x80; =20 kernel_neon_begin(); - sha3_ce_transform(sctx->st, block, 1, ds); + sha3_ce_transform(sctx, block, 1, bs); kernel_neon_end(); memzero_explicit(block , sizeof(block)); =20 for (i =3D 0; i < ds / 8; i++) put_unaligned_le64(sctx->st[i], digest++); --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 1C4F523371B; Mon, 20 Oct 2025 00:53:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921618; cv=none; b=L0JyZ4f1E6vp8O/Hsi6FnOWOys+2BZQvFvw+Q7s3H3o/2flllp24joBFXPFB/4wTOThNOsNu4Mkay5EI5D5UX2ZUaISpvNo0ei3D/HVmHECMq9ILBiGXjbCp7kbw8LOJBL3MCbDlR9uFjrVjO1LNeFKK66voIxFXQWFPqh+KZyE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921618; c=relaxed/simple; bh=B9VMbVog0Y1HY4eF9BgSn2ZAQ7f9RGz3bUChSX1584o=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UTFgtVDB0PM+go6PC/vZ59/pX/vS+aprN2og7Gcr4hlGombbbNosjZQlxIOEwUOlJD6ciAaf6OY0hmTRhuZBlc/js4W3LTROmUAZis7Fz26qUBdBCYnYFi7/7+96idVaU1WzCmKkx429vntJxgffesvv++SiuzFeKGo9ByeIDLQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rWUMBtOc; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rWUMBtOc" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 62F2BC113D0; Mon, 20 Oct 2025 00:53:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921617; bh=B9VMbVog0Y1HY4eF9BgSn2ZAQ7f9RGz3bUChSX1584o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rWUMBtOc/yw/GtX+q8dnaAPv4VvD/vcKV7vDgV2eFrncL8o4IXFGmxsKx+OzMO2Qd 7MwyjXZYkTw7wwWi5iIMhAqkqhJwIvncAoULe2andUCjvPie2mAlG/Fyryuy+RJe2b UD/hUaUdHYPGMF9tCDDAZevtcBscawlHsPYXg6QBzI1kAn6nGBDhrTyQof6qmpDgvB 1B6nY642N604Zb51R0B1iUf+Z0tTMOhvERW7ukSnF+OrunZa/GkRu1y9WfIQYNWKxq vJsvwpAK+1p2SiU2neXOThDNWY+PoyaFaOgBzp7ICwpo+4vadG9e5ab2hCQ25kQLbb zVHTlHYDACqFg== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 14/17] lib/crypto: arm64/sha3: Migrate optimized code into library Date: Sun, 19 Oct 2025 17:50:35 -0700 Message-ID: <20251020005038.661542-15-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" Instead of exposing the arm64-optimized SHA-3 code via arm64-specific crypto_shash algorithms, instead just implement the sha3_absorb_blocks() and sha3_keccakf() library functions. This is much simpler, it makes the SHA-3 library functions be arm64-optimized, and it fixes the longstanding issue where the arm64-optimized SHA-3 code was disabled by default. SHA-3 still remains available through crypto_shash, but individual architectures no longer need to handle it. Note: to see the diff from arch/arm64/crypto/sha3-ce-glue.c to lib/crypto/arm64/sha3.h, view this commit with 'git show -M10'. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- arch/arm64/configs/defconfig | 2 +- arch/arm64/crypto/Kconfig | 11 -- arch/arm64/crypto/Makefile | 3 - arch/arm64/crypto/sha3-ce-glue.c | 150 ------------------ lib/crypto/Kconfig | 5 + lib/crypto/Makefile | 5 + .../crypto/arm64}/sha3-ce-core.S | 0 lib/crypto/arm64/sha3.h | 64 ++++++++ 8 files changed, 75 insertions(+), 165 deletions(-) delete mode 100644 arch/arm64/crypto/sha3-ce-glue.c rename {arch/arm64/crypto =3D> lib/crypto/arm64}/sha3-ce-core.S (100%) create mode 100644 lib/crypto/arm64/sha3.h diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index e3a2d37bd1042..20dd3a39faead 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -1781,14 +1781,14 @@ CONFIG_SECURITY=3Dy CONFIG_CRYPTO_USER=3Dy CONFIG_CRYPTO_CHACHA20=3Dm CONFIG_CRYPTO_BENCHMARK=3Dm CONFIG_CRYPTO_ECHAINIV=3Dy CONFIG_CRYPTO_MICHAEL_MIC=3Dm +CONFIG_CRYPTO_SHA3=3Dm CONFIG_CRYPTO_ANSI_CPRNG=3Dy CONFIG_CRYPTO_USER_API_RNG=3Dm CONFIG_CRYPTO_GHASH_ARM64_CE=3Dy -CONFIG_CRYPTO_SHA3_ARM64=3Dm CONFIG_CRYPTO_SM3_ARM64_CE=3Dm CONFIG_CRYPTO_AES_ARM64_CE_BLK=3Dy CONFIG_CRYPTO_AES_ARM64_BS=3Dm CONFIG_CRYPTO_AES_ARM64_CE_CCM=3Dy CONFIG_CRYPTO_DEV_SUN8I_CE=3Dm diff --git a/arch/arm64/crypto/Kconfig b/arch/arm64/crypto/Kconfig index 91f3093eee6ab..376d6b50743ff 100644 --- a/arch/arm64/crypto/Kconfig +++ b/arch/arm64/crypto/Kconfig @@ -23,21 +23,10 @@ config CRYPTO_NHPOLY1305_NEON NHPoly1305 hash function (Adiantum) =20 Architecture: arm64 using: - NEON (Advanced SIMD) extensions =20 -config CRYPTO_SHA3_ARM64 - tristate "Hash functions: SHA-3 (ARMv8.2 Crypto Extensions)" - depends on KERNEL_MODE_NEON - select CRYPTO_HASH - select CRYPTO_SHA3 - help - SHA-3 secure hash algorithms (FIPS 202) - - Architecture: arm64 using: - - ARMv8.2 Crypto Extensions - config CRYPTO_SM3_NEON tristate "Hash functions: SM3 (NEON)" depends on KERNEL_MODE_NEON select CRYPTO_HASH select CRYPTO_LIB_SM3 diff --git a/arch/arm64/crypto/Makefile b/arch/arm64/crypto/Makefile index a8b2cdbe202c1..fd3d590fa1137 100644 --- a/arch/arm64/crypto/Makefile +++ b/arch/arm64/crypto/Makefile @@ -3,13 +3,10 @@ # linux/arch/arm64/crypto/Makefile # # Copyright (C) 2014 Linaro Ltd # =20 -obj-$(CONFIG_CRYPTO_SHA3_ARM64) +=3D sha3-ce.o -sha3-ce-y :=3D sha3-ce-glue.o sha3-ce-core.o - obj-$(CONFIG_CRYPTO_SM3_NEON) +=3D sm3-neon.o sm3-neon-y :=3D sm3-neon-glue.o sm3-neon-core.o =20 obj-$(CONFIG_CRYPTO_SM3_ARM64_CE) +=3D sm3-ce.o sm3-ce-y :=3D sm3-ce-glue.o sm3-ce-core.o diff --git a/arch/arm64/crypto/sha3-ce-glue.c b/arch/arm64/crypto/sha3-ce-g= lue.c deleted file mode 100644 index f4eae798371ef..0000000000000 --- a/arch/arm64/crypto/sha3-ce-glue.c +++ /dev/null @@ -1,150 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * sha3-ce-glue.c - core SHA-3 transform using v8.2 Crypto Extensions - * - * Copyright (C) 2018 Linaro Ltd - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_DESCRIPTION("SHA3 secure hash using ARMv8 Crypto Extensions"); -MODULE_AUTHOR("Ard Biesheuvel "); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS_CRYPTO("sha3-224"); -MODULE_ALIAS_CRYPTO("sha3-256"); -MODULE_ALIAS_CRYPTO("sha3-384"); -MODULE_ALIAS_CRYPTO("sha3-512"); - -asmlinkage size_t sha3_ce_transform(struct sha3_state *state, const u8 *da= ta, - size_t nblocks, size_t block_size); - -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 crypto_shash *tfm =3D desc->tfm; - unsigned int bs; - int blocks; - - bs =3D crypto_shash_blocksize(tfm); - blocks =3D len / bs; - len -=3D blocks * bs; - do { - int rem; - - kernel_neon_begin(); - rem =3D sha3_ce_transform(sctx, data, blocks, bs); - kernel_neon_end(); - data +=3D (blocks - rem) * bs; - blocks =3D rem; - } while (blocks); - return len; -} - -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; - __le64 *digest =3D (__le64 *)out; - u8 block[SHA3_224_BLOCK_SIZE]; - unsigned int bs, ds; - int i; - - ds =3D crypto_shash_digestsize(tfm); - bs =3D crypto_shash_blocksize(tfm); - memcpy(block, src, len); - - block[len++] =3D 0x06; - memset(block + len, 0, bs - len); - block[bs - 1] |=3D 0x80; - - kernel_neon_begin(); - sha3_ce_transform(sctx, block, 1, bs); - kernel_neon_end(); - memzero_explicit(block , sizeof(block)); - - for (i =3D 0; i < ds / 8; i++) - put_unaligned_le64(sctx->st[i], digest++); - - if (ds & 4) - put_unaligned_le32(sctx->st[i], (__le32 *)digest); - - return 0; -} - -static struct shash_alg algs[] =3D { { - .digestsize =3D SHA3_224_DIGEST_SIZE, - .init =3D crypto_sha3_init, - .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", - .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .base.cra_blocksize =3D SHA3_224_BLOCK_SIZE, - .base.cra_module =3D THIS_MODULE, - .base.cra_priority =3D 200, -}, { - .digestsize =3D SHA3_256_DIGEST_SIZE, - .init =3D crypto_sha3_init, - .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", - .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .base.cra_blocksize =3D SHA3_256_BLOCK_SIZE, - .base.cra_module =3D THIS_MODULE, - .base.cra_priority =3D 200, -}, { - .digestsize =3D SHA3_384_DIGEST_SIZE, - .init =3D crypto_sha3_init, - .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", - .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .base.cra_blocksize =3D SHA3_384_BLOCK_SIZE, - .base.cra_module =3D THIS_MODULE, - .base.cra_priority =3D 200, -}, { - .digestsize =3D SHA3_512_DIGEST_SIZE, - .init =3D crypto_sha3_init, - .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", - .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .base.cra_blocksize =3D SHA3_512_BLOCK_SIZE, - .base.cra_module =3D THIS_MODULE, - .base.cra_priority =3D 200, -} }; - -static int __init sha3_neon_mod_init(void) -{ - return crypto_register_shashes(algs, ARRAY_SIZE(algs)); -} - -static void __exit sha3_neon_mod_fini(void) -{ - crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); -} - -module_cpu_feature_match(SHA3, sha3_neon_mod_init); -module_exit(sha3_neon_mod_fini); diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index 1caf3fbe24bff..544eb67fe70f4 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -189,10 +189,15 @@ config CRYPTO_LIB_SHA3 help The SHA3 library functions. Select this if your module uses any of these functions from . =20 +config CRYPTO_LIB_SHA3_ARCH + bool + depends on CRYPTO_LIB_SHA3 && !UML + default y if ARM64 && KERNEL_MODE_NEON + config CRYPTO_LIB_SM3 tristate =20 source "lib/crypto/tests/Kconfig" =20 diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index 2f15cef850507..f638bff0fb081 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -269,10 +269,15 @@ endif # CONFIG_CRYPTO_LIB_SHA512_ARCH ##########################################################################= ###### =20 obj-$(CONFIG_CRYPTO_LIB_SHA3) +=3D libsha3.o libsha3-y :=3D sha3.o =20 +ifeq ($(CONFIG_CRYPTO_LIB_SHA3_ARCH),y) +CFLAGS_sha3.o +=3D -I$(src)/$(SRCARCH) +libsha3-$(CONFIG_ARM64) +=3D arm64/sha3-ce-core.o +endif # CONFIG_CRYPTO_LIB_SHA3_ARCH + ##########################################################################= ###### =20 obj-$(CONFIG_MPILIB) +=3D mpi/ =20 obj-$(CONFIG_CRYPTO_SELFTESTS_FULL) +=3D simd.o diff --git a/arch/arm64/crypto/sha3-ce-core.S b/lib/crypto/arm64/sha3-ce-co= re.S similarity index 100% rename from arch/arm64/crypto/sha3-ce-core.S rename to lib/crypto/arm64/sha3-ce-core.S diff --git a/lib/crypto/arm64/sha3.h b/lib/crypto/arm64/sha3.h new file mode 100644 index 0000000000000..286c519eecd5a --- /dev/null +++ b/lib/crypto/arm64/sha3.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Linaro Ltd + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_sha3); + +asmlinkage size_t sha3_ce_transform(struct sha3_state *state, const u8 *da= ta, + size_t nblocks, size_t block_size); + +static void sha3_absorb_blocks(struct __sha3_ctx *ctx, + const u8 *data, size_t nblocks) +{ + size_t block_size =3D ctx->block_size; + + if (static_branch_likely(&have_sha3) && likely(may_use_simd())) { + do { + size_t rem; + + kernel_neon_begin(); + rem =3D sha3_ce_transform(&ctx->state, data, nblocks, + block_size); + kernel_neon_end(); + data +=3D (nblocks - rem) * block_size; + nblocks =3D rem; + } while (nblocks); + } else { + sha3_absorb_blocks_generic(ctx, data, nblocks); + } +} + +static void sha3_keccakf(struct sha3_state *state) +{ + if (static_branch_likely(&have_sha3) && likely(may_use_simd())) { + /* + * Passing zeroes into sha3_ce_transform() gives the plain + * Keccak-f permutation, which is what we want here. Any + * supported block size may be used. Use SHA3_512_BLOCK_SIZE + * since it's the shortest. + */ + static const u8 zeroes[SHA3_512_BLOCK_SIZE]; + + kernel_neon_begin(); + sha3_ce_transform(state, zeroes, 1, sizeof(zeroes)); + kernel_neon_end(); + } else { + sha3_keccakf_generic(state); + } +} + +#define sha3_mod_init_arch sha3_mod_init_arch +static void sha3_mod_init_arch(void) +{ + if (cpu_have_named_feature(SHA3)) + static_branch_enable(&have_sha3); +} --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 338B3192B84; Mon, 20 Oct 2025 00:53:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921618; cv=none; b=O4db8zTTn7QR3tJTo525jHfyJSjx+3pmFDXq1HNfTQr1g5b8d0Ch8jz/szIxirkHYgl5Iif8JwjVVdpJ0GH40Amhw1BK0bv0U32ti49AHfYNtbhRa2apSUwjvtOrr67A0c5rlIwm0YmSSabGYcUU2ddhPhxdU5LS1h9sNHoi2Ao= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921618; c=relaxed/simple; bh=zXkMPjNQfeAh7+9lKU8XzQRbjmrE7OEmEaBqTzm61Ic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eLjFYeWSBaJxydCzy0l0JsnLu84Cc5N5ZVIB4k1ORdtmk50FT1eFWQp9R2uWipHrjZF/xdLP+iloTEGx/Fjy1jdICy7U6TBkhSYtXtfLAObVFIY5CAPqyfVw5gD2+JAxZUHKo6mcDUn5sQwZHyp7nCrUSP9DfKefiCCCS0ta/3o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FMf79vK7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FMf79vK7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C8F10C4CEE7; Mon, 20 Oct 2025 00:53:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921618; bh=zXkMPjNQfeAh7+9lKU8XzQRbjmrE7OEmEaBqTzm61Ic=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FMf79vK7BhWJm1/j27q2jylG8NJxDE0tTvhYvkg10FR/aKnoQXZeozp2NIjtGhN48 +kbPHC1uBrhheosAw//vmKyuK4mtPd4xvgEL6uDuAb53kHrx3n/10VTRBBEKkDjPYh fXRdUq03JkHqnurwJSgnfHVhBXL5+4fa9/MlkrUIUos+XGnKYV6RlrtpmNhEsrT7uD KPQEhXivMQyqvRQ2cqvIgG9u5yJXhwisAlWSHILCiBHKfY5kEY3vOg/VN4gINiP6nc W2uO8dERfy9RmHT7NfC86n82QMdMEWdOLDLXSunHUUWQypTcn0FcVsEEDWZv+zSbvx g4/Bky0kB6Eyg== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 15/17] lib/crypto: s390/sha3: Migrate optimized code into library Date: Sun, 19 Oct 2025 17:50:36 -0700 Message-ID: <20251020005038.661542-16-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" Instead of exposing the s390-optimized SHA-3 code via s390-specific crypto_shash algorithms, instead just implement the sha3_absorb_blocks() and sha3_keccakf() library functions. This is much simpler, it makes the SHA-3 library functions be s390-optimized, and it fixes the longstanding issue where the s390-optimized SHA-3 code was disabled by default. SHA-3 still remains available through crypto_shash, but individual architectures no longer need to handle it. Note that the existing code used both CPACF_KIMD_SHA3_224 and CPACF_KIMD_SHA3_256 after checking for just CPACF_KIMD_SHA3_256, and similarly for 384 and 512. I've preserved that behavior. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- arch/s390/configs/debug_defconfig | 3 +- arch/s390/configs/defconfig | 3 +- arch/s390/crypto/Kconfig | 20 ---- arch/s390/crypto/Makefile | 2 - arch/s390/crypto/sha.h | 51 ---------- arch/s390/crypto/sha3_256_s390.c | 157 ------------------------------ arch/s390/crypto/sha3_512_s390.c | 157 ------------------------------ arch/s390/crypto/sha_common.c | 117 ---------------------- lib/crypto/Kconfig | 1 + lib/crypto/s390/sha3.h | 76 +++++++++++++++ 10 files changed, 79 insertions(+), 508 deletions(-) delete mode 100644 arch/s390/crypto/sha.h delete mode 100644 arch/s390/crypto/sha3_256_s390.c delete mode 100644 arch/s390/crypto/sha3_512_s390.c delete mode 100644 arch/s390/crypto/sha_common.c create mode 100644 lib/crypto/s390/sha3.h diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_de= fconfig index b31c1df902577..5fdfebcfd50f2 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig @@ -790,10 +790,11 @@ CONFIG_CRYPTO_GCM=3Dy CONFIG_CRYPTO_SEQIV=3Dy CONFIG_CRYPTO_MD4=3Dm CONFIG_CRYPTO_MD5=3Dy CONFIG_CRYPTO_MICHAEL_MIC=3Dm CONFIG_CRYPTO_RMD160=3Dm +CONFIG_CRYPTO_SHA3=3Dm CONFIG_CRYPTO_SM3_GENERIC=3Dm CONFIG_CRYPTO_WP512=3Dm CONFIG_CRYPTO_XCBC=3Dm CONFIG_CRYPTO_CRC32=3Dm CONFIG_CRYPTO_842=3Dm @@ -803,12 +804,10 @@ CONFIG_CRYPTO_ZSTD=3Dm CONFIG_CRYPTO_ANSI_CPRNG=3Dm CONFIG_CRYPTO_USER_API_HASH=3Dm CONFIG_CRYPTO_USER_API_SKCIPHER=3Dm CONFIG_CRYPTO_USER_API_RNG=3Dm CONFIG_CRYPTO_USER_API_AEAD=3Dm -CONFIG_CRYPTO_SHA3_256_S390=3Dm -CONFIG_CRYPTO_SHA3_512_S390=3Dm CONFIG_CRYPTO_GHASH_S390=3Dm CONFIG_CRYPTO_AES_S390=3Dm CONFIG_CRYPTO_DES_S390=3Dm CONFIG_CRYPTO_HMAC_S390=3Dm CONFIG_ZCRYPT=3Dm diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index 161dad7ef211a..7bac3f53a95b0 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig @@ -774,10 +774,11 @@ CONFIG_CRYPTO_GCM=3Dy CONFIG_CRYPTO_SEQIV=3Dy CONFIG_CRYPTO_MD4=3Dm CONFIG_CRYPTO_MD5=3Dy CONFIG_CRYPTO_MICHAEL_MIC=3Dm CONFIG_CRYPTO_RMD160=3Dm +CONFIG_CRYPTO_SHA3=3Dm CONFIG_CRYPTO_SM3_GENERIC=3Dm CONFIG_CRYPTO_WP512=3Dm CONFIG_CRYPTO_XCBC=3Dm CONFIG_CRYPTO_CRC32=3Dm CONFIG_CRYPTO_842=3Dm @@ -788,12 +789,10 @@ CONFIG_CRYPTO_ANSI_CPRNG=3Dm CONFIG_CRYPTO_JITTERENTROPY_OSR=3D1 CONFIG_CRYPTO_USER_API_HASH=3Dm CONFIG_CRYPTO_USER_API_SKCIPHER=3Dm CONFIG_CRYPTO_USER_API_RNG=3Dm CONFIG_CRYPTO_USER_API_AEAD=3Dm -CONFIG_CRYPTO_SHA3_256_S390=3Dm -CONFIG_CRYPTO_SHA3_512_S390=3Dm CONFIG_CRYPTO_GHASH_S390=3Dm CONFIG_CRYPTO_AES_S390=3Dm CONFIG_CRYPTO_DES_S390=3Dm CONFIG_CRYPTO_HMAC_S390=3Dm CONFIG_ZCRYPT=3Dm diff --git a/arch/s390/crypto/Kconfig b/arch/s390/crypto/Kconfig index 03f73fbd38b62..f838ca055f6d7 100644 --- a/arch/s390/crypto/Kconfig +++ b/arch/s390/crypto/Kconfig @@ -1,29 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 =20 menu "Accelerated Cryptographic Algorithms for CPU (s390)" =20 -config CRYPTO_SHA3_256_S390 - tristate "Hash functions: SHA3-224 and SHA3-256" - select CRYPTO_HASH - help - SHA3-224 and SHA3-256 secure hash algorithms (FIPS 202) - - Architecture: s390 - - It is available as of z14. - -config CRYPTO_SHA3_512_S390 - tristate "Hash functions: SHA3-384 and SHA3-512" - select CRYPTO_HASH - help - SHA3-384 and SHA3-512 secure hash algorithms (FIPS 202) - - Architecture: s390 - - It is available as of z14. - config CRYPTO_GHASH_S390 tristate "Hash functions: GHASH" select CRYPTO_HASH help GCM GHASH hash function (NIST SP800-38D) diff --git a/arch/s390/crypto/Makefile b/arch/s390/crypto/Makefile index 998f4b656b18e..387a229e10381 100644 --- a/arch/s390/crypto/Makefile +++ b/arch/s390/crypto/Makefile @@ -1,12 +1,10 @@ # SPDX-License-Identifier: GPL-2.0 # # Cryptographic API # =20 -obj-$(CONFIG_CRYPTO_SHA3_256_S390) +=3D sha3_256_s390.o sha_common.o -obj-$(CONFIG_CRYPTO_SHA3_512_S390) +=3D sha3_512_s390.o sha_common.o obj-$(CONFIG_CRYPTO_DES_S390) +=3D des_s390.o obj-$(CONFIG_CRYPTO_AES_S390) +=3D aes_s390.o obj-$(CONFIG_CRYPTO_PAES_S390) +=3D paes_s390.o obj-$(CONFIG_S390_PRNG) +=3D prng.o obj-$(CONFIG_CRYPTO_GHASH_S390) +=3D ghash_s390.o diff --git a/arch/s390/crypto/sha.h b/arch/s390/crypto/sha.h deleted file mode 100644 index b9cd9572dd35c..0000000000000 --- a/arch/s390/crypto/sha.h +++ /dev/null @@ -1,51 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Cryptographic API. - * - * s390 generic implementation of the SHA Secure Hash Algorithms. - * - * Copyright IBM Corp. 2007 - * Author(s): Jan Glauber (jang@de.ibm.com) - */ -#ifndef _CRYPTO_ARCH_S390_SHA_H -#define _CRYPTO_ARCH_S390_SHA_H - -#include -#include -#include -#include -#include - -/* must be big enough for the largest SHA variant */ -#define CPACF_MAX_PARMBLOCK_SIZE SHA3_STATE_SIZE -#define SHA_MAX_BLOCK_SIZE SHA3_224_BLOCK_SIZE - -struct s390_sha_ctx { - u64 count; /* message length in bytes */ - union { - u32 state[CPACF_MAX_PARMBLOCK_SIZE / sizeof(u32)]; - struct { - u64 state[SHA512_DIGEST_SIZE / sizeof(u64)]; - u64 count_hi; - } sha512; - struct { - __le64 state[SHA3_STATE_SIZE / sizeof(u64)]; - } sha3; - }; - int func; /* KIMD function to use */ - bool first_message_part; -}; - -struct shash_desc; - -int s390_sha_update_blocks(struct shash_desc *desc, const u8 *data, - unsigned int len); -int s390_sha_finup(struct shash_desc *desc, const u8 *src, unsigned int le= n, - u8 *out); - -static inline void __check_s390_sha_ctx_size(void) -{ - BUILD_BUG_ON(S390_SHA_CTX_SIZE !=3D sizeof(struct s390_sha_ctx)); -} - -#endif diff --git a/arch/s390/crypto/sha3_256_s390.c b/arch/s390/crypto/sha3_256_s= 390.c deleted file mode 100644 index fd5ecae60a572..0000000000000 --- a/arch/s390/crypto/sha3_256_s390.c +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Cryptographic API. - * - * s390 implementation of the SHA256 and SHA224 Secure Hash Algorithm. - * - * s390 Version: - * Copyright IBM Corp. 2019 - * Author(s): Joerg Schmidbauer (jschmidb@de.ibm.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sha.h" - -static int s390_sha3_256_init(struct shash_desc *desc) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - - sctx->first_message_part =3D test_facility(86); - if (!sctx->first_message_part) - memset(sctx->state, 0, sizeof(sctx->state)); - sctx->count =3D 0; - sctx->func =3D CPACF_KIMD_SHA3_256; - - return 0; -} - -static int s390_sha3_256_export(struct shash_desc *desc, void *out) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - union { - u8 *u8; - u64 *u64; - } p =3D { .u8 =3D out }; - int i; - - if (sctx->first_message_part) { - memset(out, 0, SHA3_STATE_SIZE); - return 0; - } - for (i =3D 0; i < SHA3_STATE_SIZE / 8; i++) - put_unaligned(le64_to_cpu(sctx->sha3.state[i]), p.u64++); - return 0; -} - -static int s390_sha3_256_import(struct shash_desc *desc, const void *in) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - union { - const u8 *u8; - const u64 *u64; - } p =3D { .u8 =3D in }; - int i; - - for (i =3D 0; i < SHA3_STATE_SIZE / 8; i++) - sctx->sha3.state[i] =3D cpu_to_le64(get_unaligned(p.u64++)); - sctx->count =3D 0; - sctx->first_message_part =3D 0; - sctx->func =3D CPACF_KIMD_SHA3_256; - - return 0; -} - -static int s390_sha3_224_import(struct shash_desc *desc, const void *in) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - - s390_sha3_256_import(desc, in); - sctx->func =3D CPACF_KIMD_SHA3_224; - return 0; -} - -static struct shash_alg sha3_256_alg =3D { - .digestsize =3D SHA3_256_DIGEST_SIZE, /* =3D 32 */ - .init =3D s390_sha3_256_init, - .update =3D s390_sha_update_blocks, - .finup =3D s390_sha_finup, - .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 { - .cra_name =3D "sha3-256", - .cra_driver_name =3D "sha3-256-s390", - .cra_priority =3D 300, - .cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .cra_blocksize =3D SHA3_256_BLOCK_SIZE, - .cra_module =3D THIS_MODULE, - } -}; - -static int s390_sha3_224_init(struct shash_desc *desc) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - - s390_sha3_256_init(desc); - sctx->func =3D CPACF_KIMD_SHA3_224; - return 0; -} - -static struct shash_alg sha3_224_alg =3D { - .digestsize =3D SHA3_224_DIGEST_SIZE, - .init =3D s390_sha3_224_init, - .update =3D s390_sha_update_blocks, - .finup =3D s390_sha_finup, - .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 { - .cra_name =3D "sha3-224", - .cra_driver_name =3D "sha3-224-s390", - .cra_priority =3D 300, - .cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .cra_blocksize =3D SHA3_224_BLOCK_SIZE, - .cra_module =3D THIS_MODULE, - } -}; - -static int __init sha3_256_s390_init(void) -{ - int ret; - - if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_256)) - return -ENODEV; - - ret =3D crypto_register_shash(&sha3_256_alg); - if (ret < 0) - goto out; - - ret =3D crypto_register_shash(&sha3_224_alg); - if (ret < 0) - crypto_unregister_shash(&sha3_256_alg); -out: - return ret; -} - -static void __exit sha3_256_s390_fini(void) -{ - crypto_unregister_shash(&sha3_224_alg); - crypto_unregister_shash(&sha3_256_alg); -} - -module_cpu_feature_match(S390_CPU_FEATURE_MSA, sha3_256_s390_init); -module_exit(sha3_256_s390_fini); - -MODULE_ALIAS_CRYPTO("sha3-256"); -MODULE_ALIAS_CRYPTO("sha3-224"); -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SHA3-256 and SHA3-224 Secure Hash Algorithm"); diff --git a/arch/s390/crypto/sha3_512_s390.c b/arch/s390/crypto/sha3_512_s= 390.c deleted file mode 100644 index f4b52a3a04339..0000000000000 --- a/arch/s390/crypto/sha3_512_s390.c +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Cryptographic API. - * - * s390 implementation of the SHA512 and SHA384 Secure Hash Algorithm. - * - * Copyright IBM Corp. 2019 - * Author(s): Joerg Schmidbauer (jschmidb@de.ibm.com) - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sha.h" - -static int s390_sha3_512_init(struct shash_desc *desc) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - - sctx->first_message_part =3D test_facility(86); - if (!sctx->first_message_part) - memset(sctx->state, 0, sizeof(sctx->state)); - sctx->count =3D 0; - sctx->func =3D CPACF_KIMD_SHA3_512; - - return 0; -} - -static int s390_sha3_512_export(struct shash_desc *desc, void *out) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - union { - u8 *u8; - u64 *u64; - } p =3D { .u8 =3D out }; - int i; - - if (sctx->first_message_part) { - memset(out, 0, SHA3_STATE_SIZE); - return 0; - } - for (i =3D 0; i < SHA3_STATE_SIZE / 8; i++) - put_unaligned(le64_to_cpu(sctx->sha3.state[i]), p.u64++); - return 0; -} - -static int s390_sha3_512_import(struct shash_desc *desc, const void *in) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - union { - const u8 *u8; - const u64 *u64; - } p =3D { .u8 =3D in }; - int i; - - for (i =3D 0; i < SHA3_STATE_SIZE / 8; i++) - sctx->sha3.state[i] =3D cpu_to_le64(get_unaligned(p.u64++)); - sctx->count =3D 0; - sctx->first_message_part =3D 0; - sctx->func =3D CPACF_KIMD_SHA3_512; - - return 0; -} - -static int s390_sha3_384_import(struct shash_desc *desc, const void *in) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - - s390_sha3_512_import(desc, in); - sctx->func =3D CPACF_KIMD_SHA3_384; - return 0; -} - -static struct shash_alg sha3_512_alg =3D { - .digestsize =3D SHA3_512_DIGEST_SIZE, - .init =3D s390_sha3_512_init, - .update =3D s390_sha_update_blocks, - .finup =3D s390_sha_finup, - .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 { - .cra_name =3D "sha3-512", - .cra_driver_name =3D "sha3-512-s390", - .cra_priority =3D 300, - .cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .cra_blocksize =3D SHA3_512_BLOCK_SIZE, - .cra_module =3D THIS_MODULE, - } -}; - -MODULE_ALIAS_CRYPTO("sha3-512"); - -static int s390_sha3_384_init(struct shash_desc *desc) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - - s390_sha3_512_init(desc); - sctx->func =3D CPACF_KIMD_SHA3_384; - return 0; -} - -static struct shash_alg sha3_384_alg =3D { - .digestsize =3D SHA3_384_DIGEST_SIZE, - .init =3D s390_sha3_384_init, - .update =3D s390_sha_update_blocks, - .finup =3D s390_sha_finup, - .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 { - .cra_name =3D "sha3-384", - .cra_driver_name =3D "sha3-384-s390", - .cra_priority =3D 300, - .cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .cra_blocksize =3D SHA3_384_BLOCK_SIZE, - .cra_ctxsize =3D sizeof(struct s390_sha_ctx), - .cra_module =3D THIS_MODULE, - } -}; - -MODULE_ALIAS_CRYPTO("sha3-384"); - -static int __init init(void) -{ - int ret; - - if (!cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_512)) - return -ENODEV; - ret =3D crypto_register_shash(&sha3_512_alg); - if (ret < 0) - goto out; - ret =3D crypto_register_shash(&sha3_384_alg); - if (ret < 0) - crypto_unregister_shash(&sha3_512_alg); -out: - return ret; -} - -static void __exit fini(void) -{ - crypto_unregister_shash(&sha3_512_alg); - crypto_unregister_shash(&sha3_384_alg); -} - -module_cpu_feature_match(S390_CPU_FEATURE_MSA, init); -module_exit(fini); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SHA3-512 and SHA3-384 Secure Hash Algorithm"); diff --git a/arch/s390/crypto/sha_common.c b/arch/s390/crypto/sha_common.c deleted file mode 100644 index d6f8396187946..0000000000000 --- a/arch/s390/crypto/sha_common.c +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Cryptographic API. - * - * s390 generic implementation of the SHA Secure Hash Algorithms. - * - * Copyright IBM Corp. 2007 - * Author(s): Jan Glauber (jang@de.ibm.com) - */ - -#include -#include -#include -#include -#include "sha.h" - -int s390_sha_update_blocks(struct shash_desc *desc, const u8 *data, - unsigned int len) -{ - unsigned int bsize =3D crypto_shash_blocksize(desc->tfm); - struct s390_sha_ctx *ctx =3D shash_desc_ctx(desc); - unsigned int n; - int fc; - - fc =3D ctx->func; - if (ctx->first_message_part) - fc |=3D CPACF_KIMD_NIP; - - /* process as many blocks as possible */ - n =3D (len / bsize) * bsize; - ctx->count +=3D n; - switch (ctx->func) { - case CPACF_KLMD_SHA_512: - case CPACF_KLMD_SHA3_384: - if (ctx->count < n) - ctx->sha512.count_hi++; - break; - } - cpacf_kimd(fc, ctx->state, data, n); - ctx->first_message_part =3D 0; - return len - n; -} -EXPORT_SYMBOL_GPL(s390_sha_update_blocks); - -static int s390_crypto_shash_parmsize(int func) -{ - switch (func) { - case CPACF_KLMD_SHA_1: - return 20; - case CPACF_KLMD_SHA_256: - return 32; - case CPACF_KLMD_SHA_512: - return 64; - case CPACF_KLMD_SHA3_224: - case CPACF_KLMD_SHA3_256: - case CPACF_KLMD_SHA3_384: - case CPACF_KLMD_SHA3_512: - return 200; - default: - return -EINVAL; - } -} - -int s390_sha_finup(struct shash_desc *desc, const u8 *src, unsigned int le= n, - u8 *out) -{ - struct s390_sha_ctx *ctx =3D shash_desc_ctx(desc); - int mbl_offset, fc; - u64 bits; - - ctx->count +=3D len; - - bits =3D ctx->count * 8; - mbl_offset =3D s390_crypto_shash_parmsize(ctx->func); - if (mbl_offset < 0) - return -EINVAL; - - mbl_offset =3D mbl_offset / sizeof(u32); - - /* set total msg bit length (mbl) in CPACF parmblock */ - switch (ctx->func) { - case CPACF_KLMD_SHA_512: - /* The SHA512 parmblock has a 128-bit mbl field. */ - if (ctx->count < len) - ctx->sha512.count_hi++; - ctx->sha512.count_hi <<=3D 3; - ctx->sha512.count_hi |=3D ctx->count >> 61; - mbl_offset +=3D sizeof(u64) / sizeof(u32); - fallthrough; - case CPACF_KLMD_SHA_1: - case CPACF_KLMD_SHA_256: - memcpy(ctx->state + mbl_offset, &bits, sizeof(bits)); - break; - case CPACF_KLMD_SHA3_224: - case CPACF_KLMD_SHA3_256: - case CPACF_KLMD_SHA3_384: - case CPACF_KLMD_SHA3_512: - break; - default: - return -EINVAL; - } - - fc =3D ctx->func; - fc |=3D test_facility(86) ? CPACF_KLMD_DUFOP : 0; - if (ctx->first_message_part) - fc |=3D CPACF_KLMD_NIP; - cpacf_klmd(fc, ctx->state, src, len); - - /* copy digest to out */ - memcpy(out, ctx->state, crypto_shash_digestsize(desc->tfm)); - - return 0; -} -EXPORT_SYMBOL_GPL(s390_sha_finup); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("s390 SHA cipher common functions"); diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index 544eb67fe70f4..36bb4b94d0123 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -193,10 +193,11 @@ config CRYPTO_LIB_SHA3 =20 config CRYPTO_LIB_SHA3_ARCH bool depends on CRYPTO_LIB_SHA3 && !UML default y if ARM64 && KERNEL_MODE_NEON + default y if S390 =20 config CRYPTO_LIB_SM3 tristate =20 source "lib/crypto/tests/Kconfig" diff --git a/lib/crypto/s390/sha3.h b/lib/crypto/s390/sha3.h new file mode 100644 index 0000000000000..c08a192cc01a0 --- /dev/null +++ b/lib/crypto/s390/sha3.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * SHA-3 optimized using the CP Assist for Cryptographic Functions (CPACF) + * + * Copyright 2025 Google LLC + */ +#include +#include + +static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_cpacf_sha3_256); +static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_cpacf_sha3_512); + +static void sha3_absorb_blocks(struct __sha3_ctx *ctx, + const u8 *data, size_t nblocks) +{ + /* + * Note that since the library functions keep the sha3_state in little + * endian order, there is no need to convert it to little endian before + * invoking CPACF_KIMD_SHA3_*, which also assume little endian order. + */ + if (static_branch_likely(&have_cpacf_sha3_256)) { + if (ctx->block_size =3D=3D SHA3_224_BLOCK_SIZE) { + cpacf_kimd(CPACF_KIMD_SHA3_224, &ctx->state, data, + nblocks * SHA3_224_BLOCK_SIZE); + return; + } + if (ctx->block_size =3D=3D SHA3_256_BLOCK_SIZE) { + cpacf_kimd(CPACF_KIMD_SHA3_256, &ctx->state, data, + nblocks * SHA3_256_BLOCK_SIZE); + return; + } + } + if (static_branch_likely(&have_cpacf_sha3_512)) { + if (ctx->block_size =3D=3D SHA3_384_BLOCK_SIZE) { + cpacf_kimd(CPACF_KIMD_SHA3_384, &ctx->state, data, + nblocks * SHA3_384_BLOCK_SIZE); + return; + } + if (ctx->block_size =3D=3D SHA3_512_BLOCK_SIZE) { + cpacf_kimd(CPACF_KIMD_SHA3_512, &ctx->state, data, + nblocks * SHA3_512_BLOCK_SIZE); + return; + } + } + sha3_absorb_blocks_generic(ctx, data, nblocks); +} + +static void sha3_keccakf(struct sha3_state *state) +{ + if (static_branch_likely(&have_cpacf_sha3_512)) { + /* + * Passing zeroes into any of CPACF_KIMD_SHA3_* gives the plain + * Keccak-f permutation, which is what we want here. Use + * SHA3-512 since it has the smallest block size. + * + * Also, as in sha3_absorb_blocks(), the state needn't be + * converted to little endian. It already is little endian. + */ + static const u8 zeroes[SHA3_512_BLOCK_SIZE]; + + cpacf_kimd(CPACF_KIMD_SHA3_512, state, zeroes, sizeof(zeroes)); + } else { + sha3_keccakf_generic(state); + } +} + +#define sha3_mod_init_arch sha3_mod_init_arch +static void sha3_mod_init_arch(void) +{ + if (cpu_have_feature(S390_CPU_FEATURE_MSA)) { + if (cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_256)) + static_branch_enable(&have_cpacf_sha3_256); + if (cpacf_query_func(CPACF_KIMD, CPACF_KIMD_SHA3_512)) + static_branch_enable(&have_cpacf_sha3_512); + } +} --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 D8D9C23E320; Mon, 20 Oct 2025 00:53:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921619; cv=none; b=C5JjdyW6S5JoHrphHJZ+oJWzAFmCWL6GA8TiTyoEAn7BWEp1MSRNzAife3QbBdveN+n5D7e0t3EyD1zzBnf5hzqIGgMUCl8fb6DQ5YzCc0ORsQl7MtzK03lrfP0Bm0wY/61XlyvqISKaWFX+eKTFTxyHI40Cw04Q1plPlxJo3BM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921619; c=relaxed/simple; bh=C2S+qsv86X6YHw0RsYoz1ghvx9MVynx7qbxPFYMhHRI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gh+B59XlZelUgt5qK0O9r6RXRvnJrJ5w/E8a6qj8UVpg/5sTR0+JpFvTh5YKwswAGbmn8TvcwApFl7JFxLdnA9yexr5cQSwHa+OKenKOHu6jG2FrofEhJzEpj4Dd7ULFJM6/6lqohc5Su/QxnmvgABrlcb/uVjx5sS4DGGhT134= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=btBxdSoK; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="btBxdSoK" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 34F10C116D0; Mon, 20 Oct 2025 00:53:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921618; bh=C2S+qsv86X6YHw0RsYoz1ghvx9MVynx7qbxPFYMhHRI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=btBxdSoKK8eYo3dLvauelp0i1L3qqEStWYUk3UWxMcbn+VLvQcBpCicN0lqNtUvfL b72Ofqo+Qobk3gyo8/SYRFBVjb16+TEDVc3e07Nd59SbNJzZDJSldkTWua7lXgvYZ7 hGA+RnNVhh2BLaQq+Jgb5Z0J5KfF6LNb3dqpaZ/wPhq43KGEI+tqDGvnrsTewNKnk/ Mqr4vRGZSUv4+FZPZ5P0hJs4Fjwh+ogDkkZU2Kirgcvdj4DLOYhY083846AAWRmvet kMnHKLRVfhGnz+nw1FZJJOWyBLlYRpmRZM0tF4aMQ/HTl2J0ExvYgonVCIrZQJorMs axuWAhPVFSguw== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 16/17] crypto: jitterentropy - use default sha3 implementation Date: Sun, 19 Oct 2025 17:50:37 -0700 Message-ID: <20251020005038.661542-17-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" Make jitterentropy use "sha3-256" instead of "sha3-256-generic", as the ability to explicitly request the generic code is going away. It's not worth providing a special generic API just for jitterentropy. There are many other solutions available to it, such as doing more iterations or using a more effective jitter collection method. Moreover, the status quo is that SHA-3 is quite slow anyway. Currently only arm64 and s390 have architecture-optimized SHA-3 code. I'm not familiar with the performance of the s390 one, but the arm64 one isn't actually that much faster than the generic code anyway. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- crypto/jitterentropy-kcapi.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/crypto/jitterentropy-kcapi.c b/crypto/jitterentropy-kcapi.c index a53de7affe8d1..7c880cf34c523 100644 --- a/crypto/jitterentropy-kcapi.c +++ b/crypto/jitterentropy-kcapi.c @@ -46,11 +46,11 @@ #include #include =20 #include "jitterentropy.h" =20 -#define JENT_CONDITIONING_HASH "sha3-256-generic" +#define JENT_CONDITIONING_HASH "sha3-256" =20 /*************************************************************************= ** * Helper function *************************************************************************= **/ =20 @@ -228,19 +228,11 @@ static int jent_kcapi_init(struct crypto_tfm *tfm) struct shash_desc *sdesc; int size, ret =3D 0; =20 spin_lock_init(&rng->jent_lock); =20 - /* - * Use SHA3-256 as conditioner. We allocate only the generic - * implementation as we are not interested in high-performance. The - * execution time of the SHA3 operation is measured and adds to the - * Jitter RNG's unpredictable behavior. If we have a slower hash - * implementation, the execution timing variations are larger. When - * using a fast implementation, we would need to call it more often - * as its variations are lower. - */ + /* Use SHA3-256 as conditioner */ hash =3D crypto_alloc_shash(JENT_CONDITIONING_HASH, 0, 0); if (IS_ERR(hash)) { pr_err("Cannot allocate conditioning digest\n"); return PTR_ERR(hash); } --=20 2.51.1.dirty From nobody Sat Feb 7 15:12:04 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 F109A23EAAB; Mon, 20 Oct 2025 00:53:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921619; cv=none; b=lsQymO0/DTZUp3Nkn6TqbV0gLRKydGw7xsz/U3AInbKZK7hL+ERFRdPzQMEX9tsTphewjXJAAVz3d/8ww+AozhS+1Fyab3ZnDKLc3Z2xzeI9E9QQ4Bk/UkT1rQURED0NLPBFTZf4HzH5dg5gJ9QPWjfzNpGSxQFESko+fsCqvIo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1760921619; c=relaxed/simple; bh=9E/oxCgX41HnPpWMcFJ0We246vE2Bta3Snh9PVG52FQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=W7qlChJ5ma2AO68o0c/XLgsoHr/sR62M37MVlscFDQt18VQhQsMpoY2uujkdn0Uql5mq9yfgMybmEDlkrrghxz7Chb6YXiJIgeYrG86fa+s77at85I1hvpsa5/nuVDMTEPkkZ9ixoyOkWvQW86LWtoNwzCf6SZnYmjCb71I0LsM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=lGDihxeI; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="lGDihxeI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 94B60C113D0; Mon, 20 Oct 2025 00:53:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1760921618; bh=9E/oxCgX41HnPpWMcFJ0We246vE2Bta3Snh9PVG52FQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lGDihxeIfRVoToSLxel9R0D9htVG0xijl8HjZ45oSkM9/hNOxBhjr4tcRMBfm2BR+ rzIVqnQnwHaqhEE2l1TJz/L2zW9HCPLGUcm7cSH+BhTSBTe3oiMYykQXbp+HFehaZM dK9Q0VwnfdddGGcumj1h4MjAkOfHUzMZmYFb8r2S0cNXhHtJwhRBA5O9EKyLKoaiGV 27wi2ypICMfWicMF0ry+Ocrcajau7IHtn3L/A8MW84FKCywHuA9O0hfdgVQBOc/BQn bwQv3A2e7qoLzvYnNjcbUWynWJS3TN9qecGaBOy0g465Cp5UUrq6Pn/unpYCGT5t8N eV9UvjwhcTHng== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, Eric Biggers Subject: [PATCH 17/17] crypto: sha3 - Reimplement using library API Date: Sun, 19 Oct 2025 17:50:38 -0700 Message-ID: <20251020005038.661542-18-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251020005038.661542-1-ebiggers@kernel.org> References: <20251020005038.661542-1-ebiggers@kernel.org> 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 Content-Type: text/plain; charset="utf-8" Replace sha3_generic.c with a new file sha3.c which implements the SHA-3 crypto_shash algorithms on top of the SHA-3 library API. Change the driver name suffix from "-generic" to "-lib" to reflect that these algorithms now just use the (possibly arch-optimized) library. This closely mirrors crypto/{md5,sha1,sha256,sha512,blake2b}.c. Implement export_core and import_core since crypto/hmac.c expects these to be present. (Not like HMAC is needed with SHA-3 anyway, but dropping support for it could be viewed as a regression.) Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel --- crypto/Makefile | 2 +- crypto/sha3.c | 172 +++++++++++++++++++++++++ crypto/sha3_generic.c | 290 ------------------------------------------ crypto/testmgr.c | 8 ++ include/crypto/sha3.h | 4 - 5 files changed, 181 insertions(+), 295 deletions(-) create mode 100644 crypto/sha3.c delete mode 100644 crypto/sha3_generic.c diff --git a/crypto/Makefile b/crypto/Makefile index e430e6e99b6a2..657e15ba1fd7d 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -76,11 +76,11 @@ obj-$(CONFIG_CRYPTO_MD4) +=3D md4.o obj-$(CONFIG_CRYPTO_MD5) +=3D md5.o obj-$(CONFIG_CRYPTO_RMD160) +=3D rmd160.o obj-$(CONFIG_CRYPTO_SHA1) +=3D sha1.o obj-$(CONFIG_CRYPTO_SHA256) +=3D sha256.o obj-$(CONFIG_CRYPTO_SHA512) +=3D sha512.o -obj-$(CONFIG_CRYPTO_SHA3) +=3D sha3_generic.o +obj-$(CONFIG_CRYPTO_SHA3) +=3D sha3.o obj-$(CONFIG_CRYPTO_SM3_GENERIC) +=3D sm3_generic.o obj-$(CONFIG_CRYPTO_STREEBOG) +=3D streebog_generic.o obj-$(CONFIG_CRYPTO_WP512) +=3D wp512.o CFLAGS_wp512.o :=3D $(call cc-option,-fno-schedule-insns) # https://gcc.g= nu.org/bugzilla/show_bug.cgi?id=3D79149 obj-$(CONFIG_CRYPTO_BLAKE2B) +=3D blake2b_generic.o diff --git a/crypto/sha3.c b/crypto/sha3.c new file mode 100644 index 0000000000000..90c14841cb6b6 --- /dev/null +++ b/crypto/sha3.c @@ -0,0 +1,172 @@ +// 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 + */ +#include +#include +#include +#include +#include + +#define SHA3_CTX(desc) ((struct sha3_ctx *)shash_desc_ctx(desc)) + +static int crypto_sha3_224_init(struct shash_desc *desc) +{ + sha3_224_init(SHA3_CTX(desc)); + return 0; +} + +static int crypto_sha3_256_init(struct shash_desc *desc) +{ + sha3_256_init(SHA3_CTX(desc)); + return 0; +} + +static int crypto_sha3_384_init(struct shash_desc *desc) +{ + sha3_384_init(SHA3_CTX(desc)); + return 0; +} + +static int crypto_sha3_512_init(struct shash_desc *desc) +{ + sha3_512_init(SHA3_CTX(desc)); + return 0; +} + +static int crypto_sha3_update(struct shash_desc *desc, const u8 *data, + unsigned int len) +{ + sha3_update(SHA3_CTX(desc), data, len); + return 0; +} + +static int crypto_sha3_final(struct shash_desc *desc, u8 *out) +{ + sha3_final(SHA3_CTX(desc), out); + return 0; +} + +static int crypto_sha3_224_digest(struct shash_desc *desc, + const u8 *data, unsigned int len, u8 *out) +{ + sha3_224(data, len, out); + return 0; +} + +static int crypto_sha3_256_digest(struct shash_desc *desc, + const u8 *data, unsigned int len, u8 *out) +{ + sha3_256(data, len, out); + return 0; +} + +static int crypto_sha3_384_digest(struct shash_desc *desc, + const u8 *data, unsigned int len, u8 *out) +{ + sha3_384(data, len, out); + return 0; +} + +static int crypto_sha3_512_digest(struct shash_desc *desc, + const u8 *data, unsigned int len, u8 *out) +{ + sha3_512(data, len, out); + return 0; +} + +static int crypto_sha3_export_core(struct shash_desc *desc, void *out) +{ + memcpy(out, SHA3_CTX(desc), sizeof(struct sha3_ctx)); + return 0; +} + +static int crypto_sha3_import_core(struct shash_desc *desc, const void *in) +{ + memcpy(SHA3_CTX(desc), in, sizeof(struct sha3_ctx)); + return 0; +} + +static struct shash_alg algs[] =3D { { + .digestsize =3D SHA3_224_DIGEST_SIZE, + .init =3D crypto_sha3_224_init, + .update =3D crypto_sha3_update, + .final =3D crypto_sha3_final, + .digest =3D crypto_sha3_224_digest, + .export_core =3D crypto_sha3_export_core, + .import_core =3D crypto_sha3_import_core, + .descsize =3D sizeof(struct sha3_ctx), + .base.cra_name =3D "sha3-224", + .base.cra_driver_name =3D "sha3-224-lib", + .base.cra_blocksize =3D SHA3_224_BLOCK_SIZE, + .base.cra_module =3D THIS_MODULE, +}, { + .digestsize =3D SHA3_256_DIGEST_SIZE, + .init =3D crypto_sha3_256_init, + .update =3D crypto_sha3_update, + .final =3D crypto_sha3_final, + .digest =3D crypto_sha3_256_digest, + .export_core =3D crypto_sha3_export_core, + .import_core =3D crypto_sha3_import_core, + .descsize =3D sizeof(struct sha3_ctx), + .base.cra_name =3D "sha3-256", + .base.cra_driver_name =3D "sha3-256-lib", + .base.cra_blocksize =3D SHA3_256_BLOCK_SIZE, + .base.cra_module =3D THIS_MODULE, +}, { + .digestsize =3D SHA3_384_DIGEST_SIZE, + .init =3D crypto_sha3_384_init, + .update =3D crypto_sha3_update, + .final =3D crypto_sha3_final, + .digest =3D crypto_sha3_384_digest, + .export_core =3D crypto_sha3_export_core, + .import_core =3D crypto_sha3_import_core, + .descsize =3D sizeof(struct sha3_ctx), + .base.cra_name =3D "sha3-384", + .base.cra_driver_name =3D "sha3-384-lib", + .base.cra_blocksize =3D SHA3_384_BLOCK_SIZE, + .base.cra_module =3D THIS_MODULE, +}, { + .digestsize =3D SHA3_512_DIGEST_SIZE, + .init =3D crypto_sha3_512_init, + .update =3D crypto_sha3_update, + .final =3D crypto_sha3_final, + .digest =3D crypto_sha3_512_digest, + .export_core =3D crypto_sha3_export_core, + .import_core =3D crypto_sha3_import_core, + .descsize =3D sizeof(struct sha3_ctx), + .base.cra_name =3D "sha3-512", + .base.cra_driver_name =3D "sha3-512-lib", + .base.cra_blocksize =3D SHA3_512_BLOCK_SIZE, + .base.cra_module =3D THIS_MODULE, +} }; + +static int __init crypto_sha3_mod_init(void) +{ + return crypto_register_shashes(algs, ARRAY_SIZE(algs)); +} +module_init(crypto_sha3_mod_init); + +static void __exit crypto_sha3_mod_exit(void) +{ + crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); +} +module_exit(crypto_sha3_mod_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm"); + +MODULE_ALIAS_CRYPTO("sha3-224"); +MODULE_ALIAS_CRYPTO("sha3-224-lib"); +MODULE_ALIAS_CRYPTO("sha3-256"); +MODULE_ALIAS_CRYPTO("sha3-256-lib"); +MODULE_ALIAS_CRYPTO("sha3-384"); +MODULE_ALIAS_CRYPTO("sha3-384-lib"); +MODULE_ALIAS_CRYPTO("sha3-512"); +MODULE_ALIAS_CRYPTO("sha3-512-lib"); diff --git a/crypto/sha3_generic.c b/crypto/sha3_generic.c deleted file mode 100644 index 41d1e506e6dea..0000000000000 --- a/crypto/sha3_generic.c +++ /dev/null @@ -1,290 +0,0 @@ -// 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 - */ -#include -#include -#include -#include -#include -#include - -/* - * 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]) -{ - int round; - - for (round =3D 0; round < KECCAK_ROUNDS; round++) { - keccakf_round(st); - /* Iota */ - st[0] ^=3D keccakf_rndc[round]; - } -} - -int crypto_sha3_init(struct shash_desc *desc) -{ - struct sha3_state *sctx =3D shash_desc_ctx(desc); - - memset(sctx->st, 0, sizeof(sctx->st)); - return 0; -} -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; - - 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); - return len; -} - -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); - - return 0; -} - -static struct shash_alg algs[] =3D { { - .digestsize =3D SHA3_224_DIGEST_SIZE, - .init =3D crypto_sha3_init, - .update =3D crypto_sha3_update, - .finup =3D crypto_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, - .base.cra_name =3D "sha3-224", - .base.cra_driver_name =3D "sha3-224-generic", - .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .base.cra_blocksize =3D SHA3_224_BLOCK_SIZE, - .base.cra_module =3D THIS_MODULE, -}, { - .digestsize =3D SHA3_256_DIGEST_SIZE, - .init =3D crypto_sha3_init, - .update =3D crypto_sha3_update, - .finup =3D crypto_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, - .base.cra_name =3D "sha3-256", - .base.cra_driver_name =3D "sha3-256-generic", - .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .base.cra_blocksize =3D SHA3_256_BLOCK_SIZE, - .base.cra_module =3D THIS_MODULE, -}, { - .digestsize =3D SHA3_384_DIGEST_SIZE, - .init =3D crypto_sha3_init, - .update =3D crypto_sha3_update, - .finup =3D crypto_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, - .base.cra_name =3D "sha3-384", - .base.cra_driver_name =3D "sha3-384-generic", - .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .base.cra_blocksize =3D SHA3_384_BLOCK_SIZE, - .base.cra_module =3D THIS_MODULE, -}, { - .digestsize =3D SHA3_512_DIGEST_SIZE, - .init =3D crypto_sha3_init, - .update =3D crypto_sha3_update, - .finup =3D crypto_sha3_finup, - .descsize =3D SHA3_STATE_SIZE, - .base.cra_name =3D "sha3-512", - .base.cra_driver_name =3D "sha3-512-generic", - .base.cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .base.cra_blocksize =3D SHA3_512_BLOCK_SIZE, - .base.cra_module =3D THIS_MODULE, -} }; - -static int __init sha3_generic_mod_init(void) -{ - return crypto_register_shashes(algs, ARRAY_SIZE(algs)); -} - -static void __exit sha3_generic_mod_fini(void) -{ - crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); -} - -module_init(sha3_generic_mod_init); -module_exit(sha3_generic_mod_fini); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SHA-3 Secure Hash Algorithm"); - -MODULE_ALIAS_CRYPTO("sha3-224"); -MODULE_ALIAS_CRYPTO("sha3-224-generic"); -MODULE_ALIAS_CRYPTO("sha3-256"); -MODULE_ALIAS_CRYPTO("sha3-256-generic"); -MODULE_ALIAS_CRYPTO("sha3-384"); -MODULE_ALIAS_CRYPTO("sha3-384-generic"); -MODULE_ALIAS_CRYPTO("sha3-512"); -MODULE_ALIAS_CRYPTO("sha3-512-generic"); diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 6a490aaa71b9a..bf56877ff179d 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -5098,31 +5098,35 @@ static const struct alg_test_desc alg_test_descs[] = =3D { .suite =3D { .hash =3D __VECS(hmac_sha256_tv_template) } }, { .alg =3D "hmac(sha3-224)", + .generic_driver =3D "hmac(sha3-224-lib)", .test =3D alg_test_hash, .fips_allowed =3D 1, .suite =3D { .hash =3D __VECS(hmac_sha3_224_tv_template) } }, { .alg =3D "hmac(sha3-256)", + .generic_driver =3D "hmac(sha3-256-lib)", .test =3D alg_test_hash, .fips_allowed =3D 1, .suite =3D { .hash =3D __VECS(hmac_sha3_256_tv_template) } }, { .alg =3D "hmac(sha3-384)", + .generic_driver =3D "hmac(sha3-384-lib)", .test =3D alg_test_hash, .fips_allowed =3D 1, .suite =3D { .hash =3D __VECS(hmac_sha3_384_tv_template) } }, { .alg =3D "hmac(sha3-512)", + .generic_driver =3D "hmac(sha3-512-lib)", .test =3D alg_test_hash, .fips_allowed =3D 1, .suite =3D { .hash =3D __VECS(hmac_sha3_512_tv_template) } @@ -5472,31 +5476,35 @@ static const struct alg_test_desc alg_test_descs[] = =3D { .suite =3D { .hash =3D __VECS(sha256_tv_template) } }, { .alg =3D "sha3-224", + .generic_driver =3D "sha3-224-lib", .test =3D alg_test_hash, .fips_allowed =3D 1, .suite =3D { .hash =3D __VECS(sha3_224_tv_template) } }, { .alg =3D "sha3-256", + .generic_driver =3D "sha3-256-lib", .test =3D alg_test_hash, .fips_allowed =3D 1, .suite =3D { .hash =3D __VECS(sha3_256_tv_template) } }, { .alg =3D "sha3-384", + .generic_driver =3D "sha3-384-lib", .test =3D alg_test_hash, .fips_allowed =3D 1, .suite =3D { .hash =3D __VECS(sha3_384_tv_template) } }, { .alg =3D "sha3-512", + .generic_driver =3D "sha3-512-lib", .test =3D alg_test_hash, .fips_allowed =3D 1, .suite =3D { .hash =3D __VECS(sha3_512_tv_template) } diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h index 80acdb266b8e3..d562a25332b92 100644 --- a/include/crypto/sha3.h +++ b/include/crypto/sha3.h @@ -34,14 +34,10 @@ #define SHAKE256_DEFAULT_SIZE (256 / 8) #define SHAKE256_BLOCK_SIZE (200 - 2 * SHAKE256_DEFAULT_SIZE) =20 #define SHA3_STATE_SIZE 200 =20 -struct shash_desc; - -int crypto_sha3_init(struct shash_desc *desc); - struct sha3_state { u64 st[SHA3_STATE_SIZE / 8]; }; =20 /** --=20 2.51.1.dirty