From nobody Sat Feb 7 15:11:52 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 0BCA6244667; Sun, 26 Oct 2025 05:53:03 +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=1761457984; cv=none; b=iHoixrO20QcCt672yE2FQ8SmzucG0KkS0cZ4o/RDJn/uYcae7tI3RIOqZnvDbOxrsbhtij4DHxg0WjAIrS/JPd+GL+fz95E97CLIHKeW9/iKhodx0wT7Enad+tJXpoqD0dpLLs6F38jkSypLcSIhWubc18Z0ym6nSaYMRrQgDgU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457984; c=relaxed/simple; bh=rqo1U7wEhsUB8CdH4qk8hnOmmNikMjvUrW83FPZiVAU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cSufykOVmq0udJqoXh+TP+ZEmUbVxizjfM5S3XZKfgvji+5S7JGqobdoljDzGyb8D0xVdQZNzHWUpgMuQwx7PZMYvBYwiYvNvSJSTcARrx8673sfW+g4rGLeScdzAYrfaPVGwBHR4nhYKO0tsEZmYNxIXLa17XyQn8R5jr8yOFM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=nVTq6Mmi; 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="nVTq6Mmi" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 30E20C4CEF7; Sun, 26 Oct 2025 05:53:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457983; bh=rqo1U7wEhsUB8CdH4qk8hnOmmNikMjvUrW83FPZiVAU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=nVTq6Mmi474WJoE5Nj8BFZshsSmt1hahi/B3fYgTDipMpnXO3uXdegxKIf8GWTlWY 9tHTh2KfdMvnAPdMgyCKweIVaFM/efr+s0yc4Sh930Et2Kk3L98m6HpxgOZQgRnLJi F5XVycbAWvsgG71nnZAKDz43xkcFTX2c3XgzrT/YjH1fTdHGhaY4weHZIVVrDfOf2z /65ke7kp3/BLU4AvTS/W8tp7wiJNnq+wpM1RJQUB8xlr4tIPKL8FI4XDRzsgWCFuJ7 BoKqSWY3Elv2R1/UnpJVZCIlwWZ6nFZxCo78HPchNRXJBKRWMyFD59LkefTnyeaY5n k/AoxxuoVLSVw== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 01/15] crypto: s390/sha3 - Rename conflicting functions Date: Sat, 25 Oct 2025 22:50:18 -0700 Message-ID: <20251026055032.1413733-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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_*_init() functions to have an "s390_" prefix to avoid a name conflict with the upcoming SHA-3 library functions. Note: this code will be superseded later. This commit simply keeps the kernel building for the initial introduction of the library. Signed-off-by: David Howells [EB: dropped unnecessary rename of import and export functions, and improved commit message] Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- arch/s390/crypto/sha3_256_s390.c | 10 +++++----- arch/s390/crypto/sha3_512_s390.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/s390/crypto/sha3_256_s390.c b/arch/s390/crypto/sha3_256_s= 390.c index 03bb4f4bab701..7415d56649a52 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) @@ -77,11 +77,11 @@ static int sha3_224_import(struct shash_desc *desc, con= st void *in) 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, .descsize =3D S390_SHA_CTX_SIZE, @@ -94,22 +94,22 @@ 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! */ .descsize =3D S390_SHA_CTX_SIZE, diff --git a/arch/s390/crypto/sha3_512_s390.c b/arch/s390/crypto/sha3_512_s= 390.c index a5c9690eecb19..ff6ee55844005 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) @@ -76,11 +76,11 @@ static int sha3_384_import(struct shash_desc *desc, con= st void *in) 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, .descsize =3D S390_SHA_CTX_SIZE, @@ -95,22 +95,22 @@ static struct shash_alg sha3_512_alg =3D { } }; =20 MODULE_ALIAS_CRYPTO("sha3-512"); =20 -static int sha3_384_init(struct shash_desc *desc) +static int s390_sha3_384_init(struct shash_desc *desc) { struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); =20 - sha3_512_init(desc); + s390_sha3_512_init(desc); sctx->func =3D CPACF_KIMD_SHA3_384; return 0; } =20 static struct shash_alg sha3_384_alg =3D { .digestsize =3D SHA3_384_DIGEST_SIZE, - .init =3D sha3_384_init, + .init =3D s390_sha3_384_init, .update =3D s390_sha_update_blocks, .finup =3D s390_sha_finup, .export =3D sha3_512_export, /* same as for 512 */ .import =3D sha3_384_import, /* function code different! */ .descsize =3D S390_SHA_CTX_SIZE, --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 04C1126CE36; Sun, 26 Oct 2025 05:53:04 +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=1761457985; cv=none; b=U+1Cpr8IYeQ2V+XTipj1uVQkp/SHfymqlBzNxwBDGSukfa9YmRwkBMaytEQjglNQEBmLV00CyKS1f3JL3ZMZBW66xNM/ffuD0Sj3WurZEH3KcuI3SCZyl0Tcb1BsKv1Mv6Gs1PzZBuru7Y9tYMhKwat+H78EPGBwaa9iNs+QOvE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457985; c=relaxed/simple; bh=CPnbj7IYQFMudI6yBXTtVoWUb+m8d0YI96zTtdLwMdQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lymSErgj+ybUL2cqRBLF6KHhKuO/1/FQSvhqc1HUevCy1+WR3GXsAre9Rlm2eSNrMQ3a4/UjmRnXF2fLgg8ltO7wDPu71cU7FPiTCOxYXi6EQjs6O0uZRG8Oweb9/V7BeBjuTOlrs1TSc3ecZHmcXx0/i9BaJSuhS3IYHskWg5k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=mz4zHVc/; 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="mz4zHVc/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A4C2FC113D0; Sun, 26 Oct 2025 05:53:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457984; bh=CPnbj7IYQFMudI6yBXTtVoWUb+m8d0YI96zTtdLwMdQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mz4zHVc/OV+KduHUq6phOIHpr5Ks3IDeZpDxzUgbKqWaT6IbOQqKvj/PwBIZNUlFY 1NuJ71P3h+jIUNmrloAZU2n2Y7kcHbTX0m2c7tCalhzxKJFn+lswqvjkk/qEKZSDXr H5WxnbORcGnUf/3ovcdCS4HwPfVM3ZO6E3tuu5/A4ax5PzYH5KqtD+UMHW4ACTjC0n SKhi3bvDhWgdST782tg9/djTpUgH661wuSiU2xQ1pX934M98G+tMl9DZiyf0bpA/fF goFJWa6WN7ElyZehVWZHh9Tgi7BwtiuD04mAmwv0NDmYVrTxflwnnskT2zVzzszuDL WeVHD+Kd9BP7Q== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 02/15] crypto: arm64/sha3 - Rename conflicting function Date: Sat, 25 Oct 2025 22:50:19 -0700 Message-ID: <20251026055032.1413733-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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_update() function to have an "arm64_" prefix to avoid a name conflict with the upcoming SHA-3 library. Note: this code will be superseded later. This commit simply keeps the kernel building for the initial introduction of the library. Signed-off-by: David Howells [EB: dropped unnecessary rename of sha3_finup(), and improved commit message] Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- arch/arm64/crypto/sha3-ce-glue.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm64/crypto/sha3-ce-glue.c b/arch/arm64/crypto/sha3-ce-g= lue.c index b4f1001046c9a..f5c8302349337 100644 --- a/arch/arm64/crypto/sha3-ce-glue.c +++ b/arch/arm64/crypto/sha3-ce-glue.c @@ -29,12 +29,12 @@ 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, - unsigned int len) +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; int blocks; @@ -88,11 +88,11 @@ 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, + .update =3D arm64_sha3_update, .finup =3D 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, @@ -100,11 +100,11 @@ static struct shash_alg algs[] =3D { { .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, + .update =3D arm64_sha3_update, .finup =3D 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, @@ -112,11 +112,11 @@ static struct shash_alg algs[] =3D { { .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, + .update =3D arm64_sha3_update, .finup =3D 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, @@ -124,11 +124,11 @@ static struct shash_alg algs[] =3D { { .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, + .update =3D arm64_sha3_update, .finup =3D 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, --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 04C7C26D4C2; Sun, 26 Oct 2025 05:53:04 +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=1761457985; cv=none; b=RmKsvQlPzXRCjOd2RYhwTf5IdbJVVzW1HnnKJbJBmsaAqULyewDwMK2l9z6+CqguwhYmWYhcY27d5KST7c6Gg5OQ0vGE1De24CM3cQ98IjfQyTvvPoKF2ymTpoyr9ApMRW+h+lNecN5FBR3SXhl7cYO/vwD9DAcbMvESUtSoXeY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457985; c=relaxed/simple; bh=m54LInOorH439DfIKKGs+6cnPnALMPj8RJ+jLMC/NN0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eak9h3kqK+94Iims6zSzMFdEPWidRhVFCkmHM4dmMCLNduBaPFEnyPJu/O8e4SytNcgo2bmE2ywpPev3vpZ9nEUXJpBcsTxM4+yN9GBISGqfEREePH7Bafk1r92IqfR3lu5GZlQzxprTBhJ58FmimalSJeBvKuXF62L9xVTiL1Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FLEx9Bce; 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="FLEx9Bce" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 24267C16AAE; Sun, 26 Oct 2025 05:53:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457984; bh=m54LInOorH439DfIKKGs+6cnPnALMPj8RJ+jLMC/NN0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=FLEx9Bce1znOT5HplM0dJsPQI6OhFZz5heWCqC6Y9MlLcMFV8p4lxTcLihYKPe3fA A+jxbnQfC0G1rcEOwqdcEsQ6UDUaJyakK0Fh5x5OFsOnu4xhmH0neW4KPFUNFFGlIc pxgCK/8PT9MZT4pSI5JrF+NxvnLrymvurV1ozUEh6bcd1Rg3P6fPJ/nnxCXvNzZYcS hHBjnB4yehlS7N0VA6+3ZyqX9pePKh/Y1iGdFkF/qjkWRTvxKTX1EQWVzIjH7bFfsv kWNBqQewcy7/oaAgEGINhN+BevCdSTivtJ0xcla20ihtsoShB8qrnvEvPzAonQsDhc rWl8O+dTBg50w== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 03/15] lib/crypto: sha3: Add SHA-3 support Date: Sat, 25 Oct 2025 22:50:20 -0700 Message-ID: <20251026055032.1413733-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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 SHA-3 support to lib/crypto/. All six algorithms in the SHA-3 family are supported: four digests (SHA3-224, SHA3-256, SHA3-384, and SHA3-512) and two extendable-output functions (SHAKE128 and SHAKE256). The SHAKE algorithms will be required for ML-DSA. Signed-off-by: David Howells [EB: simplified the API to use fewer types and functions, fixed bug that sometimes caused incorrect SHAKE output, cleaned up the documentation, dropped an ad-hoc test that was inconsistent with the rest of lib/crypto/, and many other cleanups] Co-developed-by: Eric Biggers Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- Documentation/crypto/index.rst | 1 + Documentation/crypto/sha3.rst | 119 +++++++++++ include/crypto/sha3.h | 308 +++++++++++++++++++++++++++- lib/crypto/Kconfig | 7 + lib/crypto/Makefile | 5 + lib/crypto/sha3.c | 359 +++++++++++++++++++++++++++++++++ 6 files changed, 796 insertions(+), 3 deletions(-) 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..b705e70691d7b --- /dev/null +++ b/Documentation/crypto/sha3.rst @@ -0,0 +1,119 @@ +.. 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 +=3D=3D=3D=3D=3D=3D=3D=3D + +The SHA-3 family of algorithms, as specified in NIST FIPS-202 [1]_, contai= ns six +algorithms based on the Keccak sponge function. The differences between t= hem +are: the "rate" (how much of the state buffer gets updated with new data b= etween +invocations of the Keccak function and analogous to the "block size"), what +domain separation suffix gets appended to the input data, and how much out= put +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 digest algorithms are provided: + + - SHA3-224 + - SHA3-256 + - SHA3-384 + - SHA3-512 + +Additionally, two Extendable-Output Functions (XOFs) are provided: + + - SHAKE128 + - SHAKE256 + +The SHA-3 library API supports all six of these algorithms. The four dige= st +algorithms are also supported by the crypto_shash and crypto_ahash APIs. + +This document describes the SHA-3 library API. + + +Digests +=3D=3D=3D=3D=3D=3D=3D + +The following functions compute SHA-3 digests:: + + 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]); + +For users that need to pass in data incrementally, an incremental API is a= lso +provided. The incremental API uses the following struct:: + + struct sha3_ctx { ... }; + +Initialization is done with one of:: + + 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); + +Input data is then added with any number of calls to:: + + void sha3_update(struct sha3_ctx *ctx, const u8 *in, size_t in_len); + +Finally, the digest is generated using:: + + void sha3_final(struct sha3_ctx *ctx, u8 *out); + +which also zeroizes the context. The length of the digest is determined b= y the +initialization function that was called. + + +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 following functions compute the SHA-3 extendable-output functions (XOF= s):: + + 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); + +For users that need to provide the input data incrementally and/or receive= the +output data incrementally, an incremental API is also provided. The incre= mental +API uses the following struct:: + + struct shake_ctx { ... }; + +Initialization is done with one of:: + + void shake128_init(struct shake_ctx *ctx); + void shake256_init(struct shake_ctx *ctx); + +Input data is then added with any number of calls to:: + + void shake_update(struct shake_ctx *ctx, const u8 *in, size_t in_len); + +Finally, the output data is extracted with any number of calls to:: + + void shake_squeeze(struct shake_ctx *ctx, u8 *out, size_t out_len); + +and telling it how much data should be extracted. Note that performing mu= ltiple +squeezes, with the output laid consecutively in a buffer, gets exactly the= same +output as doing a single squeeze for the combined amount over the same buf= fer. + +More input data cannot be added after squeezing has started. + +Once all the desired output has been extracted, zeroize the context:: + + void shake_zeroize_ctx(struct shake_ctx *ctx); + + +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:: include/crypto/sha3.h diff --git a/include/crypto/sha3.h b/include/crypto/sha3.h index 41e1b83a6d918..a7503dfc1a044 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,315 @@ =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 u= sed 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 +int crypto_sha3_init(struct shash_desc *desc); + +/* + * State for the Keccak-f[1600] permutation: 25 64-bit words. + * + * We usually keep the state words as little-endian, to make absorbing and + * squeezing easier. (It means that absorbing and squeezing can just trea= t the + * state as a byte array.) The state words are converted to native-endian= only + * temporarily by implementations of the permutation that need native-endi= an + * words. Of course, that conversion is a no-op on little-endian machines. + */ struct sha3_state { - u64 st[SHA3_STATE_SIZE / 8]; + union { + u64 st[SHA3_STATE_SIZE / 8]; /* temporarily retained for compatibility p= urposes */ + + __le64 words[SHA3_STATE_SIZE / 8]; + u8 bytes[SHA3_STATE_SIZE]; + + u64 native_words[SHA3_STATE_SIZE / 8]; /* see comment above */ + }; }; =20 -int crypto_sha3_init(struct shash_desc *desc); +/* Internal context, shared by the digests (SHA3-*) and the XOFs (SHAKE*) = */ +struct __sha3_ctx { + struct sha3_state state; + u8 digest_size; /* Digests only: the digest size in bytes */ + u8 block_size; /* Block size in bytes */ + u8 absorb_offset; /* Index of next state byte to absorb into */ + u8 squeeze_offset; /* XOFs only: index of next state byte to extract */ +}; + +void __sha3_update(struct __sha3_ctx *ctx, const u8 *in, size_t in_len); + +/** Context for SHA3-224, SHA3-256, SHA3-384, or SHA3-512 */ +struct sha3_ctx { + struct __sha3_ctx ctx; +}; + +/** + * 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_zeroize_ctx(struct sha3_ctx *ctx) +{ + memzero_explicit(ctx, sizeof(*ctx)); +} + +/** Context for SHAKE128 or SHAKE256 */ +struct shake_ctx { + struct __sha3_ctx ctx; +}; + +/** Zeroize a shake_ctx. Call this after the last squeeze. */ +static inline void shake_zeroize_ctx(struct shake_ctx *ctx) +{ + memzero_explicit(ctx, sizeof(*ctx)); +} + +/** + * sha3_224_init() - Initialize a context for SHA3-224 + * @ctx: The context to initialize + * + * This begins a new SHA3-224 message digest computation. + * + * Context: Any context. + */ +static inline void sha3_224_init(struct sha3_ctx *ctx) +{ + *ctx =3D (struct sha3_ctx){ + .ctx.digest_size =3D SHA3_224_DIGEST_SIZE, + .ctx.block_size =3D SHA3_224_BLOCK_SIZE, + }; +} + +/** + * sha3_256_init() - Initialize a context for SHA3-256 + * @ctx: The context to initialize + * + * This begins a new SHA3-256 message digest computation. + * + * Context: Any context. + */ +static inline void sha3_256_init(struct sha3_ctx *ctx) +{ + *ctx =3D (struct sha3_ctx){ + .ctx.digest_size =3D SHA3_256_DIGEST_SIZE, + .ctx.block_size =3D SHA3_256_BLOCK_SIZE, + }; +} + +/** + * sha3_384_init() - Initialize a context for SHA3-384 + * @ctx: The context to initialize + * + * This begins a new SHA3-384 message digest computation. + * + * Context: Any context. + */ +static inline void sha3_384_init(struct sha3_ctx *ctx) +{ + *ctx =3D (struct sha3_ctx){ + .ctx.digest_size =3D SHA3_384_DIGEST_SIZE, + .ctx.block_size =3D SHA3_384_BLOCK_SIZE, + }; +} + +/** + * sha3_512_init() - Initialize a context for SHA3-512 + * @ctx: The context to initialize + * + * This begins a new SHA3-512 message digest computation. + * + * Context: Any context. + */ +static inline void sha3_512_init(struct sha3_ctx *ctx) +{ + *ctx =3D (struct sha3_ctx){ + .ctx.digest_size =3D SHA3_512_DIGEST_SIZE, + .ctx.block_size =3D SHA3_512_BLOCK_SIZE, + }; +} + +/** + * 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 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_update(struct sha3_ctx *ctx, + const u8 *in, size_t in_len) +{ + __sha3_update(&ctx->ctx, in, in_len); +} + +/** + * 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. + * + * After finishing, this zeroizes @ctx. So the caller does not need to do= it. + * + * Context: Any context. + */ +void sha3_final(struct sha3_ctx *ctx, u8 *out); + +/** + * shake128_init() - Initialize a context for SHAKE128 + * @ctx: The context to initialize + * + * This begins a new SHAKE128 extendable-output function (XOF) computation. + * + * Context: Any context. + */ +static inline void shake128_init(struct shake_ctx *ctx) +{ + *ctx =3D (struct shake_ctx){ + .ctx.block_size =3D SHAKE128_BLOCK_SIZE, + }; +} + +/** + * shake256_init() - Initialize a context for SHAKE256 + * @ctx: The context to initialize + * + * This begins a new SHAKE256 extendable-output function (XOF) computation. + * + * Context: Any context. + */ +static inline void shake256_init(struct shake_ctx *ctx) +{ + *ctx =3D (struct shake_ctx){ + .ctx.block_size =3D SHAKE256_BLOCK_SIZE, + }; +} + +/** + * 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 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 shake_update(struct shake_ctx *ctx, + const u8 *in, size_t in_len) +{ + __sha3_update(&ctx->ctx, in, in_len); +} + +/** + * 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 + * + * 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 the last squeeze, call shake_zeroize_ctx(). + * + * Context: Any context. + */ +void shake_squeeze(struct shake_ctx *ctx, u8 *out, size_t out_len); + +/** + * 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 +#endif /* __CRYPTO_SHA3_H__ */ diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index 280b888153bf0..a05f5a349cd8c 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -193,10 +193,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 + select CRYPTO_LIB_UTILS + help + The SHA3 library functions. Select this if your module uses any of + the 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 bc26777d08e97..0cfdb511f32b6 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -276,10 +276,15 @@ 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_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..049be8414de26 --- /dev/null +++ b/lib/crypto/sha3.c @@ -0,0 +1,359 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * 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 +#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_generic(). On the other hand, on 64-bit architectures with + * plenty of [64-bit wide] general purpose registers, not inlining it seve= rely + * hurts performance. So let's use 64-bitness as a heuristic to decide wh= ether + * 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[SHA3_KECCAK_ROUNDS] =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(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]; +} + +/* Generic implementation of the Keccak-f[1600] permutation */ +static void sha3_keccakf_generic(struct sha3_state *state) +{ + /* + * Temporarily convert the state words from little-endian to native- + * endian so that they can be operated on. Note that on little-endian + * machines this conversion is a no-op and is optimized out. + */ + + for (int i =3D 0; i < ARRAY_SIZE(state->words); i++) + state->native_words[i] =3D le64_to_cpu(state->words[i]); + + for (int round =3D 0; round < SHA3_KECCAK_ROUNDS; round++) { + sha3_keccakf_one_round_generic(state->native_words); + /* Iota */ + state->native_words[0] ^=3D sha3_keccakf_rndc[round]; + } + + for (int i =3D 0; i < ARRAY_SIZE(state->words); i++) + state->words[i] =3D cpu_to_le64(state->native_words[i]); +} + +/* + * Generic implementation of absorbing the given nonzero number of full bl= ocks + * into the sponge function Keccak[r=3D8*block_size, c=3D1600-8*block_size= ]. + */ +static void __maybe_unused +sha3_absorb_blocks_generic(struct sha3_state *state, const u8 *data, + size_t nblocks, size_t block_size) +{ + do { + for (size_t i =3D 0; i < block_size; i +=3D 8) + state->words[i / 8] ^=3D get_unaligned((__le64 *)&data[i]); + sha3_keccakf_generic(state); + data +=3D 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 + +void __sha3_update(struct __sha3_ctx *ctx, const u8 *in, size_t in_len) +{ + const size_t block_size =3D ctx->block_size; + size_t absorb_offset =3D ctx->absorb_offset; + + /* Warn if squeezing has already begun. */ + WARN_ON_ONCE(absorb_offset >=3D block_size); + + if (absorb_offset && absorb_offset + in_len >=3D block_size) { + crypto_xor(&ctx->state.bytes[absorb_offset], in, + block_size - absorb_offset); + in +=3D block_size - absorb_offset; + in_len -=3D block_size - absorb_offset; + sha3_keccakf(&ctx->state); + absorb_offset =3D 0; + } + + if (in_len >=3D block_size) { + size_t nblocks =3D in_len / block_size; + + sha3_absorb_blocks(&ctx->state, in, nblocks, block_size); + in +=3D nblocks * block_size; + in_len -=3D nblocks * block_size; + } + + if (in_len) { + crypto_xor(&ctx->state.bytes[absorb_offset], in, in_len); + absorb_offset +=3D in_len; + } + ctx->absorb_offset =3D absorb_offset; +} +EXPORT_SYMBOL_GPL(__sha3_update); + +void sha3_final(struct sha3_ctx *sha3_ctx, u8 *out) +{ + struct __sha3_ctx *ctx =3D &sha3_ctx->ctx; + + ctx->state.bytes[ctx->absorb_offset] ^=3D 0x06; + ctx->state.bytes[ctx->block_size - 1] ^=3D 0x80; + sha3_keccakf(&ctx->state); + memcpy(out, ctx->state.bytes, ctx->digest_size); + sha3_zeroize_ctx(sha3_ctx); +} +EXPORT_SYMBOL_GPL(sha3_final); + +void shake_squeeze(struct shake_ctx *shake_ctx, u8 *out, size_t out_len) +{ + struct __sha3_ctx *ctx =3D &shake_ctx->ctx; + const size_t block_size =3D ctx->block_size; + size_t squeeze_offset =3D ctx->squeeze_offset; + + if (ctx->absorb_offset < block_size) { + /* First squeeze: */ + + /* Add the domain separation suffix and padding. */ + ctx->state.bytes[ctx->absorb_offset] ^=3D 0x1f; + ctx->state.bytes[block_size - 1] ^=3D 0x80; + + /* Indicate that squeezing has begun. */ + ctx->absorb_offset =3D block_size; + + /* + * Indicate that no output is pending yet, i.e. sha3_keccakf() + * will need to be called before the first copy. + */ + squeeze_offset =3D block_size; + } + while (out_len) { + if (squeeze_offset =3D=3D block_size) { + sha3_keccakf(&ctx->state); + squeeze_offset =3D 0; + } + size_t copy =3D min(out_len, block_size - squeeze_offset); + + memcpy(out, &ctx->state.bytes[squeeze_offset], copy); + out +=3D copy; + out_len -=3D copy; + squeeze_offset +=3D copy; + } + ctx->squeeze_offset =3D squeeze_offset; +} +EXPORT_SYMBOL_GPL(shake_squeeze); + +void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE]) +{ + struct sha3_ctx ctx; + + sha3_224_init(&ctx); + sha3_update(&ctx, in, in_len); + sha3_final(&ctx, out); +} +EXPORT_SYMBOL_GPL(sha3_224); + +void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE]) +{ + struct sha3_ctx ctx; + + sha3_256_init(&ctx); + sha3_update(&ctx, in, in_len); + sha3_final(&ctx, out); +} +EXPORT_SYMBOL_GPL(sha3_256); + +void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE]) +{ + struct sha3_ctx ctx; + + sha3_384_init(&ctx); + sha3_update(&ctx, in, in_len); + sha3_final(&ctx, out); +} +EXPORT_SYMBOL_GPL(sha3_384); + +void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE]) +{ + struct sha3_ctx ctx; + + sha3_512_init(&ctx); + sha3_update(&ctx, in, in_len); + sha3_final(&ctx, out); +} +EXPORT_SYMBOL_GPL(sha3_512); + +void shake128(const u8 *in, size_t in_len, u8 *out, size_t out_len) +{ + struct shake_ctx ctx; + + shake128_init(&ctx); + shake_update(&ctx, in, in_len); + shake_squeeze(&ctx, out, out_len); + shake_zeroize_ctx(&ctx); +} +EXPORT_SYMBOL_GPL(shake128); + +void shake256(const u8 *in, size_t in_len, u8 *out, size_t out_len) +{ + struct shake_ctx ctx; + + shake256_init(&ctx); + shake_update(&ctx, in, in_len); + shake_squeeze(&ctx, out, out_len); + shake_zeroize_ctx(&ctx); +} +EXPORT_SYMBOL_GPL(shake256); + +#ifdef sha3_mod_init_arch +static int __init sha3_mod_init(void) +{ + sha3_mod_init_arch(); + return 0; +} +subsys_initcall(sha3_mod_init); + +static void __exit sha3_mod_exit(void) +{ +} +module_exit(sha3_mod_exit); +#endif + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("SHA-3 library functions"); --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 7E6D4286408; Sun, 26 Oct 2025 05:53:05 +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=1761457988; cv=none; b=NKvLTVayIHYcqC9MctfU2Ny8jzOR3M2Mlsi5AkrAbMJel6TS/LfgvVn4QwW201ruTE8l8KtXjkVILFbkA03oLENF2eEbxYixU33n1nke20FWvZ8vLqMVLQGMc5LDCoffme21ZULt5gUQJXS7WExUqpDUMRci/9oWUFlArockGC8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457988; c=relaxed/simple; bh=G4phGjZg/4DyxMiZScpeB5F56Kh8gOR6USagGkBx7Vo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KsFj+4Axn1+dMwAIwzxWPsj2WuMcJJn6J0AArpx6heYOUEbpNsuDH/UFhvLqsST5cMRik/gP3gFVVRjRC1DMGnrgqFOJaiWlYkCyTVENr6A7HJF5Dh6lzS1KksC8VA8EVRVAyyTaxEu5EIV27hBnb4kbgJrVUh2Rm/zGCL19PEE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TlTvEPgl; 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="TlTvEPgl" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 98D9DC4AF09; Sun, 26 Oct 2025 05:53:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457985; bh=G4phGjZg/4DyxMiZScpeB5F56Kh8gOR6USagGkBx7Vo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TlTvEPglQOHat1LvQgZUeyeuH7Hcljru/KjtGuDlPGeis3n5PDywGuUR25jVngEOp T5yZXcLFZ6og46oOZMuQ7zxtDth/L4dx3COFvfMV2Ow2EFNErD0glGUlcdwh7UeBOE wWenUYvUP+Ih//cuIDUWWg4XEVrTtksjyp3Hrr6JIDvEU1OCybt2M1YcdmsLDis+mU eWoRbzOIp5aaz5BtZ4nWu/8zl2nG9wqJV/h4GPP4EX2ZBDcXb8UQ5NFva900cfcsXS Uah4c0CN9RaIVGM+Q7TDU4TRcbg3JQiuhVNtJMXM6hlZYSFRY4ishXF3Nd3XaNcyhX 3XHR8lijJDvvQ== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 04/15] lib/crypto: sha3: Move SHA3 Iota step mapping into round function Date: Sat, 25 Oct 2025 22:50:21 -0700 Message-ID: <20251026055032.1413733-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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 four of Keccak-f's five step mappings. However, it does not do the Iota step mapping - presumably because that is dependent on round number, whereas Theta, Rho, Pi and Chi 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 step mapping 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 Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- 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 049be8414de26..ee7a2ca92b2c5 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -46,11 +46,11 @@ static const u64 sha3_keccakf_rndc[SHA3_KECCAK_ROUNDS] = =3D { }; =20 /* * Perform a single round of Keccak mixing. */ -static SHA3_INLINE void sha3_keccakf_one_round_generic(u64 st[25]) +static SHA3_INLINE void sha3_keccakf_one_round_generic(u64 st[25], int rou= nd) { u64 t[5], tt, bc[5]; =20 /* Theta */ bc[0] =3D st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20]; @@ -147,10 +147,13 @@ static SHA3_INLINE void sha3_keccakf_one_round_generi= c(u64 st[25]) 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 */ + st[0] ^=3D sha3_keccakf_rndc[round]; } =20 /* Generic implementation of the Keccak-f[1600] permutation */ static void sha3_keccakf_generic(struct sha3_state *state) { @@ -161,15 +164,12 @@ static void sha3_keccakf_generic(struct sha3_state *s= tate) */ =20 for (int i =3D 0; i < ARRAY_SIZE(state->words); i++) state->native_words[i] =3D le64_to_cpu(state->words[i]); =20 - for (int round =3D 0; round < SHA3_KECCAK_ROUNDS; round++) { - sha3_keccakf_one_round_generic(state->native_words); - /* Iota */ - state->native_words[0] ^=3D sha3_keccakf_rndc[round]; - } + for (int round =3D 0; round < SHA3_KECCAK_ROUNDS; round++) + sha3_keccakf_one_round_generic(state->native_words, round); =20 for (int i =3D 0; i < ARRAY_SIZE(state->words); i++) state->words[i] =3D cpu_to_le64(state->native_words[i]); } =20 --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 8813127144A; Sun, 26 Oct 2025 05:53:05 +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=1761457985; cv=none; b=AMmZFdYNJGaIFLvq/jP+gXWWcM9ro+mKYGLcfGaqTezrMn3I7je/GnsFj+U/ecXAzzvHxLetLZwd+uFwz2A1mjmw37fhWSmbfvYduEhgKyAM+RjZI+foLW00YZ3MsW29MnDx2CaMJc2cT+PnxWtKaU7u8YoKs+XSmf71S5hOS0Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457985; c=relaxed/simple; bh=0rmCigZD30Y7Qn/5Q6S8PKiXC3oSi31nmGmj7+N9pY0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pK9xaz+XJfvPh/ok3L4Lv0UvQcET+ir65u5XIJxpSuqvhLnMUBY18VIbYoGsHMKo6jdWP7HVZuRjdU0ngqwLQgrHnRvrX4HqOQttzDyYpLr32VxUtO1y2Va1mHuhUzc2jReXteyobMJJrpyivXJ1R1ew1MYwoFFloaPXRWYDMnc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=J8C8+7Mp; 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="J8C8+7Mp" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1A05DC4CEE7; Sun, 26 Oct 2025 05:53:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457985; bh=0rmCigZD30Y7Qn/5Q6S8PKiXC3oSi31nmGmj7+N9pY0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=J8C8+7Mpx81zGro0KS2xamL+VQLInlUrhT0Pvwhyj8wCh7A9k4ZR9gTqSKdvIZEl7 ow1fKXQKwVp3tEiwvrVdoKvPgm59hSBABm3w8bnZ3GFE1N1QP0FvAlEmTLOiZkYW0J SYtpBbgwitLybc9BVu5xB6L5GGrx6hdpxAJzfEaNGMFeq9Gp5/x2LdQNBCCRjXYJYI XdRVsOywZuATVMq2SUArXtewQVROAiL1I2j9cDS8ba0sYRiwqbdbaed8WoQABXkVk/ K+qkBPTxzaiGwcAPGit73yD7uIE4jkrz0WokECUomfIRLJG1lEFML0GW91+ItbEsAI F100nKS05z0HQ== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 05/15] lib/crypto: tests: Add SHA3 kunit tests Date: Sat, 25 Oct 2025 22:50:22 -0700 Message-ID: <20251026055032.1413733-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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 suite, providing the following: (*) A simple test of each of SHA3-224, SHA3-256, SHA3-384, SHA3-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. To make this possible, gen-hash-testvecs.py is modified to support sha3-256. (*) Standard benchmark test for SHA3-256. Signed-off-by: David Howells Reviewed-by: Ard Biesheuvel [EB: dropped some unnecessary changes to gen-hash-testvecs.py, moved addition of Testing section in doc file into this commit, and other small cleanups] Signed-off-by: Eric Biggers Tested-by: Harald Freudenberger --- Documentation/crypto/sha3.rst | 6 + lib/crypto/tests/Kconfig | 11 + lib/crypto/tests/Makefile | 1 + lib/crypto/tests/sha3-testvecs.h | 231 +++++++++++++++++++ lib/crypto/tests/sha3_kunit.c | 344 ++++++++++++++++++++++++++++ scripts/crypto/gen-hash-testvecs.py | 4 +- 6 files changed, 596 insertions(+), 1 deletion(-) create mode 100644 lib/crypto/tests/sha3-testvecs.h create mode 100644 lib/crypto/tests/sha3_kunit.c diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst index b705e70691d7b..f8c484feaa291 100644 --- a/Documentation/crypto/sha3.rst +++ b/Documentation/crypto/sha3.rst @@ -105,10 +105,16 @@ More input data cannot be added after squeezing has s= tarted. Once all the desired output has been extracted, zeroize the context:: =20 void shake_zeroize_ctx(struct shake_ctx *ctx); =20 =20 +Testing +=3D=3D=3D=3D=3D=3D=3D + +To test the SHA-3 code, use sha3_kunit (CONFIG_CRYPTO_LIB_SHA3_KUNIT_TEST). + + References =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 .. [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf =20 diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig index 2ebfd681bae4d..140afd1714bab 100644 --- a/lib/crypto/tests/Kconfig +++ b/lib/crypto/tests/Kconfig @@ -79,10 +79,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 f21a48a4415d0..f7d1392dc8475 100644 --- a/lib/crypto/tests/Makefile +++ b/lib/crypto/tests/Makefile @@ -6,5 +6,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-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/lib/crypto/tests/sha3_kunit.c b/lib/crypto/tests/sha3_kunit.c new file mode 100644 index 0000000000000..c267984c4aff1 --- /dev/null +++ b/lib/crypto/tests/sha3_kunit.c @@ -0,0 +1,344 @@ +// 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_ctx +#define HASH_SIZE SHA3_256_DIGEST_SIZE +#define HASH_INIT sha3_256_init +#define HASH_UPDATE sha3_update +#define HASH_FINAL sha3_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 shake_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); + shake_update(&ctx, test_sha3_sample, + sizeof(test_sha3_sample) - 1); + while (left > 0) { + int part =3D umin(tile_size, left); + + shake_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 shake_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); + shake_update(&ctx, test_sha3_sample, + sizeof(test_sha3_sample) - 1); + while (left > 0) { + int part =3D umin(tile_size, left); + + shake_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 sha3_test_cases[] =3D { + HASH_KUNIT_CASES, + 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), + KUNIT_CASE(benchmark_hash), + {}, +}; + +static struct kunit_suite sha3_test_suite =3D { + .name =3D "sha3", + .test_cases =3D sha3_test_cases, + .suite_init =3D hash_suite_init, + .suite_exit =3D hash_suite_exit, +}; +kunit_test_suite(sha3_test_suite); + +MODULE_DESCRIPTION("KUnit tests and benchmark for SHA3"); +MODULE_LICENSE("GPL"); diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-= testvecs.py index c5b7985fe7280..47f79602e2903 100755 --- a/scripts/crypto/gen-hash-testvecs.py +++ b/scripts/crypto/gen-hash-testvecs.py @@ -85,11 +85,11 @@ def print_c_struct_u8_array_field(name, value): print('\t\t},') =20 def alg_digest_size_const(alg): if alg.startswith('blake2'): return f'{alg.upper()}_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;') @@ -165,7 +165,9 @@ print(f'/* This file was generated by: {sys.argv[0]} {"= ".join(sys.argv[1:])} */ gen_unkeyed_testvecs(alg) if alg.startswith('blake2'): gen_additional_blake2_testvecs(alg) elif alg =3D=3D 'poly1305': gen_additional_poly1305_testvecs() +elif alg.startswith('sha3-'): + pass # no HMAC else: gen_hmac_testvecs(alg) --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 092FB275AE3; Sun, 26 Oct 2025 05:53:06 +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=1761457986; cv=none; b=T7KO5pDOnVyx/dcLnTMbWNtHk8gYxkQHAFQv8RyiNwZ6h+/tyAzJdU7zNdNRshGtZMPtHGvDmwflRfH3CplIExSluyNKJwhyopKsqjNecgUkyMuLcwJcm8JnizYK2Nc2yg925at+2buHTQbM9YWqh+iqEij+vPQaxvZeyNx5so8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457986; c=relaxed/simple; bh=GCyZqLSJojQX4LemND++76qvdpEf1Eblafr0NXESqYE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PLIfaCKkAXvKTgR3xqM2QpO91tRszSMEmYOdSKF5UBZODoF1QoLVHXBM+ZNxVMTO/Azei8PzLGWAG89aO83mT/k4zDoP5tlWbmUMLdZbuuki4CARxO74VPCCqII6sTI3rj6wVpP3hOMDrjw72I178mBAS0PqK7ENUxjs4/T1ZAI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=KRVAkIgf; 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="KRVAkIgf" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8E0EBC4CEF7; Sun, 26 Oct 2025 05:53:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457985; bh=GCyZqLSJojQX4LemND++76qvdpEf1Eblafr0NXESqYE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KRVAkIgfwa+dovbgZ/yeDOA7VZ0bi6PGr6wswsdq7ScLz/iDbQ42bjAj8LW+QOnPY EQ0pk487IVPypsHlXF6oLAjTJgz6nr+QNHl7w4DJBjzGmP1HeYttVhiXT3h6RMDy3r k0RnFejMO+p6gne6PjHqiDzci9sV+sybf33ai22PExNaJWRPTNEUc8fW55ZDqDjv7x 2NhyEhQbsYBOrh+SQ+K/xQV+N1jm9O+00qCoz5rKRcYq00m9vU8hwAmgpYNWtp+y5W eiFB7ol/cYVmucuu7rLkzRfA9vDDuvP28xTBWcMi/vacIZJsOnLnn7z/9h8mVwPC93 uC3OjMr+vIrXw== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 06/15] lib/crypto: tests: Add additional SHAKE tests Date: Sat, 25 Oct 2025 22:50:23 -0700 Message-ID: <20251026055032.1413733-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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" Add the following test cases to cover gaps in the SHAKE testing: - test_shake_all_lens_up_to_4096() - test_shake_multiple_squeezes() - test_shake_with_guarded_bufs() Remove test_shake256_tiling() and test_shake256_tiling2() since they are superseded by test_shake_multiple_squeezes(). It provides better test coverage by using randomized testing. E.g., it's able to generate a zero-length squeeze followed by a nonzero-length squeeze, which the first 7 versions of the SHA-3 patchset handled incorrectly. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- lib/crypto/tests/sha3-testvecs.h | 20 ++- lib/crypto/tests/sha3_kunit.c | 186 ++++++++++++++++++++-------- scripts/crypto/gen-hash-testvecs.py | 27 +++- 3 files changed, 174 insertions(+), 59 deletions(-) diff --git a/lib/crypto/tests/sha3-testvecs.h b/lib/crypto/tests/sha3-testv= ecs.h index 9c4c403cc6e06..8d614a5fa0c37 100644 --- a/lib/crypto/tests/sha3-testvecs.h +++ b/lib/crypto/tests/sha3-testvecs.h @@ -1,7 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha3-= 256 */ +/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py sha3 = */ + +/* SHA3-256 test vectors */ =20 static const struct { size_t data_len; u8 digest[SHA3_256_DIGEST_SIZE]; } hash_testvecs[] =3D { @@ -227,5 +229,21 @@ static const u8 hash_testvec_consolidated[SHA3_256_DIG= EST_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, }; + +/* SHAKE test vectors */ + +static const u8 shake128_testvec_consolidated[SHA3_256_DIGEST_SIZE] =3D { + 0x89, 0x88, 0x3a, 0x44, 0xec, 0xfe, 0x3c, 0xeb, + 0x2f, 0x1c, 0x1d, 0xda, 0x9e, 0x36, 0x64, 0xf0, + 0x85, 0x4c, 0x49, 0x12, 0x76, 0x5a, 0x4d, 0xe7, + 0xa8, 0xfd, 0xcd, 0xbe, 0x45, 0xb4, 0x6f, 0xb0, +}; + +static const u8 shake256_testvec_consolidated[SHA3_256_DIGEST_SIZE] =3D { + 0x5a, 0xfd, 0x66, 0x62, 0x5c, 0x37, 0x2b, 0x41, + 0x77, 0x1c, 0x01, 0x5d, 0x64, 0x7c, 0x63, 0x7a, + 0x7c, 0x76, 0x9e, 0xa8, 0xd1, 0xb0, 0x8e, 0x02, + 0x16, 0x9b, 0xfe, 0x0e, 0xb5, 0xd8, 0x6a, 0xb5, +}; diff --git a/lib/crypto/tests/sha3_kunit.c b/lib/crypto/tests/sha3_kunit.c index c267984c4aff1..ed5fbe80337fe 100644 --- a/lib/crypto/tests/sha3_kunit.c +++ b/lib/crypto/tests/sha3_kunit.c @@ -245,76 +245,153 @@ static void test_shake256_nist(struct kunit *test) out, sizeof(out)); KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256_nist_1600, sizeof(out), "SHAKE256 gives wrong output for NIST.1600"); } =20 -/* - * 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) +static void shake(int alg, const u8 *in, size_t in_len, u8 *out, size_t ou= t_len) { - struct shake_ctx ctx; - u8 out[8 + SHA3_512_DIGEST_SIZE + 8]; + if (alg =3D=3D 0) + shake128(in, in_len, out, out_len); + else + shake256(in, in_len, out, out_len); +} =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; +static void shake_init(struct shake_ctx *ctx, int alg) +{ + if (alg =3D=3D 0) + shake128_init(ctx); + else + shake256_init(ctx); +} =20 - memset(out, 0, sizeof(out)); - shake256_init(&ctx); - shake_update(&ctx, test_sha3_sample, - sizeof(test_sha3_sample) - 1); - while (left > 0) { - int part =3D umin(tile_size, left); +/* + * Test each of SHAKE128 and SHAKE256 with all input lengths 0 through 409= 6, for + * both input and output. The input and output lengths cycle through the = values + * together, so we do 4096 tests total. To verify all the SHAKE outputs, + * compute and verify the SHA3-256 digest of all of them concatenated toge= ther. + */ +static void test_shake_all_lens_up_to_4096(struct kunit *test) +{ + struct sha3_ctx main_ctx; + const size_t max_len =3D 4096; + u8 *const in =3D test_buf; + u8 *const out =3D &test_buf[TEST_BUF_LEN - max_len]; + u8 main_hash[SHA3_256_DIGEST_SIZE]; + + KUNIT_ASSERT_LE(test, 2 * max_len, TEST_BUF_LEN); + + rand_bytes_seeded_from_len(in, max_len); + for (int alg =3D 0; alg < 2; alg++) { + sha3_256_init(&main_ctx); + for (size_t in_len =3D 0; in_len <=3D max_len; in_len++) { + size_t out_len =3D (in_len * 293) % (max_len + 1); + + shake(alg, in, in_len, out, out_len); + sha3_update(&main_ctx, out, out_len); + } + sha3_final(&main_ctx, main_hash); + if (alg =3D=3D 0) + KUNIT_ASSERT_MEMEQ_MSG(test, main_hash, + shake128_testvec_consolidated, + sizeof(main_hash), + "shake128() gives wrong output"); + else + KUNIT_ASSERT_MEMEQ_MSG(test, main_hash, + shake256_testvec_consolidated, + sizeof(main_hash), + "shake256() gives wrong output"); + } +} =20 - shake_squeeze(&ctx, p, part); - p +=3D part; - left -=3D part; +/* + * Test that a sequence of SHAKE squeezes gives the same output as a single + * squeeze of the same total length. + */ +static void test_shake_multiple_squeezes(struct kunit *test) +{ + const size_t max_len =3D 512; + u8 *ref_out; + + KUNIT_ASSERT_GE(test, TEST_BUF_LEN, 2 * max_len); + + ref_out =3D kunit_kzalloc(test, max_len, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, ref_out); + + for (int i =3D 0; i < 2000; i++) { + const int alg =3D rand32() % 2; + const size_t in_len =3D rand_length(max_len); + const size_t out_len =3D rand_length(max_len); + const size_t in_offs =3D rand_offset(max_len - in_len); + const size_t out_offs =3D rand_offset(max_len - out_len); + u8 *const in =3D &test_buf[in_offs]; + u8 *const out =3D &test_buf[out_offs]; + struct shake_ctx ctx; + size_t remaining_len, j, num_parts; + + rand_bytes(in, in_len); + rand_bytes(out, out_len); + + /* Compute the output using the one-shot function. */ + shake(alg, in, in_len, ref_out, out_len); + + /* Compute the output using a random sequence of squeezes. */ + shake_init(&ctx, alg); + shake_update(&ctx, in, in_len); + remaining_len =3D out_len; + j =3D 0; + num_parts =3D 0; + while (rand_bool()) { + size_t part_len =3D rand_length(remaining_len); + + shake_squeeze(&ctx, &out[j], part_len); + num_parts++; + j +=3D part_len; + remaining_len -=3D part_len; + } + if (remaining_len !=3D 0 || rand_bool()) { + shake_squeeze(&ctx, &out[j], remaining_len); + num_parts++; } =20 - KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256), - "SHAKE tile %u gives wrong output", tile_size); + /* Verify that the outputs are the same. */ + KUNIT_ASSERT_MEMEQ_MSG( + test, out, ref_out, out_len, + "Multi-squeeze test failed with in_len=3D%zu in_offs=3D%zu out_len=3D%z= u out_offs=3D%zu num_parts=3D%zu alg=3D%d", + in_len, in_offs, out_len, out_offs, num_parts, alg); } } =20 /* - * 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. + * Test that SHAKE operations on buffers immediately followed by an unmapp= ed + * page work as expected. This catches out-of-bounds memory accesses even= if + * they occur in assembly code. */ -static void test_shake256_tiling2(struct kunit *test) +static void test_shake_with_guarded_bufs(struct kunit *test) { - struct shake_ctx ctx; - u8 out[8 + SHA3_512_DIGEST_SIZE + 8]; + const size_t max_len =3D 512; + u8 *reg_buf; =20 - 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); - shake_update(&ctx, test_sha3_sample, - sizeof(test_sha3_sample) - 1); - while (left > 0) { - int part =3D umin(tile_size, left); - - shake_squeeze(&ctx, p, part); - p +=3D part; - left -=3D part; - tile_size--; - if (tile_size < 1) - tile_size =3D 5; - } + KUNIT_ASSERT_GE(test, TEST_BUF_LEN, max_len); =20 - KUNIT_ASSERT_MEMEQ_MSG(test, out, test_shake256, sizeof(test_shake256), - "SHAKE tile %u gives wrong output", tile_size); + reg_buf =3D kunit_kzalloc(test, max_len, GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, reg_buf); + + for (int alg =3D 0; alg < 2; alg++) { + for (size_t len =3D 0; len <=3D max_len; len++) { + u8 *guarded_buf =3D &test_buf[TEST_BUF_LEN - len]; + + rand_bytes(reg_buf, len); + memcpy(guarded_buf, reg_buf, len); + + shake(alg, reg_buf, len, reg_buf, len); + shake(alg, guarded_buf, len, guarded_buf, len); + + KUNIT_ASSERT_MEMEQ_MSG( + test, reg_buf, guarded_buf, len, + "Guard page test failed with len=3D%zu alg=3D%d", + len, alg); + } } } =20 static struct kunit_case sha3_test_cases[] =3D { HASH_KUNIT_CASES, @@ -324,12 +401,13 @@ static struct kunit_case sha3_test_cases[] =3D { 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), + KUNIT_CASE(test_shake_all_lens_up_to_4096), + KUNIT_CASE(test_shake_multiple_squeezes), + KUNIT_CASE(test_shake_with_guarded_bufs), KUNIT_CASE(benchmark_hash), {}, }; =20 static struct kunit_suite sha3_test_suite =3D { diff --git a/scripts/crypto/gen-hash-testvecs.py b/scripts/crypto/gen-hash-= testvecs.py index 47f79602e2903..ae2682882cd18 100755 --- a/scripts/crypto/gen-hash-testvecs.py +++ b/scripts/crypto/gen-hash-testvecs.py @@ -109,10 +109,22 @@ def gen_unkeyed_testvecs(alg): hash_update(ctx, compute_hash(alg, data[:data_len])) print_static_u8_array_definition( f'hash_testvec_consolidated[{alg_digest_size_const(alg)}]', hash_final(ctx)) =20 +def gen_additional_sha3_testvecs(): + max_len =3D 4096 + in_data =3D rand_bytes(max_len) + for alg in ['shake128', 'shake256']: + ctx =3D hashlib.new('sha3-256') + for in_len in range(max_len + 1): + out_len =3D (in_len * 293) % (max_len + 1) + out =3D hashlib.new(alg, data=3Din_data[:in_len]).digest(out_l= en) + ctx.update(out) + print_static_u8_array_definition(f'{alg}_testvec_consolidated[SHA3= _256_DIGEST_SIZE]', + ctx.digest()) + def gen_hmac_testvecs(alg): ctx =3D hmac.new(rand_bytes(32), digestmod=3Dalg) data =3D rand_bytes(4096) for data_len in range(len(data) + 1): ctx.update(data[:data_len]) @@ -153,21 +165,28 @@ def gen_additional_poly1305_testvecs(): 'poly1305_allones_macofmacs[POLY1305_DIGEST_SIZE]', Poly1305(key).update(data).digest()) =20 if len(sys.argv) !=3D 2: sys.stderr.write('Usage: gen-hash-testvecs.py ALGORITHM\n') - sys.stderr.write('ALGORITHM may be any supported by Python hashlib, or= poly1305.\n') + sys.stderr.write('ALGORITHM may be any supported by Python hashlib, or= poly1305 or sha3.\n') sys.stderr.write('Example: gen-hash-testvecs.py sha512\n') sys.exit(1) =20 alg =3D sys.argv[1] print('/* SPDX-License-Identifier: GPL-2.0-or-later */') print(f'/* This file was generated by: {sys.argv[0]} {" ".join(sys.argv[1:= ])} */') -gen_unkeyed_testvecs(alg) if alg.startswith('blake2'): + gen_unkeyed_testvecs(alg) gen_additional_blake2_testvecs(alg) elif alg =3D=3D 'poly1305': + gen_unkeyed_testvecs(alg) gen_additional_poly1305_testvecs() -elif alg.startswith('sha3-'): - pass # no HMAC +elif alg =3D=3D 'sha3': + print() + print('/* SHA3-256 test vectors */') + gen_unkeyed_testvecs('sha3-256') + print() + print('/* SHAKE test vectors */') + gen_additional_sha3_testvecs() else: + gen_unkeyed_testvecs(alg) gen_hmac_testvecs(alg) --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 7CC082798F3; Sun, 26 Oct 2025 05:53:06 +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=1761457986; cv=none; b=DfqNheu/bQkWG1jgFtztjOfO85M0dTgSTSqCBW8rmpE0+yTi530cDMOO0dtCFIUNnwdXs+upotWsGnxJ+ew5Lr9Ax/YpWVqTYf5ElyhTjWww5ULIZ9oyYCqKKN4Lgv4HCHxXqw+3gAWcP6OdYTnCVDbRu6VJENnVg9pOVf79PVM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457986; c=relaxed/simple; bh=emlkY+5nNYi2ijHBbHH5c1+/nTs6+mI5TfOU5NxkBH0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=R5kdCKUBrHlHTBHmklqFJbeITbnPVxN8tMLRE2VhhjUqTT+qCYGL90dSMtPt8X2QVFNCv4op7OF5npLXRe2WQFcT53RVu8dCmo8vTQz2QodskJD45W6/cPKhui2TW6bfGmFcF0zgYSILxPT3H5uGLLMyHCXswFc7EFlBBsJ//OU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=M/HDHsbI; 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="M/HDHsbI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0EA00C116C6; Sun, 26 Oct 2025 05:53:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457986; bh=emlkY+5nNYi2ijHBbHH5c1+/nTs6+mI5TfOU5NxkBH0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=M/HDHsbI8X4Ka6VopNPe2FePuOltDSqHCT7iRjQTHzAntSOa3ktqhNOaVG4ORtJrN JJinlHRql8sJ2ZUmE6kSRGdJ7X/k0wqgCasH10F4v1Te63aQVGpZnVtN0L/FiKd454 oNcpIkrSxJrBM9Q6uQJYwAiEpUxO5pHK2yBCG0yqpvvdzHDrSIXcIo0Q8n38hkEcoq uv3U3ZgyGclFqOy5WWCwAfohpB2TRuCdJptorIZAuJqk0CwmIFtKC5goTttmNhNcBM rz9DgLySiS15sGVFeJ2ILXK07YyjrxA7R6Gg6Ag2ZmrgG2mz7gnHJ08/GAfLU85yaJ jZjPkbNjWt+5w== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 07/15] lib/crypto: sha3: Add FIPS cryptographic algorithm self-test Date: Sat, 25 Oct 2025 22:50:24 -0700 Message-ID: <20251026055032.1413733-8-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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 the SHA-3 algorithms are FIPS-approved, add the boot-time self-test which is apparently required. This closely follows the corresponding SHA-1, SHA-256, and SHA-512 tests. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- Documentation/crypto/sha3.rst | 5 +++++ lib/crypto/fips.h | 7 +++++++ lib/crypto/sha3.c | 17 ++++++++++++++++- scripts/crypto/gen-fips-testvecs.py | 4 ++++ 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Documentation/crypto/sha3.rst b/Documentation/crypto/sha3.rst index f8c484feaa291..37640f295118b 100644 --- a/Documentation/crypto/sha3.rst +++ b/Documentation/crypto/sha3.rst @@ -110,10 +110,15 @@ Once all the desired output has been extracted, zeroi= ze the context:: Testing =3D=3D=3D=3D=3D=3D=3D =20 To test the SHA-3 code, use sha3_kunit (CONFIG_CRYPTO_LIB_SHA3_KUNIT_TEST). =20 +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 References =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 .. [1] https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf 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 ee7a2ca92b2c5..6c94b4ebd0fd1 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -15,10 +15,11 @@ #include #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_generic(). On the other hand, on 64-bit architectures with @@ -339,14 +340,28 @@ void shake256(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(shake256); =20 -#ifdef sha3_mod_init_arch +#if defined(sha3_mod_init_arch) || defined(CONFIG_CRYPTO_FIPS) static int __init sha3_mod_init(void) { +#ifdef sha3_mod_init_arch sha3_mod_init_arch(); +#endif + 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) 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:11:52 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 F137627BF99; Sun, 26 Oct 2025 05:53:06 +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=1761457987; cv=none; b=ijt9TwFvqZcWEboemE5m2DNL1pSkCwnihMyB+qMa0O/5Q1zejCQHMrx61t5t2wEWiNt/qyMp67Khx9n53n/0vYInwMLPGX/DMoCC4axh3VPEVcGDorU8JHIPEPPVyePb3IWUCKejSqVSnHGNgX550dQRcKhV+q4E7fRotKOlANU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457987; c=relaxed/simple; bh=9zIsMK25uFIFNUHHbNGygE2cNkGTDolXEFgcGk4aVRY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=uwFeFLkH6p/hT5G9Apo3JbCJ9djKzKpLr5pzyrGJvUeqrjqZS75O+U8u1QhUoCa2kSFxxb5Dx7VGzzUXV+kcofb7qqHBy8qkhZHgh77oES/TseJfdW3SM4uyz1sLRR48g2ny4LOQZietBN/LPoGTmQDAOC9ir/YWhL4hQygbAiU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WDYfrzph; 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="WDYfrzph" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8240BC116B1; Sun, 26 Oct 2025 05:53:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457986; bh=9zIsMK25uFIFNUHHbNGygE2cNkGTDolXEFgcGk4aVRY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WDYfrzphOQ3g0yyOcjMGD4F33TFbRHE0Zl4C69qpePf9wpkyZmEPqTEZuzbheDXBz Jvy6bwMOdxaPAAA4U1jgCh1ZX5iu4EfXhezJR6rTEtM9eKoXOoFNJEHeKOJ7hwZO9+ De8piST2FzwwIDo78tiVMiIEO4+/Txn5b39Hdt4I20B5JbbxgDBt2GsuD7eQQJC5/Z BOA2JIAMY9gxw5kQdqOrIzTXLwfElT1SV3UU4vEEnBD4OIT4oP29iOYj3v6+KXn1h4 dad2FBacZM3UKvSe+dkF2IL/hKTEpdKw/8Fs7OxSH67WwjfYA1+eDPtO2w6DHKsDng OBobBS/X6tmNA== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 08/15] crypto: arm64/sha3 - Update sha3_ce_transform() to prepare for library Date: Sat, 25 Oct 2025 22:50:25 -0700 Message-ID: <20251026055032.1413733-9-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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_sha3_update() too much, as it gets deleted when the SHA-3 code is migrated into lib/crypto/ anyway. Reviewed-by: Ard Biesheuvel Signed-off-by: Eric Biggers Tested-by: Harald Freudenberger --- arch/arm64/crypto/sha3-ce-core.S | 67 ++++++++++++++++---------------- arch/arm64/crypto/sha3-ce-glue.c | 11 +++--- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/arch/arm64/crypto/sha3-ce-core.S b/arch/arm64/crypto/sha3-ce-c= ore.S index 9c77313f5a608..b62bd714839b1 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,59 @@ 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: + /* SHA3-224 (block_size=3D144) */ + ld1 {v25.8b}, [x1], #8 + 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 +184,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 f5c8302349337..250f4fb76b472 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 sha3_finup(struct shash_desc *desc, const u8= *src, unsigned int len, 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:11:52 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 70832280033; Sun, 26 Oct 2025 05:53:07 +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=1761457987; cv=none; b=K2jXBlMSKAsaCa5ghwOUNWHjqpZVnwc63ZHR4RrlhEPRmDE8927OjLRBA6KKJ2IlrA7nPdloHoyW8TVF9iyFi0Wo0zGDvB0WjPXjefkRtMARAXgxnZK3Kkr8pxtrvhGGlANh9cJbKB4p7M7uzbk0yudp5C/UhJSigDOCE+y/MKM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457987; c=relaxed/simple; bh=whd3/UAU+Av8P94JmMwJInAffIEeimNA4qb0IpZM3BE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dXhOin0JmTxGCKLONhzdN+tZpefbNIsKYtTJTQYTCg0ANINB5bdLHYUQkO6z9FwNgA7zOzKHHBzDD+HSpyvTKu2jUloyOzhGzCgnXXrvURDW66APW/kefHun8vlDM+qdEChqLGiENWpQfDYqm08tgY3tCVamJ1OLIKPpsQi8C8g= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=JkuRP+Ev; 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="JkuRP+Ev" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 021BAC4CEE7; Sun, 26 Oct 2025 05:53:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457987; bh=whd3/UAU+Av8P94JmMwJInAffIEeimNA4qb0IpZM3BE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JkuRP+EvVU4pwZ7E6PK7sAdaSnn9Gseea3mkv7c7lrYvjNCdLocin68xIEW73mnIu G1+xw1WwcuiedY94SAOKIfsoKHSKt5ujrL36GWVwkyuu88jHtFRqwIz/HC+kPKB46g r7EBcLuZ6YVTkzr4gLDKn0ib+cL80u/w+62ZekNVooTRwHURSlSj9wFrS8PEKWkPkx Puuj2RELLpDDFm9Yk1CMlIP0PlrIxXruVuJGjXMWxJohG3jBtTwRLMdlJp3iWrjIF4 zAVOdrZYQHiO6qRR5Tu4f2r1PDD5WQ6dS3U/zY7hnWNSinxfn6ZyFcClRen7R96M+x XjAN4Bw14/yGA== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 09/15] lib/crypto: arm64/sha3: Migrate optimized code into library Date: Sat, 25 Oct 2025 22:50:26 -0700 Message-ID: <20251026055032.1413733-10-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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'. Reviewed-by: Ard Biesheuvel Signed-off-by: Eric Biggers Tested-by: Harald Freudenberger --- 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 | 62 ++++++++ 8 files changed, 73 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 250f4fb76b472..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 sha3_finup(struct shash_desc *desc, const u8 *src, unsigned 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 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 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 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 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 a05f5a349cd8c..587490ca65654 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -200,10 +200,15 @@ config CRYPTO_LIB_SHA3 select CRYPTO_LIB_UTILS help The SHA3 library functions. Select this if your module uses any of the 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 0cfdb511f32b6..5515e73bfd5e3 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -279,10 +279,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..6dd5183056da4 --- /dev/null +++ b/lib/crypto/arm64/sha3.h @@ -0,0 +1,62 @@ +/* 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_state *state, const u8 *data, + size_t nblocks, size_t block_size) +{ + if (static_branch_likely(&have_sha3) && likely(may_use_simd())) { + do { + size_t rem; + + kernel_neon_begin(); + rem =3D sha3_ce_transform(state, data, nblocks, + block_size); + kernel_neon_end(); + data +=3D (nblocks - rem) * block_size; + nblocks =3D rem; + } while (nblocks); + } else { + sha3_absorb_blocks_generic(state, data, nblocks, block_size); + } +} + +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:11:52 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 E398B283FE5; Sun, 26 Oct 2025 05:53:07 +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=1761457988; cv=none; b=bTHJ4S08M4IrVrxBBPczKgZkodcdyeM5ElUHIBQP06xSe9pBLnpYG23fukIYMdflU7I1QoqH+7z46yKJ6M2ulah71rHN30Rufe+CLE+/sRei7TQ1q0du+rxs55pNy/5VYXBVxiqCZfEHXV7FEwy4swM2Kg7rPcvgPYS84a9TEUo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457988; c=relaxed/simple; bh=UDeV+e2gTIJPhO0d+cQbe63gbfwYnFHdWs0Ho6ezHg0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VW44EEFf9BJAZnu3amwKoe8EsyoT1qzqQxZ+Mi9MX0N+lPDLZvkc7tnRrOOBSn5zuc5PwmzS2St8vg2Z888Cx+FNyDn9HDyrkT7jKnWGKEqdHfpLmGeQ5ph3h0VOm5o5++9R44BEQn/0OKtVf4XOkNf81zi4s8nxLdxV3U3PFrA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fUSepT19; 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="fUSepT19" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 752A9C116C6; Sun, 26 Oct 2025 05:53:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457987; bh=UDeV+e2gTIJPhO0d+cQbe63gbfwYnFHdWs0Ho6ezHg0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fUSepT19WMWWLhm/3WnKdHgpZlIAoFal9CQHkqFa4qLw5yULTpRBxag4bbuH+qh0V mu4/41ajLPPg4RQziYYXAU+j4GSdkfCo02xmTo9u5LSTsRDjou7i/QU1QXcGljVHrt /35RPFqSU+1Fj37OIUV/UxrvGCrzxmwQfpDdo+xDYvuGyzVNGVqNBk7YI0DEAnFm53 DesU1dALhqTdyz8V6p7hYZUybZAHPYtajemxkf527gYM48pb/+FN67/7gW7pfQkErY uQUWO5uq6eWnkPvraolNzYsPvyLquG22Kye3RWAJyvztSW5fJAzlIdYCPn/BcNtZDr DjevePua//JHA== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 10/15] lib/crypto: s390/sha3: Add optimized Keccak functions Date: Sat, 25 Oct 2025 22:50:27 -0700 Message-ID: <20251026055032.1413733-11-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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" Implement sha3_absorb_blocks() and sha3_keccakf() using the hardware- accelerated SHA-3 support in Message-Security-Assist Extension 6. This accelerates the SHA3-224, SHA3-256, SHA3-384, SHA3-512, and SHAKE256 library functions. Note that arch/s390/crypto/ already has SHA-3 code that uses this extension, but it is exposed only via crypto_shash. This commit brings the same acceleration to the SHA-3 library. The arch/s390/crypto/ version will become redundant and be removed in later changes. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- lib/crypto/Kconfig | 1 + lib/crypto/s390/sha3.h | 88 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 lib/crypto/s390/sha3.h diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index 587490ca65654..7445054fc0ad4 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -204,10 +204,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..668e53da93d2c --- /dev/null +++ b/lib/crypto/s390/sha3.h @@ -0,0 +1,88 @@ +/* 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_sha3); + +static void sha3_absorb_blocks(struct sha3_state *state, const u8 *data, + size_t nblocks, size_t block_size) +{ + if (static_branch_likely(&have_sha3)) { + /* + * Note that KIMD assumes little-endian order of the state + * words. sha3_state already uses that order, though, so + * there's no need for a byteswap. + */ + switch (block_size) { + case SHA3_224_BLOCK_SIZE: + cpacf_kimd(CPACF_KIMD_SHA3_224, state, + data, nblocks * block_size); + return; + case SHA3_256_BLOCK_SIZE: + /* + * This case handles both SHA3-256 and SHAKE256, since + * they have the same block size. + */ + cpacf_kimd(CPACF_KIMD_SHA3_256, state, + data, nblocks * block_size); + return; + case SHA3_384_BLOCK_SIZE: + cpacf_kimd(CPACF_KIMD_SHA3_384, state, + data, nblocks * block_size); + return; + case SHA3_512_BLOCK_SIZE: + cpacf_kimd(CPACF_KIMD_SHA3_512, state, + data, nblocks * block_size); + return; + } + } + sha3_absorb_blocks_generic(state, data, nblocks, block_size); +} + +static void sha3_keccakf(struct sha3_state *state) +{ + if (static_branch_likely(&have_sha3)) { + /* + * 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. + */ + 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) +{ + int num_present =3D 0; + int num_possible =3D 0; + + if (!cpu_have_feature(S390_CPU_FEATURE_MSA)) + return; + /* + * Since all the SHA-3 functions are in Message-Security-Assist + * Extension 6, just treat them as all or nothing. This way we need + * only one static_key. + */ +#define QUERY(opcode, func) \ + ({ num_present +=3D !!cpacf_query_func(opcode, func); num_possible++; }) + QUERY(CPACF_KIMD, CPACF_KIMD_SHA3_224); + QUERY(CPACF_KIMD, CPACF_KIMD_SHA3_256); + QUERY(CPACF_KIMD, CPACF_KIMD_SHA3_384); + QUERY(CPACF_KIMD, CPACF_KIMD_SHA3_512); +#undef QUERY + + if (num_present =3D=3D num_possible) + static_branch_enable(&have_sha3); + else if (num_present !=3D 0) + pr_warn("Unsupported combination of SHA-3 facilities\n"); +} --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 610B82853F8; Sun, 26 Oct 2025 05:53:08 +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=1761457988; cv=none; b=tBubLI08uqpvoyHD6fGbbS95MVaeJ0TrnyP8MNU2H3pBmSA2K7rhC8N0UfUST5dVOzE+51CopynLfIXM20CN9kjvLF39bo2VqNDPnhY58P+xfMU++jEIYRFqTh0vSNOtx3SvULYKG0F3FxEvdpnvkiIkIIZugrqKuwptTW8O6GA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457988; c=relaxed/simple; bh=TbVLbaUPq3TI8tu/I7Jnha1NiyG1jt55JtZfnYEOEf4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Eduzcf99I37nF2j4sxaJfyu42JBq/bPkOTmsvGIb6WDi7BLUuv1nhf6isGg1T+/uX7O+U0BeRqnnRCOWqHIHcMsi8JKCPbIYFa2xDiEk0i5CRUpsN9zMrw2eGxlSR9rHi34mRZHwyf35+wdYOPbAcPOv2mh/BhqZYWAJUOdiCAc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VzIzVp/9; 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="VzIzVp/9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E8E41C4AF0B; Sun, 26 Oct 2025 05:53:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457988; bh=TbVLbaUPq3TI8tu/I7Jnha1NiyG1jt55JtZfnYEOEf4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VzIzVp/98BzPaqHpgDXy9lQcQUD53jo9sL7ZNoHHIu2yiWxxWDvWMQohZSuBT20il oICPtpc0wRBUgfldpYr23cY5Xg2JLjRi7z+yy4c/RKLNyPIfGtqZQq1JNBPe8OMKVJ XYBZFFXliuGCsJykRNPn/Mzv5W4Sodla4EOmohhJ2ZTJgsUWDFPm5CT+EzWfNYqIFG prh6Qdqz/COR2oh6fY0Jff+Hdo71h74/WNC+VBmSzyfGJA5joMC+Ws0fcgaJAjg9ck 0w4fSYweNEqoud+Kb/BiVCKP9p5Ql4cEDmZO4gpjTijkIa8FCdgsafazfWPToHUg/7 IEzljMhGNvZwg== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 11/15] lib/crypto: sha3: Support arch overrides of one-shot digest functions Date: Sat, 25 Oct 2025 22:50:28 -0700 Message-ID: <20251026055032.1413733-12-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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" Add support for architecture-specific overrides of sha3_224(), sha3_256(), sha3_384(), and sha3_512(). This will be used to implement these functions more efficiently on s390 than is possible via the usual init + update + final flow. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- lib/crypto/sha3.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/lib/crypto/sha3.c b/lib/crypto/sha3.c index 6c94b4ebd0fd1..a598138d47a59 100644 --- a/lib/crypto/sha3.c +++ b/lib/crypto/sha3.c @@ -278,44 +278,81 @@ void shake_squeeze(struct shake_ctx *shake_ctx, u8 *o= ut, size_t out_len) } ctx->squeeze_offset =3D squeeze_offset; } EXPORT_SYMBOL_GPL(shake_squeeze); =20 +#ifndef sha3_224_arch +static inline bool sha3_224_arch(const u8 *in, size_t in_len, + u8 out[SHA3_224_DIGEST_SIZE]) +{ + return false; +} +#endif +#ifndef sha3_256_arch +static inline bool sha3_256_arch(const u8 *in, size_t in_len, + u8 out[SHA3_256_DIGEST_SIZE]) +{ + return false; +} +#endif +#ifndef sha3_384_arch +static inline bool sha3_384_arch(const u8 *in, size_t in_len, + u8 out[SHA3_384_DIGEST_SIZE]) +{ + return false; +} +#endif +#ifndef sha3_512_arch +static inline bool sha3_512_arch(const u8 *in, size_t in_len, + u8 out[SHA3_512_DIGEST_SIZE]) +{ + return false; +} +#endif + void sha3_224(const u8 *in, size_t in_len, u8 out[SHA3_224_DIGEST_SIZE]) { struct sha3_ctx ctx; =20 + if (sha3_224_arch(in, in_len, out)) + return; sha3_224_init(&ctx); sha3_update(&ctx, in, in_len); sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_224); =20 void sha3_256(const u8 *in, size_t in_len, u8 out[SHA3_256_DIGEST_SIZE]) { struct sha3_ctx ctx; =20 + if (sha3_256_arch(in, in_len, out)) + return; sha3_256_init(&ctx); sha3_update(&ctx, in, in_len); sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_256); =20 void sha3_384(const u8 *in, size_t in_len, u8 out[SHA3_384_DIGEST_SIZE]) { struct sha3_ctx ctx; =20 + if (sha3_384_arch(in, in_len, out)) + return; sha3_384_init(&ctx); sha3_update(&ctx, in, in_len); sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_384); =20 void sha3_512(const u8 *in, size_t in_len, u8 out[SHA3_512_DIGEST_SIZE]) { struct sha3_ctx ctx; =20 + if (sha3_512_arch(in, in_len, out)) + return; sha3_512_init(&ctx); sha3_update(&ctx, in, in_len); sha3_final(&ctx, out); } EXPORT_SYMBOL_GPL(sha3_512); --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 3D9F9288C3D; Sun, 26 Oct 2025 05:53:08 +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=1761457989; cv=none; b=VBDtU6NIIL4l1rLLoyW/9YWtV0Pta9VpYLhiJvBizPP600E1jP/AWwvLMo9QzBk06oUgF4cSXDxpLydFuRNYMtCFggkvUOggIC9iDN6IVNKys/hiOTT68L1cgF7VgpwTIDie8ElMNr9xc39IaoQ2I5Ny3sar7CUPGkMzvmsb7k4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457989; c=relaxed/simple; bh=tK4ZwtbvVT+WWMAoNFlch+KJGW1l/8qhroTz/lgXZ+w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JtywViQyNsVhA55lRfIMU6mb756YGhJ0d1ffxEBXUgPC06MLu1Vu2uQb1JUdnPfTs6wt7vsk05MZ9Bf4rwfGgaQXCinBW5nkxcqZ3gaI2cFeIz9q9KocRemm80Gzro9Ir5VfSm7zYph6FDhcJJTHYKqffQzEDMlZNuUrtbQi8ig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VjCjZuVI; 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="VjCjZuVI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 68413C116C6; Sun, 26 Oct 2025 05:53:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457988; bh=tK4ZwtbvVT+WWMAoNFlch+KJGW1l/8qhroTz/lgXZ+w=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VjCjZuVIcC04piSCOr/VPr+Acxc4Jbc9WzwyZjZsuZyijzdgb4V2ePe38orck/ib4 0QDKFZgHjokI7bVMZWsYUuc5osS8lr1CTrTtc4tVumVXTGVy2QFbBft1mQwlkFKYwj EyuYZXpOpVH7tKFGUGFf9wvRiuQibbsFoeFc5THM2DijB77in3MrMLNRpya/Bj0PuX ZDj47k4Sy1BRg1Z5kQEmwrVqxi6F4NHEQldxYeGterWeNg57gMojOcKASpAW3uDvEs Zz7xK6V/lReCdjwRzMavc+tLiIDxETdLKM7iZYd/rjCBbR6EKISWx5mn73nHurZXcE S5wYHNmhhtH5g== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 12/15] lib/crypto: s390/sha3: Add optimized one-shot SHA-3 digest functions Date: Sat, 25 Oct 2025 22:50:29 -0700 Message-ID: <20251026055032.1413733-13-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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" Some z/Architecture processors can compute a SHA-3 digest in a single instruction. Use this capability to implement the sha3_224(), sha3_256(), sha3_384(), and sha3_512() library functions. Note that the performance improvement is likely to be relatively small and be noticeable primarily on short messages, as the actual Keccak permutation is already accelerated via the implementations of sha3_absorb_blocks() and sha3_keccakf(). Nevertheless, arch/s390/crypto/ takes advantage of the "do the full SHA-3" capability, and it was requested that lib/crypto/ do so as well for parity with it. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- lib/crypto/s390/sha3.h | 67 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/lib/crypto/s390/sha3.h b/lib/crypto/s390/sha3.h index 668e53da93d2c..85471404775a3 100644 --- a/lib/crypto/s390/sha3.h +++ b/lib/crypto/s390/sha3.h @@ -6,10 +6,11 @@ */ #include #include =20 static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_sha3); +static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_sha3_init_optim); =20 static void sha3_absorb_blocks(struct sha3_state *state, const u8 *data, size_t nblocks, size_t block_size) { if (static_branch_likely(&have_sha3)) { @@ -58,10 +59,65 @@ static void sha3_keccakf(struct sha3_state *state) } else { sha3_keccakf_generic(state); } } =20 +static inline bool s390_sha3(int func, const u8 *in, size_t in_len, + u8 *out, size_t out_len) +{ + struct sha3_state state; + + if (!static_branch_likely(&have_sha3)) + return false; + + if (static_branch_likely(&have_sha3_init_optim)) + func |=3D CPACF_KLMD_NIP | CPACF_KLMD_DUFOP; + else + memset(&state, 0, sizeof(state)); + + cpacf_klmd(func, &state, in, in_len); + + if (static_branch_likely(&have_sha3_init_optim)) + kmsan_unpoison_memory(&state, out_len); + + memcpy(out, &state, out_len); + memzero_explicit(&state, sizeof(state)); + return true; +} + +#define sha3_224_arch sha3_224_arch +static bool sha3_224_arch(const u8 *in, size_t in_len, + u8 out[SHA3_224_DIGEST_SIZE]) +{ + return s390_sha3(CPACF_KLMD_SHA3_224, in, in_len, + out, SHA3_224_DIGEST_SIZE); +} + +#define sha3_256_arch sha3_256_arch +static bool sha3_256_arch(const u8 *in, size_t in_len, + u8 out[SHA3_256_DIGEST_SIZE]) +{ + return s390_sha3(CPACF_KLMD_SHA3_256, in, in_len, + out, SHA3_256_DIGEST_SIZE); +} + +#define sha3_384_arch sha3_384_arch +static bool sha3_384_arch(const u8 *in, size_t in_len, + u8 out[SHA3_384_DIGEST_SIZE]) +{ + return s390_sha3(CPACF_KLMD_SHA3_384, in, in_len, + out, SHA3_384_DIGEST_SIZE); +} + +#define sha3_512_arch sha3_512_arch +static bool sha3_512_arch(const u8 *in, size_t in_len, + u8 out[SHA3_512_DIGEST_SIZE]) +{ + return s390_sha3(CPACF_KLMD_SHA3_512, in, in_len, + out, SHA3_512_DIGEST_SIZE); +} + #define sha3_mod_init_arch sha3_mod_init_arch static void sha3_mod_init_arch(void) { int num_present =3D 0; int num_possible =3D 0; @@ -77,12 +133,19 @@ static void sha3_mod_init_arch(void) ({ num_present +=3D !!cpacf_query_func(opcode, func); num_possible++; }) QUERY(CPACF_KIMD, CPACF_KIMD_SHA3_224); QUERY(CPACF_KIMD, CPACF_KIMD_SHA3_256); QUERY(CPACF_KIMD, CPACF_KIMD_SHA3_384); QUERY(CPACF_KIMD, CPACF_KIMD_SHA3_512); + QUERY(CPACF_KLMD, CPACF_KLMD_SHA3_224); + QUERY(CPACF_KLMD, CPACF_KLMD_SHA3_256); + QUERY(CPACF_KLMD, CPACF_KLMD_SHA3_384); + QUERY(CPACF_KLMD, CPACF_KLMD_SHA3_512); #undef QUERY =20 - if (num_present =3D=3D num_possible) + if (num_present =3D=3D num_possible) { static_branch_enable(&have_sha3); - else if (num_present !=3D 0) + if (test_facility(86)) + static_branch_enable(&have_sha3_init_optim); + } else if (num_present !=3D 0) { pr_warn("Unsupported combination of SHA-3 facilities\n"); + } } --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 E6E6F298CA5; Sun, 26 Oct 2025 05:53:09 +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=1761457990; cv=none; b=o6JFKDsfsE6CyBxFb1PTphPCNorHOfOS7gCW512klsZtPf8A1H2iB4qZ5pwJs+mGhQpHy6qMO+4aAvW6kzg5+7gotrsDbOMPgGYBP6cT9obeG4zh2OCJ6+iivR54TkvVze00sG16iFELOTZp10cC1SuRk4abAMs4fDoFLhJeCOY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457990; c=relaxed/simple; bh=J3m+RqWldOSAlbAr+elclDhB5NSc/+pHmiWDmVt7Zz4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JNQmTLdwVymRe40RyU0Lb2ztocO+Qs64K5NXCG4dcmrp0KeNn71floBRlA49QmBKAShzJWH1BgxGg0i9KtXg8L3ZPTBR2pypYsUgR4+XL3J/t3Fdy4RhkWc1upUn26QXE3xl+inZrUgCpduilX7//vFo8308xvbOXp79pmYM4f4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=fJWEPIXQ; 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="fJWEPIXQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DBBC1C4CEE7; Sun, 26 Oct 2025 05:53:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457989; bh=J3m+RqWldOSAlbAr+elclDhB5NSc/+pHmiWDmVt7Zz4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fJWEPIXQJVdiF8om1EtHzN8GX9OBPNVfzf2bgq3sTdtKwrz3f5gMcKWNV3fJW3aId FQgVyV5Nq8FwB4EVlMSZ2dgwXr6JWPzyQpRysrgBNptPeidPWzySe9sCEcAzCHgd46 wmFyiTVTrbUTd9lnxhdBncQ6tpkZ5wwQKND0af8Oo5rpoFoPMKAY2UBbkh/ExT620y mon9WeI8757GA5SKwNN9FC4UJ6gz853GlVrykUPmtNQ3pE0FwFGtVQ1lypnXh26l85 yY+p7BuEsxsmvbc2PS0erCbH1bB4KZYL1AigdrHD1iPXQkMHFMRXFqy4wayfpB9cJu N2dD2j64H0kvQ== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 13/15] crypto: jitterentropy - Use default sha3 implementation Date: Sat, 25 Oct 2025 22:50:30 -0700 Message-ID: <20251026055032.1413733-14-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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. Note that jitterentropy should just use the library API instead of crypto_shash. But that belongs in a separate change later. Reviewed-by: Ard Biesheuvel Signed-off-by: Eric Biggers Tested-by: Harald Freudenberger --- 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:11:52 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 D8950296BD1; Sun, 26 Oct 2025 05:53:09 +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=1761457990; cv=none; b=or+jq9IZT8hPnIDP0/F2IikO0Q5GDZOz+daywgKtwDzwZYqEU8fsiMz72FSIee0IXPZPHqKJyijmTqiaNqLect17MDhR1sYVKXLAc4MydjCsDVHzDo7xESBBB6p20vFrLTJCJoZoeD+3sgguAo1+y7R9Aci1zj/HMrybZuEeTU4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457990; c=relaxed/simple; bh=Lzx62QBuaeOXq0bj2I+HZPtnTXKhz7ZQUxNW7xFMCUQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=F/u1iDSHUbRgKGJpkBobjoxVnIXZOu4wQTN5Sg9CsPnSqL3CQ4Wo/HwkX8i0WL8JxbSl+AldO5DJm3as2zCmChoS1cBFHwBqj1JsUFrxdOYYeFlUXV54xNkw+Fell0BRzhc4xCpXMiUYM/Bgrn+1R1tvzK1ny73aqEf4yCyQTVg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eFq2JDXg; 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="eFq2JDXg" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 63EA8C4AF16; Sun, 26 Oct 2025 05:53:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457989; bh=Lzx62QBuaeOXq0bj2I+HZPtnTXKhz7ZQUxNW7xFMCUQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=eFq2JDXgvXOyXU2M+OjGTFwuhY6MD4rN2xC1cvgsdXAl3V6rUPyGIRL2IxGVBtbct +cXMtc9F6yF/yPQNRX7D9e4nWj1NGTygsUXASKifPtPv3F8xLMSHbty1dd4nUrimWS I/WWqgfkqmApZFfkeru8AzRLobi421VRAvggTJmyX6e4s6gbCFzmP5RHJqHnMZNLfM r9e46Cs9yBxAGqgSNjIUA+wtzCv/uD+y/IDh7tQBL/nSEWchbrEaSYwPMwzSSDAlmg LC0sdS6NJF3/8lzKgEeMl4qitupFl3egd7eV8cyuzMlQDgDQdmB638fqWzKbFPSDCO rfNyKbE/z5O8g== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 14/15] crypto: sha3 - Reimplement using library API Date: Sat, 25 Oct 2025 22:50:31 -0700 Message-ID: <20251026055032.1413733-15-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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. (Note that there is no security purpose in wrapping SHA-3 with HMAC. HMAC was designed for older algorithms that don't resist length extension attacks. But since someone could be using "hmac(sha3-*)" via crypto_shash anyway, keep supporting it for now.) Reviewed-by: Ard Biesheuvel Signed-off-by: Eric Biggers Tested-by: Harald Freudenberger --- crypto/Kconfig | 1 + crypto/Makefile | 2 +- crypto/sha3.c | 166 ++++++++++++++++++++++++ crypto/sha3_generic.c | 290 ------------------------------------------ crypto/testmgr.c | 8 ++ include/crypto/sha3.h | 6 - 6 files changed, 176 insertions(+), 297 deletions(-) create mode 100644 crypto/sha3.c delete mode 100644 crypto/sha3_generic.c diff --git a/crypto/Kconfig b/crypto/Kconfig index 0a7e74ac870b0..57b85e903cf0b 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -1004,10 +1004,11 @@ config CRYPTO_SHA512 10118-3), including HMAC support. =20 config CRYPTO_SHA3 tristate "SHA-3" select CRYPTO_HASH + select CRYPTO_LIB_SHA3 help SHA-3 secure hash algorithms (FIPS 202, ISO/IEC 10118-3) =20 config CRYPTO_SM3_GENERIC tristate "SM3 (ShangMi 3)" diff --git a/crypto/Makefile b/crypto/Makefile index 5b02ca2cb04e0..0388ff8d219d1 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.o diff --git a/crypto/sha3.c b/crypto/sha3.c new file mode 100644 index 0000000000000..8f364979ec890 --- /dev/null +++ b/crypto/sha3.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Crypto API support for SHA-3 + * (https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf) + */ +#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("Crypto API support for SHA-3"); + +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 3ab7adc1cdce5..90d06c3ec9679 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -5102,31 +5102,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) } @@ -5476,31 +5480,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 a7503dfc1a044..d713b5e3d6956 100644 --- a/include/crypto/sha3.h +++ b/include/crypto/sha3.h @@ -35,14 +35,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); - /* * State for the Keccak-f[1600] permutation: 25 64-bit words. * * We usually keep the state words as little-endian, to make absorbing and * squeezing easier. (It means that absorbing and squeezing can just trea= t the @@ -50,12 +46,10 @@ int crypto_sha3_init(struct shash_desc *desc); * temporarily by implementations of the permutation that need native-endi= an * words. Of course, that conversion is a no-op on little-endian machines. */ struct sha3_state { union { - u64 st[SHA3_STATE_SIZE / 8]; /* temporarily retained for compatibility p= urposes */ - __le64 words[SHA3_STATE_SIZE / 8]; u8 bytes[SHA3_STATE_SIZE]; =20 u64 native_words[SHA3_STATE_SIZE / 8]; /* see comment above */ }; --=20 2.51.1.dirty From nobody Sat Feb 7 15:11:52 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 D5C4629E0ED; Sun, 26 Oct 2025 05:53:10 +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=1761457991; cv=none; b=LjCrPg9qK0Q+DTaBQdEMVGVOqIrdz29H5OMq8pTOB3jr0Edqksw++aRkd/zG2BG3hD4g6XMPsPRYDc2l7g6jqY2wGB8nyIwUdm/T/cXyq0iXfkpg/uDm8+9GCLJwFMgfZIvTLdQiv9UYkmQ3zRcqmmBJGf8PPduOVHCIaY0eiRI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761457991; c=relaxed/simple; bh=FxkTtqmvapgMOXF2seH3qE7iMfwcM5QZ6SqZ2cx83o8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=e74to5sztchHtYQliKEQMrl4KDi70QIP/0bDFn9QIDqEun4+SNXOdYNvMhgdTHhnxMyr4vQ/9QO9wDIVZVhetY5Ezkm1GpJNLcOUjr/yAex0qGMJYJpOUovDTxz5AHrFCEskc8N2SWElQVCy9kZDkpjm3YlZXe221uxTPg+AGmU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=tNUDlFIP; 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="tNUDlFIP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DF5D7C116C6; Sun, 26 Oct 2025 05:53:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1761457990; bh=FxkTtqmvapgMOXF2seH3qE7iMfwcM5QZ6SqZ2cx83o8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tNUDlFIPgnqc0EXEqpGqAa6pDym0eG8iIlNmAQcVq8kAN61eKZbgxL3QMv+pKpKOb LPAzqHg2C9BXJ/GtXU6zUaTJkuo1l6p/pvUvot0KrYPB7/hAclSxhQrphjIotiSnN0 wtA7c2FIsig0ezUo3zECgZHGurQn/WhCqgzCR6/YSrimP5WMV1D6iGoAuM470mUSgH CvFtqMoyB4mmceTewc5Q0DzK5gX94lQFg8gfBtYOJ5I4v7FIOfgV51jlhI8OZC1Wuw sE0Gt29NwPTpWc0ZYsqcAmGhbPLnRf7Yx2J5EYK8J3e2Lmrnp61vMEBN2A9Rqi6CWU 9Y58m3Tc8JQMw== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: David Howells , Ard Biesheuvel , "Jason A . Donenfeld" , Eric Biggers , Holger Dengler , Harald Freudenberger , Herbert Xu , linux-arm-kernel@lists.infradead.org, linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 15/15] crypto: s390/sha3 - Remove superseded SHA-3 code Date: Sat, 25 Oct 2025 22:50:32 -0700 Message-ID: <20251026055032.1413733-16-ebiggers@kernel.org> X-Mailer: git-send-email 2.51.1.dirty In-Reply-To: <20251026055032.1413733-1-ebiggers@kernel.org> References: <20251026055032.1413733-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 SHA-3 library now utilizes the same s390 SHA-3 acceleration capabilities as the arch/s390/crypto/ SHA-3 crypto_shash algorithms. Moreover, crypto/sha3.c now uses the SHA-3 library. The result is that all SHA-3 APIs are now s390-accelerated without any need for the old SHA-3 code in arch/s390/crypto/. Remove this superseded code. Also update the s390 defconfig and debug_defconfig files to enable CONFIG_CRYPTO_SHA3 instead of CONFIG_CRYPTO_SHA3_256_S390 and CONFIG_CRYPTO_SHA3_512_S390. This makes it so that the s390-optimized SHA-3 continues to be built when either of these defconfigs is used. Signed-off-by: Eric Biggers Reviewed-by: Ard Biesheuvel Tested-by: Harald Freudenberger --- 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 ---------------------- 8 files changed, 2 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 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 7415d56649a52..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 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 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 sha3_224_import(struct shash_desc *desc, const void *in) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - - 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 sha3_256_export, - .import =3D 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 sha3_256_export, /* same as for 256 */ - .import =3D 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 ff6ee55844005..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 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 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 sha3_384_import(struct shash_desc *desc, const void *in) -{ - struct s390_sha_ctx *sctx =3D shash_desc_ctx(desc); - - 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 sha3_512_export, - .import =3D 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 sha3_512_export, /* same as for 512 */ - .import =3D 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"); --=20 2.51.1.dirty