From nobody Sun Oct 5 10:44:55 2025 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 954B526D4E3; Tue, 5 Aug 2025 22:30: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=1754433007; cv=none; b=UBaSj+JPGKY43HfRPMAlwfIpHc/1+yhtQRYh1eV8LX0a9GPPWFRiMpWsNt9xqKqn067sQPWK/MQ9iQwQpfZAv/nAo269zRklTqFESI2mcjkvXMsXGYQY4JQwhFAErqO+7SNu3bsvjA/sgMuhz0ADBElOH+KB6aQt31U+qvSYCsE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754433007; c=relaxed/simple; bh=diEwP3bTzTcLxERSznAaXyRLMCt8PO8TDpNygKx37DY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Iwwbx4WBaYWoGbYAcHDsk3ebkYvuBh995pPVc6W3XMJ6svqkRao6AnRiVfGveFxpNn1q/3tro25CTrMWYrpNZTov3KmCihGCZhITbypOMvTzNrLrXlEaKyXbjf5WCvv4rDepGnzDv9XsLtdtWNpwTxp99rLYfg3zGr3DA2M4AKg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=oPExYvqj; 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="oPExYvqj" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A557BC4CEF7; Tue, 5 Aug 2025 22:30:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754433007; bh=diEwP3bTzTcLxERSznAaXyRLMCt8PO8TDpNygKx37DY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oPExYvqjMiDHILp6aZn9Vu1w8mg3kTAc+DFdlMf7tSiizg+GIyxIvd0FQU7Tm98Al NsvTr8fqNiVPBWbEPkSS3PADw4rljUdSrcmsOy7mLOxG76pLvrVjlxqM4vMu1ENJLz 6a9Lh8/9+eP8XX5p9F3tPclNzginiNCl/TkMJE6jRQuMnL7+E9eCm3uNSwaOURPBy1 +cuXCNJc3Ka/upunCrh7wYTmw6rOoudUqFZxeNsYlUgtCnlHPE44qAMNHH2MFoE+WB bBSEtqTG9ldvDyJFMEajyczFwrZOJ5tSdXWaOFPQf+fC2nJ6OcehWj62MOJw3nQiKm +AHOjIFw9WVhA== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, sparclinux@vger.kernel.org, Eric Biggers Subject: [PATCH v2 1/7] lib/crypto: md5: Add MD5 and HMAC-MD5 library functions Date: Tue, 5 Aug 2025 15:28:49 -0700 Message-ID: <20250805222855.10362-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250805222855.10362-1-ebiggers@kernel.org> References: <20250805222855.10362-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 library functions for MD5, including HMAC support. The MD5 implementation is derived from crypto/md5.c. This closely mirrors the corresponding SHA-1 and SHA-2 changes. Like SHA-1 and SHA-2, support for architecture-optimized MD5 implementations is included. I originally proposed dropping those, but unfortunately there is an AF_ALG user of the PowerPC MD5 code (https://lore.kernel.org/r/c4191597-341d-4fd7-bc3d-13daf7666c41@csgroup.eu/= ), and dropping that code would be viewed as a performance regression. We don't add new software algorithm implementations purely for AF_ALG, as escalating to kernel mode merely to do calculations that could be done in userspace is inefficient and is completely the wrong design. But since this one already existed, it gets grandfathered in for now. An objection was also raised to dropping the SPARC64 MD5 code because it utilizes the CPU's direct support for MD5, although it remains unclear that anyone is using that. Regardless, we'll keep these around for now. Note that while MD5 is a legacy algorithm that is vulnerable to practical collision attacks, it still has various in-kernel users that implement legacy protocols. Switching to a simple library API, which is the way the code should have been organized originally, will greatly simplify their code. For example: MD5: drivers/md/dm-crypt.c (for lmk IV generation) fs/nfsd/nfs4recover.c fs/ecryptfs/ fs/smb/client/ net/{ipv4,ipv6}/ (for TCP-MD5 signatures) HMAC-MD5: fs/smb/client/ fs/smb/server/ (Also net/sctp/ if it continues using HMAC-MD5 for cookie generation. However, that use case has the flexibility to upgrade to a more modern algorithm, which I'll be proposing instead.) As usual, the "md5" and "hmac(md5)" crypto_shash algorithms will also be reimplemented on top of these library functions. For "hmac(md5)" this will provide a faster, more streamlined implementation. Signed-off-by: Eric Biggers --- include/crypto/md5.h | 181 +++++++++++++++++++++++- lib/crypto/Kconfig | 10 ++ lib/crypto/Makefile | 10 ++ lib/crypto/md5.c | 322 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 522 insertions(+), 1 deletion(-) create mode 100644 lib/crypto/md5.c diff --git a/include/crypto/md5.h b/include/crypto/md5.h index 28ee533a0507a..d8e4d3c7c0369 100644 --- a/include/crypto/md5.h +++ b/include/crypto/md5.h @@ -5,10 +5,11 @@ #include #include =20 #define MD5_DIGEST_SIZE 16 #define MD5_HMAC_BLOCK_SIZE 64 +#define MD5_BLOCK_SIZE 64 #define MD5_BLOCK_WORDS 16 #define MD5_HASH_WORDS 4 #define MD5_STATE_SIZE 24 =20 #define MD5_H0 0x67452301UL @@ -25,6 +26,184 @@ struct md5_state { u32 hash[MD5_HASH_WORDS]; u64 byte_count; u32 block[MD5_BLOCK_WORDS]; }; =20 -#endif +/* State for the MD5 compression function */ +struct md5_block_state { + u32 h[MD5_HASH_WORDS]; +}; + +/** + * struct md5_ctx - Context for hashing a message with MD5 + * @state: the compression function state + * @bytecount: number of bytes processed so far + * @buf: partial block buffer; bytecount % MD5_BLOCK_SIZE bytes are valid + */ +struct md5_ctx { + struct md5_block_state state; + u64 bytecount; + u8 buf[MD5_BLOCK_SIZE] __aligned(__alignof__(__le64)); +}; + +/** + * md5_init() - Initialize an MD5 context for a new message + * @ctx: the context to initialize + * + * If you don't need incremental computation, consider md5() instead. + * + * Context: Any context. + */ +void md5_init(struct md5_ctx *ctx); + +/** + * md5_update() - Update an MD5 context with message data + * @ctx: the context to update; must have been initialized + * @data: the message data + * @len: the data length in bytes + * + * This can be called any number of times. + * + * Context: Any context. + */ +void md5_update(struct md5_ctx *ctx, const u8 *data, size_t len); + +/** + * md5_final() - Finish computing an MD5 message digest + * @ctx: the context to finalize; must have been initialized + * @out: (output) the resulting MD5 message digest + * + * After finishing, this zeroizes @ctx. So the caller does not need to do= it. + * + * Context: Any context. + */ +void md5_final(struct md5_ctx *ctx, u8 out[MD5_DIGEST_SIZE]); + +/** + * md5() - Compute MD5 message digest in one shot + * @data: the message data + * @len: the data length in bytes + * @out: (output) the resulting MD5 message digest + * + * Context: Any context. + */ +void md5(const u8 *data, size_t len, u8 out[MD5_DIGEST_SIZE]); + +/** + * struct hmac_md5_key - Prepared key for HMAC-MD5 + * @istate: private + * @ostate: private + */ +struct hmac_md5_key { + struct md5_block_state istate; + struct md5_block_state ostate; +}; + +/** + * struct hmac_md5_ctx - Context for computing HMAC-MD5 of a message + * @hash_ctx: private + * @ostate: private + */ +struct hmac_md5_ctx { + struct md5_ctx hash_ctx; + struct md5_block_state ostate; +}; + +/** + * hmac_md5_preparekey() - Prepare a key for HMAC-MD5 + * @key: (output) the key structure to initialize + * @raw_key: the raw HMAC-MD5 key + * @raw_key_len: the key length in bytes. All key lengths are supported. + * + * Note: the caller is responsible for zeroizing both the struct hmac_md5_= key + * and the raw key once they are no longer needed. + * + * Context: Any context. + */ +void hmac_md5_preparekey(struct hmac_md5_key *key, + const u8 *raw_key, size_t raw_key_len); + +/** + * hmac_md5_init() - Initialize an HMAC-MD5 context for a new message + * @ctx: (output) the HMAC context to initialize + * @key: the prepared HMAC key + * + * If you don't need incremental computation, consider hmac_md5() instead. + * + * Context: Any context. + */ +void hmac_md5_init(struct hmac_md5_ctx *ctx, const struct hmac_md5_key *ke= y); + +/** + * hmac_md5_init_usingrawkey() - Initialize an HMAC-MD5 context for a new + * message, using a raw key + * @ctx: (output) the HMAC context to initialize + * @raw_key: the raw HMAC-MD5 key + * @raw_key_len: the key length in bytes. All key lengths are supported. + * + * If you don't need incremental computation, consider hmac_md5_usingrawke= y() + * instead. + * + * Context: Any context. + */ +void hmac_md5_init_usingrawkey(struct hmac_md5_ctx *ctx, + const u8 *raw_key, size_t raw_key_len); + +/** + * hmac_md5_update() - Update an HMAC-MD5 context with message data + * @ctx: the HMAC context to update; must have been initialized + * @data: the message data + * @data_len: the data length in bytes + * + * This can be called any number of times. + * + * Context: Any context. + */ +static inline void hmac_md5_update(struct hmac_md5_ctx *ctx, + const u8 *data, size_t data_len) +{ + md5_update(&ctx->hash_ctx, data, data_len); +} + +/** + * hmac_md5_final() - Finish computing an HMAC-MD5 value + * @ctx: the HMAC context to finalize; must have been initialized + * @out: (output) the resulting HMAC-MD5 value + * + * After finishing, this zeroizes @ctx. So the caller does not need to do= it. + * + * Context: Any context. + */ +void hmac_md5_final(struct hmac_md5_ctx *ctx, u8 out[MD5_DIGEST_SIZE]); + +/** + * hmac_md5() - Compute HMAC-MD5 in one shot, using a prepared key + * @key: the prepared HMAC key + * @data: the message data + * @data_len: the data length in bytes + * @out: (output) the resulting HMAC-MD5 value + * + * If you're using the key only once, consider using hmac_md5_usingrawkey(= ). + * + * Context: Any context. + */ +void hmac_md5(const struct hmac_md5_key *key, const u8 *data, size_t data_= len, + u8 out[MD5_DIGEST_SIZE]); + +/** + * hmac_md5_usingrawkey() - Compute HMAC-MD5 in one shot, using a raw key + * @raw_key: the raw HMAC-MD5 key + * @raw_key_len: the key length in bytes. All key lengths are supported. + * @data: the message data + * @data_len: the data length in bytes + * @out: (output) the resulting HMAC-MD5 value + * + * If you're using the key multiple times, prefer to use hmac_md5_preparek= ey() + * followed by multiple calls to hmac_md5() instead. + * + * Context: Any context. + */ +void hmac_md5_usingrawkey(const u8 *raw_key, size_t raw_key_len, + const u8 *data, size_t data_len, + u8 out[MD5_DIGEST_SIZE]); + +#endif /* _CRYPTO_MD5_H */ diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index c2b65b6a9bb6f..8ccb5b794b76a 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -99,10 +99,20 @@ config CRYPTO_LIB_CURVE25519 one, if one is available and enabled. =20 config CRYPTO_LIB_DES tristate =20 +config CRYPTO_LIB_MD5 + tristate + help + The MD5 and HMAC-MD5 library functions. Select this if your module + uses any of the functions from . + +config CRYPTO_LIB_MD5_ARCH + bool + depends on CRYPTO_LIB_MD5 && !UML + config CRYPTO_LIB_POLY1305_RSIZE int default 2 if MIPS default 11 if X86_64 default 9 if ARM || ARM64 diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index e4151be2ebd44..25443e9ca7465 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -57,10 +57,20 @@ libcurve25519-y +=3D curve25519.o libcurve25519-$(CONFIG_CRYPTO_SELFTESTS) +=3D curve25519-selftest.o =20 obj-$(CONFIG_CRYPTO_LIB_DES) +=3D libdes.o libdes-y :=3D des.o =20 +##########################################################################= ###### + +obj-$(CONFIG_CRYPTO_LIB_MD5) +=3D libmd5.o +libmd5-y :=3D md5.o +ifeq ($(CONFIG_CRYPTO_LIB_MD5_ARCH),y) +CFLAGS_md5.o +=3D -I$(src)/$(SRCARCH) +endif # CONFIG_CRYPTO_LIB_MD5_ARCH + +##########################################################################= ###### + obj-$(CONFIG_CRYPTO_LIB_POLY1305) +=3D libpoly1305.o libpoly1305-y +=3D poly1305.o =20 obj-$(CONFIG_CRYPTO_LIB_POLY1305_GENERIC) +=3D libpoly1305-generic.o libpoly1305-generic-y :=3D poly1305-donna32.o diff --git a/lib/crypto/md5.c b/lib/crypto/md5.c new file mode 100644 index 0000000000000..c0610ea1370e6 --- /dev/null +++ b/lib/crypto/md5.c @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * MD5 and HMAC-MD5 library functions + * + * md5_block_generic() is derived from cryptoapi implementation, originally + * based on the public domain implementation written by Colin Plumb in 199= 3. + * + * Copyright (c) Cryptoapi developers. + * Copyright (c) 2002 James Morris + * Copyright 2025 Google LLC + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const struct md5_block_state md5_iv =3D { + .h =3D { MD5_H0, MD5_H1, MD5_H2, MD5_H3 }, +}; + +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, in, s) \ + (w +=3D f(x, y, z) + in, w =3D (w << s | w >> (32 - s)) + x) + +static void md5_block_generic(struct md5_block_state *state, + const u8 data[MD5_BLOCK_SIZE]) +{ + u32 in[MD5_BLOCK_WORDS]; + u32 a, b, c, d; + + memcpy(in, data, MD5_BLOCK_SIZE); + le32_to_cpu_array(in, ARRAY_SIZE(in)); + + a =3D state->h[0]; + b =3D state->h[1]; + c =3D state->h[2]; + d =3D state->h[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + state->h[0] +=3D a; + state->h[1] +=3D b; + state->h[2] +=3D c; + state->h[3] +=3D d; +} + +static void __maybe_unused md5_blocks_generic(struct md5_block_state *stat= e, + const u8 *data, size_t nblocks) +{ + do { + md5_block_generic(state, data); + data +=3D MD5_BLOCK_SIZE; + } while (--nblocks); +} + +#ifdef CONFIG_CRYPTO_LIB_MD5_ARCH +#include "md5.h" /* $(SRCARCH)/md5.h */ +#else +#define md5_blocks md5_blocks_generic +#endif + +void md5_init(struct md5_ctx *ctx) +{ + ctx->state =3D md5_iv; + ctx->bytecount =3D 0; +} +EXPORT_SYMBOL_GPL(md5_init); + +void md5_update(struct md5_ctx *ctx, const u8 *data, size_t len) +{ + size_t partial =3D ctx->bytecount % MD5_BLOCK_SIZE; + + ctx->bytecount +=3D len; + + if (partial + len >=3D MD5_BLOCK_SIZE) { + size_t nblocks; + + if (partial) { + size_t l =3D MD5_BLOCK_SIZE - partial; + + memcpy(&ctx->buf[partial], data, l); + data +=3D l; + len -=3D l; + + md5_blocks(&ctx->state, ctx->buf, 1); + } + + nblocks =3D len / MD5_BLOCK_SIZE; + len %=3D MD5_BLOCK_SIZE; + + if (nblocks) { + md5_blocks(&ctx->state, data, nblocks); + data +=3D nblocks * MD5_BLOCK_SIZE; + } + partial =3D 0; + } + if (len) + memcpy(&ctx->buf[partial], data, len); +} +EXPORT_SYMBOL_GPL(md5_update); + +static void __md5_final(struct md5_ctx *ctx, u8 out[MD5_DIGEST_SIZE]) +{ + u64 bitcount =3D ctx->bytecount << 3; + size_t partial =3D ctx->bytecount % MD5_BLOCK_SIZE; + + ctx->buf[partial++] =3D 0x80; + if (partial > MD5_BLOCK_SIZE - 8) { + memset(&ctx->buf[partial], 0, MD5_BLOCK_SIZE - partial); + md5_blocks(&ctx->state, ctx->buf, 1); + partial =3D 0; + } + memset(&ctx->buf[partial], 0, MD5_BLOCK_SIZE - 8 - partial); + *(__le64 *)&ctx->buf[MD5_BLOCK_SIZE - 8] =3D cpu_to_le64(bitcount); + md5_blocks(&ctx->state, ctx->buf, 1); + + cpu_to_le32_array(ctx->state.h, ARRAY_SIZE(ctx->state.h)); + memcpy(out, ctx->state.h, MD5_DIGEST_SIZE); +} + +void md5_final(struct md5_ctx *ctx, u8 out[MD5_DIGEST_SIZE]) +{ + __md5_final(ctx, out); + memzero_explicit(ctx, sizeof(*ctx)); +} +EXPORT_SYMBOL_GPL(md5_final); + +void md5(const u8 *data, size_t len, u8 out[MD5_DIGEST_SIZE]) +{ + struct md5_ctx ctx; + + md5_init(&ctx); + md5_update(&ctx, data, len); + md5_final(&ctx, out); +} +EXPORT_SYMBOL_GPL(md5); + +static void __hmac_md5_preparekey(struct md5_block_state *istate, + struct md5_block_state *ostate, + const u8 *raw_key, size_t raw_key_len) +{ + union { + u8 b[MD5_BLOCK_SIZE]; + unsigned long w[MD5_BLOCK_SIZE / sizeof(unsigned long)]; + } derived_key =3D { 0 }; + + if (unlikely(raw_key_len > MD5_BLOCK_SIZE)) + md5(raw_key, raw_key_len, derived_key.b); + else + memcpy(derived_key.b, raw_key, raw_key_len); + + for (size_t i =3D 0; i < ARRAY_SIZE(derived_key.w); i++) + derived_key.w[i] ^=3D REPEAT_BYTE(HMAC_IPAD_VALUE); + *istate =3D md5_iv; + md5_blocks(istate, derived_key.b, 1); + + for (size_t i =3D 0; i < ARRAY_SIZE(derived_key.w); i++) + derived_key.w[i] ^=3D REPEAT_BYTE(HMAC_OPAD_VALUE ^ + HMAC_IPAD_VALUE); + *ostate =3D md5_iv; + md5_blocks(ostate, derived_key.b, 1); + + memzero_explicit(&derived_key, sizeof(derived_key)); +} + +void hmac_md5_preparekey(struct hmac_md5_key *key, + const u8 *raw_key, size_t raw_key_len) +{ + __hmac_md5_preparekey(&key->istate, &key->ostate, raw_key, raw_key_len); +} +EXPORT_SYMBOL_GPL(hmac_md5_preparekey); + +void hmac_md5_init(struct hmac_md5_ctx *ctx, const struct hmac_md5_key *ke= y) +{ + ctx->hash_ctx.state =3D key->istate; + ctx->hash_ctx.bytecount =3D MD5_BLOCK_SIZE; + ctx->ostate =3D key->ostate; +} +EXPORT_SYMBOL_GPL(hmac_md5_init); + +void hmac_md5_init_usingrawkey(struct hmac_md5_ctx *ctx, + const u8 *raw_key, size_t raw_key_len) +{ + __hmac_md5_preparekey(&ctx->hash_ctx.state, &ctx->ostate, + raw_key, raw_key_len); + ctx->hash_ctx.bytecount =3D MD5_BLOCK_SIZE; +} +EXPORT_SYMBOL_GPL(hmac_md5_init_usingrawkey); + +void hmac_md5_final(struct hmac_md5_ctx *ctx, u8 out[MD5_DIGEST_SIZE]) +{ + /* Generate the padded input for the outer hash in ctx->hash_ctx.buf. */ + __md5_final(&ctx->hash_ctx, ctx->hash_ctx.buf); + memset(&ctx->hash_ctx.buf[MD5_DIGEST_SIZE], 0, + MD5_BLOCK_SIZE - MD5_DIGEST_SIZE); + ctx->hash_ctx.buf[MD5_DIGEST_SIZE] =3D 0x80; + *(__le64 *)&ctx->hash_ctx.buf[MD5_BLOCK_SIZE - 8] =3D + cpu_to_le64(8 * (MD5_BLOCK_SIZE + MD5_DIGEST_SIZE)); + + /* Compute the outer hash, which gives the HMAC value. */ + md5_blocks(&ctx->ostate, ctx->hash_ctx.buf, 1); + cpu_to_le32_array(ctx->ostate.h, ARRAY_SIZE(ctx->ostate.h)); + memcpy(out, ctx->ostate.h, MD5_DIGEST_SIZE); + + memzero_explicit(ctx, sizeof(*ctx)); +} +EXPORT_SYMBOL_GPL(hmac_md5_final); + +void hmac_md5(const struct hmac_md5_key *key, + const u8 *data, size_t data_len, u8 out[MD5_DIGEST_SIZE]) +{ + struct hmac_md5_ctx ctx; + + hmac_md5_init(&ctx, key); + hmac_md5_update(&ctx, data, data_len); + hmac_md5_final(&ctx, out); +} +EXPORT_SYMBOL_GPL(hmac_md5); + +void hmac_md5_usingrawkey(const u8 *raw_key, size_t raw_key_len, + const u8 *data, size_t data_len, + u8 out[MD5_DIGEST_SIZE]) +{ + struct hmac_md5_ctx ctx; + + hmac_md5_init_usingrawkey(&ctx, raw_key, raw_key_len); + hmac_md5_update(&ctx, data, data_len); + hmac_md5_final(&ctx, out); +} +EXPORT_SYMBOL_GPL(hmac_md5_usingrawkey); + +#ifdef md5_mod_init_arch +static int __init md5_mod_init(void) +{ + md5_mod_init_arch(); + return 0; +} +subsys_initcall(md5_mod_init); + +static void __exit md5_mod_exit(void) +{ +} +module_exit(md5_mod_exit); +#endif + +MODULE_DESCRIPTION("MD5 and HMAC-MD5 library functions"); +MODULE_LICENSE("GPL"); --=20 2.50.1 From nobody Sun Oct 5 10:44:55 2025 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 5FE9C275B02; Tue, 5 Aug 2025 22:30: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=1754433008; cv=none; b=ptqWFOPKap2lAiUPH8BJA/1o0HjdvesFwCgrJN9lAsMvQyIL3P+byN92wEn9/Pbfg0lZwUHASgDCpFFn25vT38PSqdtllz2T7pCKr47ypqGCELyJL0zBr/KO95w3Fffa8evP5Pw4J97ncXr35xEZ3jnTuLI03x5EExx7MjNgL44= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754433008; c=relaxed/simple; bh=3SMCk1Bp8W8VsXMpjpu/X2NPIu92XHe+tlWFsAdpQtI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i1xlzZJ9GpUpaMYOsE2R8c4cCS2jpAwWAgfaFglzedtxCpz3N3AwlktBVa42/pSUydO22U7O9nwdzNJ0QgBycgAwIYkk1SXtajgp1K8rUiwHUACwpZXldiYRMCpkymMv9VDmnGQz5PWN746VwgqDYlSdtkri/Lelrfm0Q58HXgk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=GIw3YkHO; 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="GIw3YkHO" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 60EE6C4CEF9; Tue, 5 Aug 2025 22:30:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754433007; bh=3SMCk1Bp8W8VsXMpjpu/X2NPIu92XHe+tlWFsAdpQtI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GIw3YkHONYpD1eXEpedG7ATsTUxQYVXVR02vcIsAeAOLImaIlMQ9oBFrQpmsFJFNH Bqc8VGenm/IJJsFZ0YjiMKdjdRnGKHr0izqc4N+xJ/5WCgJvzb9oZ6tGVYJreBoT18 3mJh7KsqMJLerKOnSXBvM21CU4pTxy8UfmrYfV5c2kbEQ6u0jUcE1LVqunopuXHIBX N7fnQUx2jPOi35GqjmQA0h4871BJYVvAW9I4gLYmc2nBjdZOj0Zyx5chqKgrUuR248 vSBsCpuQBrfqY8DpG17iBace67se7Dw7kW3SQCBJ9m7zYy4ZKuHBOva98cuyIMW844 YkCPcDuKFn56Q== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, sparclinux@vger.kernel.org, Eric Biggers Subject: [PATCH v2 2/7] lib/crypto: mips/md5: Migrate optimized code into library Date: Tue, 5 Aug 2025 15:28:50 -0700 Message-ID: <20250805222855.10362-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250805222855.10362-1-ebiggers@kernel.org> References: <20250805222855.10362-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 mips-optimized MD5 code via mips-specific crypto_shash algorithms, instead just implement the md5_blocks() library function. This is much simpler, it makes the MD5 library functions be mips-optimized, and it fixes the longstanding issue where the mips-optimized MD5 code was disabled by default. MD5 still remains available through crypto_shash, but individual architectures no longer need to handle it. Note: to see the diff from arch/mips/cavium-octeon/crypto/octeon-md5.c to lib/crypto/mips/md5.h, view this commit with 'git show -M10'. Signed-off-by: Eric Biggers --- arch/mips/cavium-octeon/crypto/Makefile | 2 - arch/mips/cavium-octeon/crypto/octeon-md5.c | 214 -------------------- arch/mips/configs/cavium_octeon_defconfig | 1 - arch/mips/crypto/Kconfig | 10 - lib/crypto/Kconfig | 1 + lib/crypto/mips/md5.h | 65 ++++++ 6 files changed, 66 insertions(+), 227 deletions(-) delete mode 100644 arch/mips/cavium-octeon/crypto/octeon-md5.c create mode 100644 lib/crypto/mips/md5.h diff --git a/arch/mips/cavium-octeon/crypto/Makefile b/arch/mips/cavium-oct= eon/crypto/Makefile index 83f2f5dd93ccc..b7d03e8a03187 100644 --- a/arch/mips/cavium-octeon/crypto/Makefile +++ b/arch/mips/cavium-octeon/crypto/Makefile @@ -2,7 +2,5 @@ # # OCTEON-specific crypto modules. # =20 obj-y +=3D octeon-crypto.o - -obj-$(CONFIG_CRYPTO_MD5_OCTEON) +=3D octeon-md5.o diff --git a/arch/mips/cavium-octeon/crypto/octeon-md5.c b/arch/mips/cavium= -octeon/crypto/octeon-md5.c deleted file mode 100644 index a8ce831e2cebd..0000000000000 --- a/arch/mips/cavium-octeon/crypto/octeon-md5.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Cryptographic API. - * - * MD5 Message Digest Algorithm (RFC1321). - * - * Adapted for OCTEON by Aaro Koskinen . - * - * Based on crypto/md5.c, which is: - * - * Derived from cryptoapi implementation, originally based on the - * public domain implementation written by Colin Plumb in 1993. - * - * Copyright (c) Cryptoapi developers. - * Copyright (c) 2002 James Morris - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the F= ree - * Software Foundation; either version 2 of the License, or (at your optio= n) - * any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -struct octeon_md5_state { - __le32 hash[MD5_HASH_WORDS]; - u64 byte_count; -}; - -/* - * We pass everything as 64-bit. OCTEON can handle misaligned data. - */ - -static void octeon_md5_store_hash(struct octeon_md5_state *ctx) -{ - u64 *hash =3D (u64 *)ctx->hash; - - write_octeon_64bit_hash_dword(hash[0], 0); - write_octeon_64bit_hash_dword(hash[1], 1); -} - -static void octeon_md5_read_hash(struct octeon_md5_state *ctx) -{ - u64 *hash =3D (u64 *)ctx->hash; - - hash[0] =3D read_octeon_64bit_hash_dword(0); - hash[1] =3D read_octeon_64bit_hash_dword(1); -} - -static void octeon_md5_transform(const void *_block) -{ - const u64 *block =3D _block; - - write_octeon_64bit_block_dword(block[0], 0); - write_octeon_64bit_block_dword(block[1], 1); - write_octeon_64bit_block_dword(block[2], 2); - write_octeon_64bit_block_dword(block[3], 3); - write_octeon_64bit_block_dword(block[4], 4); - write_octeon_64bit_block_dword(block[5], 5); - write_octeon_64bit_block_dword(block[6], 6); - octeon_md5_start(block[7]); -} - -static int octeon_md5_init(struct shash_desc *desc) -{ - struct octeon_md5_state *mctx =3D shash_desc_ctx(desc); - - mctx->hash[0] =3D cpu_to_le32(MD5_H0); - mctx->hash[1] =3D cpu_to_le32(MD5_H1); - mctx->hash[2] =3D cpu_to_le32(MD5_H2); - mctx->hash[3] =3D cpu_to_le32(MD5_H3); - mctx->byte_count =3D 0; - - return 0; -} - -static int octeon_md5_update(struct shash_desc *desc, const u8 *data, - unsigned int len) -{ - struct octeon_md5_state *mctx =3D shash_desc_ctx(desc); - struct octeon_cop2_state state; - unsigned long flags; - - mctx->byte_count +=3D len; - flags =3D octeon_crypto_enable(&state); - octeon_md5_store_hash(mctx); - - do { - octeon_md5_transform(data); - data +=3D MD5_HMAC_BLOCK_SIZE; - len -=3D MD5_HMAC_BLOCK_SIZE; - } while (len >=3D MD5_HMAC_BLOCK_SIZE); - - octeon_md5_read_hash(mctx); - octeon_crypto_disable(&state, flags); - mctx->byte_count -=3D len; - return len; -} - -static int octeon_md5_finup(struct shash_desc *desc, const u8 *src, - unsigned int offset, u8 *out) -{ - struct octeon_md5_state *mctx =3D shash_desc_ctx(desc); - int padding =3D 56 - (offset + 1); - struct octeon_cop2_state state; - u32 block[MD5_BLOCK_WORDS]; - unsigned long flags; - char *p; - - p =3D memcpy(block, src, offset); - p +=3D offset; - *p++ =3D 0x80; - - flags =3D octeon_crypto_enable(&state); - octeon_md5_store_hash(mctx); - - if (padding < 0) { - memset(p, 0x00, padding + sizeof(u64)); - octeon_md5_transform(block); - p =3D (char *)block; - padding =3D 56; - } - - memset(p, 0, padding); - mctx->byte_count +=3D offset; - block[14] =3D mctx->byte_count << 3; - block[15] =3D mctx->byte_count >> 29; - cpu_to_le32_array(block + 14, 2); - octeon_md5_transform(block); - - octeon_md5_read_hash(mctx); - octeon_crypto_disable(&state, flags); - - memzero_explicit(block, sizeof(block)); - memcpy(out, mctx->hash, sizeof(mctx->hash)); - - return 0; -} - -static int octeon_md5_export(struct shash_desc *desc, void *out) -{ - struct octeon_md5_state *ctx =3D shash_desc_ctx(desc); - union { - u8 *u8; - u32 *u32; - u64 *u64; - } p =3D { .u8 =3D out }; - int i; - - for (i =3D 0; i < MD5_HASH_WORDS; i++) - put_unaligned(le32_to_cpu(ctx->hash[i]), p.u32++); - put_unaligned(ctx->byte_count, p.u64); - return 0; -} - -static int octeon_md5_import(struct shash_desc *desc, const void *in) -{ - struct octeon_md5_state *ctx =3D shash_desc_ctx(desc); - union { - const u8 *u8; - const u32 *u32; - const u64 *u64; - } p =3D { .u8 =3D in }; - int i; - - for (i =3D 0; i < MD5_HASH_WORDS; i++) - ctx->hash[i] =3D cpu_to_le32(get_unaligned(p.u32++)); - ctx->byte_count =3D get_unaligned(p.u64); - return 0; -} - -static struct shash_alg alg =3D { - .digestsize =3D MD5_DIGEST_SIZE, - .init =3D octeon_md5_init, - .update =3D octeon_md5_update, - .finup =3D octeon_md5_finup, - .export =3D octeon_md5_export, - .import =3D octeon_md5_import, - .statesize =3D MD5_STATE_SIZE, - .descsize =3D sizeof(struct octeon_md5_state), - .base =3D { - .cra_name =3D "md5", - .cra_driver_name=3D "octeon-md5", - .cra_priority =3D OCTEON_CR_OPCODE_PRIORITY, - .cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .cra_blocksize =3D MD5_HMAC_BLOCK_SIZE, - .cra_module =3D THIS_MODULE, - } -}; - -static int __init md5_mod_init(void) -{ - if (!octeon_has_crypto()) - return -ENOTSUPP; - return crypto_register_shash(&alg); -} - -static void __exit md5_mod_fini(void) -{ - crypto_unregister_shash(&alg); -} - -module_init(md5_mod_init); -module_exit(md5_mod_fini); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("MD5 Message Digest Algorithm (OCTEON)"); -MODULE_AUTHOR("Aaro Koskinen "); diff --git a/arch/mips/configs/cavium_octeon_defconfig b/arch/mips/configs/= cavium_octeon_defconfig index 3f50e1d78894a..68c363366bceb 100644 --- a/arch/mips/configs/cavium_octeon_defconfig +++ b/arch/mips/configs/cavium_octeon_defconfig @@ -153,11 +153,10 @@ CONFIG_NLS_ISO8859_1=3Dy CONFIG_NLS_UTF8=3Dy CONFIG_SECURITY=3Dy CONFIG_SECURITY_NETWORK=3Dy CONFIG_CRYPTO_CBC=3Dy CONFIG_CRYPTO_HMAC=3Dy -CONFIG_CRYPTO_MD5_OCTEON=3Dy CONFIG_CRYPTO_DES=3Dy CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=3Dy CONFIG_DEBUG_FS=3Dy CONFIG_MAGIC_SYSRQ=3Dy # CONFIG_SCHED_DEBUG is not set diff --git a/arch/mips/crypto/Kconfig b/arch/mips/crypto/Kconfig index 7b91f4ec65bff..6a5bd5074867e 100644 --- a/arch/mips/crypto/Kconfig +++ b/arch/mips/crypto/Kconfig @@ -1,15 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 =20 menu "Accelerated Cryptographic Algorithms for CPU (mips)" =20 -config CRYPTO_MD5_OCTEON - tristate "Digests: MD5 (OCTEON)" - depends on CPU_CAVIUM_OCTEON - select CRYPTO_MD5 - select CRYPTO_HASH - help - MD5 message digest algorithm (RFC1321) - - Architecture: mips OCTEON using crypto instructions, when available - endmenu diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index 8ccb5b794b76a..fe2910c25f0ba 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -108,10 +108,11 @@ config CRYPTO_LIB_MD5 uses any of the functions from . =20 config CRYPTO_LIB_MD5_ARCH bool depends on CRYPTO_LIB_MD5 && !UML + default y if MIPS && CPU_CAVIUM_OCTEON =20 config CRYPTO_LIB_POLY1305_RSIZE int default 2 if MIPS default 11 if X86_64 diff --git a/lib/crypto/mips/md5.h b/lib/crypto/mips/md5.h new file mode 100644 index 0000000000000..e08e28aeffa46 --- /dev/null +++ b/lib/crypto/mips/md5.h @@ -0,0 +1,65 @@ +/* + * Cryptographic API. + * + * MD5 Message Digest Algorithm (RFC1321). + * + * Adapted for OCTEON by Aaro Koskinen . + * + * Based on crypto/md5.c, which is: + * + * Derived from cryptoapi implementation, originally based on the + * public domain implementation written by Colin Plumb in 1993. + * + * Copyright (c) Cryptoapi developers. + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the F= ree + * Software Foundation; either version 2 of the License, or (at your optio= n) + * any later version. + */ + +#include +#include + +/* + * We pass everything as 64-bit. OCTEON can handle misaligned data. + */ + +static void md5_blocks(struct md5_block_state *state, + const u8 *data, size_t nblocks) +{ + struct octeon_cop2_state cop2_state; + u64 *state64 =3D (u64 *)state; + unsigned long flags; + + if (!octeon_has_crypto()) + return md5_blocks_generic(state, data, nblocks); + + cpu_to_le32_array(state->h, ARRAY_SIZE(state->h)); + + flags =3D octeon_crypto_enable(&cop2_state); + write_octeon_64bit_hash_dword(state64[0], 0); + write_octeon_64bit_hash_dword(state64[1], 1); + + do { + const u64 *block =3D (const u64 *)data; + + write_octeon_64bit_block_dword(block[0], 0); + write_octeon_64bit_block_dword(block[1], 1); + write_octeon_64bit_block_dword(block[2], 2); + write_octeon_64bit_block_dword(block[3], 3); + write_octeon_64bit_block_dword(block[4], 4); + write_octeon_64bit_block_dword(block[5], 5); + write_octeon_64bit_block_dword(block[6], 6); + octeon_md5_start(block[7]); + + data +=3D MD5_BLOCK_SIZE; + } while (--nblocks); + + state64[0] =3D read_octeon_64bit_hash_dword(0); + state64[1] =3D read_octeon_64bit_hash_dword(1); + octeon_crypto_disable(&cop2_state, flags); + + le32_to_cpu_array(state->h, ARRAY_SIZE(state->h)); +} --=20 2.50.1 From nobody Sun Oct 5 10:44:55 2025 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 BE358283FEE; Tue, 5 Aug 2025 22:30: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=1754433008; cv=none; b=ro/+B/YIc62JaLQRcH5aD7PDfz25+bfNVJ2yUXTcbkVa7ZQ2B4yvgceXYQxHLfHyDxd9HCj2GqS9WPtZWsgsBs7V94utLSNuYlZJRDSk6t9hXbYhiQKVt+2K9zV192OUSTd/AUzk7isQpXnxXEJR6mO7q78Cfah5redFgaqR4LA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754433008; c=relaxed/simple; bh=VRc4KV6AcWRLoeXQnbyPvjrtyrIbJyC0ogU8BITtRHo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FvzW3l4zCp9Fg1VIsDT7TW4WPgAHUqNJdYWQbz0iY9c/lPv3G4OJ1B8UMJrhkKWsKBBskX4lmhslCWc1AHt9TCbqXa799VdhsPsueZ91Pvy8rhcWpKlTwf18Nl1DvowfQtNiKfQN2WbLQZMcOg5cLMy7w7zNmgt7HxXAvbRpvnU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=r/HPibEG; 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="r/HPibEG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1517BC4CEFA; Tue, 5 Aug 2025 22:30:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754433008; bh=VRc4KV6AcWRLoeXQnbyPvjrtyrIbJyC0ogU8BITtRHo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r/HPibEGVSJ55Kdivcxfl4OtFhQRmH//SQRo23gj/tJjHsIsd0mSraovQNVi/WBKA cY3UZo2uOlhxH8Wyu4EMvmZeA3Wrs/Y05176OMN0ofcWIXSsDAq6vwnjaXPLJLIvt+ ewDrV1sjW00zJcNzAT81G6fHrNvoPsTF4EGf2NyJ6HkOUIcv0vvOEVe9wR6yM/Zl0k ZurMIu/XzEApEyKYVjQLRl6Ttg59UYm43evi3Qy5YX+fpbkFu2XmJYf6IqLWcm6+bY Mp7Od81jWSCz7WBPI/STFw11P18reMYBoAJn8ntZCGM1TW633Y2im6rxoGUcKpDISA tCE7HqgIx6VYw== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, sparclinux@vger.kernel.org, Eric Biggers Subject: [PATCH v2 3/7] mips: cavium-octeon: Move octeon-crypto.c into parent dir Date: Tue, 5 Aug 2025 15:28:51 -0700 Message-ID: <20250805222855.10362-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250805222855.10362-1-ebiggers@kernel.org> References: <20250805222855.10362-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 octeon-crypto.c is the only remaining source file in arch/mips/cavium-octeon/crypto/, move it into its parent directory arch/mips/cavium-octeon/. Then remove the directory arch/mips/cavium-octeon/crypto/, including its Makefile. Signed-off-by: Eric Biggers --- arch/mips/cavium-octeon/Makefile | 2 +- arch/mips/cavium-octeon/crypto/Makefile | 6 ------ arch/mips/cavium-octeon/{crypto =3D> }/octeon-crypto.c | 0 3 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 arch/mips/cavium-octeon/crypto/Makefile rename arch/mips/cavium-octeon/{crypto =3D> }/octeon-crypto.c (100%) diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Mak= efile index 2a59265788413..ab84ede0cbe0e 100644 --- a/arch/mips/cavium-octeon/Makefile +++ b/arch/mips/cavium-octeon/Makefile @@ -9,12 +9,12 @@ # Copyright (C) 2005-2009 Cavium Networks # =20 obj-y :=3D cpu.o setup.o octeon-platform.o octeon-irq.o csrc-octeon.o obj-y +=3D dma-octeon.o +obj-y +=3D octeon-crypto.o obj-y +=3D octeon-memcpy.o obj-y +=3D executive/ -obj-y +=3D crypto/ =20 obj-$(CONFIG_MTD) +=3D flash_setup.o obj-$(CONFIG_SMP) +=3D smp.o obj-$(CONFIG_OCTEON_ILM) +=3D oct_ilm.o diff --git a/arch/mips/cavium-octeon/crypto/Makefile b/arch/mips/cavium-oct= eon/crypto/Makefile deleted file mode 100644 index b7d03e8a03187..0000000000000 --- a/arch/mips/cavium-octeon/crypto/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# OCTEON-specific crypto modules. -# - -obj-y +=3D octeon-crypto.o diff --git a/arch/mips/cavium-octeon/crypto/octeon-crypto.c b/arch/mips/cav= ium-octeon/octeon-crypto.c similarity index 100% rename from arch/mips/cavium-octeon/crypto/octeon-crypto.c rename to arch/mips/cavium-octeon/octeon-crypto.c --=20 2.50.1 From nobody Sun Oct 5 10:44:55 2025 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 A1876298CC3; Tue, 5 Aug 2025 22:30: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=1754433009; cv=none; b=I/dIqR9QnsOCBEnIc0lJxiX3kp5PyUttGXecZk/GMiI40th1kd98P9z6Y0/tvm/oOE49wqa3LARd0oRrta3XgJf5ook7v52XhN7eiI92MwFES3SWtrzxSipMOuvqrY4KnLBJYN/HNzSs/oz8RJbrquanebT2m4PrsBSed+9yvog= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754433009; c=relaxed/simple; bh=1MyX5/ScI+ABzLHp94uEiUWeHGKbS9SP8d6OkXKSCMU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jXaW1FMc5pA78rfCWwM5/jS7yq8Me8wUSTQVYGVGxPbHCdGykmITNvQ7NdHg1/waL+U9/Q4XjVF0AJXcugbOhuwyUvAOHsFA97nNP8ivo550HIzHWk5+jLllocKUtSOlMQtPypYjUfrt4VkQ02Q1KtMlTY2Ca7iiIgy+NSPHnXQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NM/B5cER; 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="NM/B5cER" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BB128C4CEF4; Tue, 5 Aug 2025 22:30:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754433009; bh=1MyX5/ScI+ABzLHp94uEiUWeHGKbS9SP8d6OkXKSCMU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NM/B5cER0kHM26PVRd5nsKUaz/6xEg3J0MAxmPDAYziStnyDLO6OqBjoCKDU05m1C jys9dP5LtFjHGTnaxTfOU/Ua8qJBFpyHVj80/br8jIsQQyqRbP53L8f/LBm65Y+97f PsKAFQmMiGvsWRMcrrV+zzjCHUO2BflRxLrZNM5s8c3CbyrfbdoPolcP0a7JXUMn0V etHV5/GqhZD4SQ4NYxgwn50Nsw3uQ248HAFWwtAbI5oSx+2iPxJXADWwf17S7a3Vmj 3D62qWA1pG5Cm9uPj6XbTojhxBrv7T9i27VVjS9Qc0cqvWJfYmOt2/xfo1g5JJwv2V l/Wuov4vsgH8Q== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, sparclinux@vger.kernel.org, Eric Biggers Subject: [PATCH v2 4/7] lib/crypto: powerpc/md5: Migrate optimized code into library Date: Tue, 5 Aug 2025 15:28:52 -0700 Message-ID: <20250805222855.10362-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250805222855.10362-1-ebiggers@kernel.org> References: <20250805222855.10362-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 powerpc-optimized MD5 code via powerpc-specific crypto_shash algorithms, instead just implement the md5_blocks() library function. This is much simpler, it makes the MD5 library functions be powerpc-optimized, and it fixes the longstanding issue where the powerpc-optimized MD5 code was disabled by default. MD5 still remains available through crypto_shash, but individual architectures no longer need to handle it. Signed-off-by: Eric Biggers --- arch/powerpc/configs/powernv_defconfig | 1 - arch/powerpc/configs/ppc64_defconfig | 1 - arch/powerpc/crypto/Kconfig | 8 -- arch/powerpc/crypto/Makefile | 2 - arch/powerpc/crypto/md5-glue.c | 99 ------------------- lib/crypto/Kconfig | 1 + lib/crypto/Makefile | 1 + .../crypto =3D> lib/crypto/powerpc}/md5-asm.S | 0 lib/crypto/powerpc/md5.h | 12 +++ 9 files changed, 14 insertions(+), 111 deletions(-) delete mode 100644 arch/powerpc/crypto/md5-glue.c rename {arch/powerpc/crypto =3D> lib/crypto/powerpc}/md5-asm.S (100%) create mode 100644 lib/crypto/powerpc/md5.h diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/= powernv_defconfig index d06388b0f66e3..bd4685612de6d 100644 --- a/arch/powerpc/configs/powernv_defconfig +++ b/arch/powerpc/configs/powernv_defconfig @@ -318,11 +318,10 @@ CONFIG_FTR_FIXUP_SELFTEST=3Dy CONFIG_MSI_BITMAP_SELFTEST=3Dy CONFIG_XMON=3Dy CONFIG_CRYPTO_BENCHMARK=3Dm CONFIG_CRYPTO_PCBC=3Dm CONFIG_CRYPTO_HMAC=3Dy -CONFIG_CRYPTO_MD5_PPC=3Dm CONFIG_CRYPTO_MICHAEL_MIC=3Dm CONFIG_CRYPTO_SHA256=3Dy CONFIG_CRYPTO_WP512=3Dm CONFIG_CRYPTO_ANUBIS=3Dm CONFIG_CRYPTO_BLOWFISH=3Dm diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/pp= c64_defconfig index ce34597e9f3e1..2d92c11eea7e4 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -385,11 +385,10 @@ CONFIG_CRYPTO_TWOFISH=3Dm CONFIG_CRYPTO_PCBC=3Dm CONFIG_CRYPTO_MICHAEL_MIC=3Dm CONFIG_CRYPTO_SHA256=3Dy CONFIG_CRYPTO_WP512=3Dm CONFIG_CRYPTO_LZO=3Dm -CONFIG_CRYPTO_MD5_PPC=3Dm CONFIG_CRYPTO_AES_GCM_P10=3Dm CONFIG_CRYPTO_DEV_NX=3Dy CONFIG_CRYPTO_DEV_NX_ENCRYPT=3Dm CONFIG_CRYPTO_DEV_VMX=3Dy CONFIG_SYSTEM_TRUSTED_KEYRING=3Dy diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig index cfe39fc221cf8..f4b779c7352de 100644 --- a/arch/powerpc/crypto/Kconfig +++ b/arch/powerpc/crypto/Kconfig @@ -13,18 +13,10 @@ config CRYPTO_CURVE25519_PPC64 Curve25519 algorithm =20 Architecture: PowerPC64 - Little-endian =20 -config CRYPTO_MD5_PPC - tristate "Digests: MD5" - select CRYPTO_HASH - help - MD5 message digest algorithm (RFC1321) - - Architecture: powerpc - config CRYPTO_AES_PPC_SPE tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS (SPE)" depends on SPE select CRYPTO_SKCIPHER help diff --git a/arch/powerpc/crypto/Makefile b/arch/powerpc/crypto/Makefile index bc8fd27344b8b..9eb59dce67f36 100644 --- a/arch/powerpc/crypto/Makefile +++ b/arch/powerpc/crypto/Makefile @@ -4,17 +4,15 @@ # # Arch-specific CryptoAPI modules. # =20 obj-$(CONFIG_CRYPTO_AES_PPC_SPE) +=3D aes-ppc-spe.o -obj-$(CONFIG_CRYPTO_MD5_PPC) +=3D md5-ppc.o obj-$(CONFIG_CRYPTO_AES_GCM_P10) +=3D aes-gcm-p10-crypto.o obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) +=3D vmx-crypto.o obj-$(CONFIG_CRYPTO_CURVE25519_PPC64) +=3D curve25519-ppc64le.o =20 aes-ppc-spe-y :=3D aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-mode= s.o aes-spe-glue.o -md5-ppc-y :=3D md5-asm.o md5-glue.o aes-gcm-p10-crypto-y :=3D aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o = aesp10-ppc.o vmx-crypto-objs :=3D vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_c= tr.o aes_xts.o ghash.o curve25519-ppc64le-y :=3D curve25519-ppc64le-core.o curve25519-ppc64le_asm= .o =20 ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) diff --git a/arch/powerpc/crypto/md5-glue.c b/arch/powerpc/crypto/md5-glue.c deleted file mode 100644 index 204440a90cd84..0000000000000 --- a/arch/powerpc/crypto/md5-glue.c +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Glue code for MD5 implementation for PPC assembler - * - * Based on generic implementation. - * - * Copyright (c) 2015 Markus Stockhausen - */ - -#include -#include -#include -#include -#include - -extern void ppc_md5_transform(u32 *state, const u8 *src, u32 blocks); - -static int ppc_md5_init(struct shash_desc *desc) -{ - struct md5_state *sctx =3D shash_desc_ctx(desc); - - sctx->hash[0] =3D MD5_H0; - sctx->hash[1] =3D MD5_H1; - sctx->hash[2] =3D MD5_H2; - sctx->hash[3] =3D MD5_H3; - sctx->byte_count =3D 0; - - return 0; -} - -static int ppc_md5_update(struct shash_desc *desc, const u8 *data, - unsigned int len) -{ - struct md5_state *sctx =3D shash_desc_ctx(desc); - - sctx->byte_count +=3D round_down(len, MD5_HMAC_BLOCK_SIZE); - ppc_md5_transform(sctx->hash, data, len >> 6); - return len - round_down(len, MD5_HMAC_BLOCK_SIZE); -} - -static int ppc_md5_finup(struct shash_desc *desc, const u8 *src, - unsigned int offset, u8 *out) -{ - struct md5_state *sctx =3D shash_desc_ctx(desc); - __le64 block[MD5_BLOCK_WORDS] =3D {}; - u8 *p =3D memcpy(block, src, offset); - __le32 *dst =3D (__le32 *)out; - __le64 *pbits; - - src =3D p; - p +=3D offset; - *p++ =3D 0x80; - sctx->byte_count +=3D offset; - pbits =3D &block[(MD5_BLOCK_WORDS / (offset > 55 ? 1 : 2)) - 1]; - *pbits =3D cpu_to_le64(sctx->byte_count << 3); - ppc_md5_transform(sctx->hash, src, (pbits - block + 1) / 8); - memzero_explicit(block, sizeof(block)); - - dst[0] =3D cpu_to_le32(sctx->hash[0]); - dst[1] =3D cpu_to_le32(sctx->hash[1]); - dst[2] =3D cpu_to_le32(sctx->hash[2]); - dst[3] =3D cpu_to_le32(sctx->hash[3]); - return 0; -} - -static struct shash_alg alg =3D { - .digestsize =3D MD5_DIGEST_SIZE, - .init =3D ppc_md5_init, - .update =3D ppc_md5_update, - .finup =3D ppc_md5_finup, - .descsize =3D MD5_STATE_SIZE, - .base =3D { - .cra_name =3D "md5", - .cra_driver_name=3D "md5-ppc", - .cra_priority =3D 200, - .cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .cra_blocksize =3D MD5_HMAC_BLOCK_SIZE, - .cra_module =3D THIS_MODULE, - } -}; - -static int __init ppc_md5_mod_init(void) -{ - return crypto_register_shash(&alg); -} - -static void __exit ppc_md5_mod_fini(void) -{ - crypto_unregister_shash(&alg); -} - -module_init(ppc_md5_mod_init); -module_exit(ppc_md5_mod_fini); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, PPC assembler"); - -MODULE_ALIAS_CRYPTO("md5"); -MODULE_ALIAS_CRYPTO("md5-ppc"); diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index fe2910c25f0ba..cfbbfaae9fe29 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -109,10 +109,11 @@ config CRYPTO_LIB_MD5 =20 config CRYPTO_LIB_MD5_ARCH bool depends on CRYPTO_LIB_MD5 && !UML default y if MIPS && CPU_CAVIUM_OCTEON + default y if PPC =20 config CRYPTO_LIB_POLY1305_RSIZE int default 2 if MIPS default 11 if X86_64 diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index 25443e9ca7465..8360054481b84 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -63,10 +63,11 @@ libdes-y :=3D des.o =20 obj-$(CONFIG_CRYPTO_LIB_MD5) +=3D libmd5.o libmd5-y :=3D md5.o ifeq ($(CONFIG_CRYPTO_LIB_MD5_ARCH),y) CFLAGS_md5.o +=3D -I$(src)/$(SRCARCH) +libmd5-$(CONFIG_PPC) +=3D powerpc/md5-asm.o endif # CONFIG_CRYPTO_LIB_MD5_ARCH =20 ##########################################################################= ###### =20 obj-$(CONFIG_CRYPTO_LIB_POLY1305) +=3D libpoly1305.o diff --git a/arch/powerpc/crypto/md5-asm.S b/lib/crypto/powerpc/md5-asm.S similarity index 100% rename from arch/powerpc/crypto/md5-asm.S rename to lib/crypto/powerpc/md5-asm.S diff --git a/lib/crypto/powerpc/md5.h b/lib/crypto/powerpc/md5.h new file mode 100644 index 0000000000000..540b08e34d1d5 --- /dev/null +++ b/lib/crypto/powerpc/md5.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * MD5 optimized for PowerPC + */ + +void ppc_md5_transform(u32 *state, const u8 *data, size_t nblocks); + +static void md5_blocks(struct md5_block_state *state, + const u8 *data, size_t nblocks) +{ + ppc_md5_transform(state->h, data, nblocks); +} --=20 2.50.1 From nobody Sun Oct 5 10:44:55 2025 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 41E57262FE5; Tue, 5 Aug 2025 22:30: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=1754433010; cv=none; b=Ht+W5t2vSXcKwhT2KBRBq8DPU3D7ezqend3meixCcNiPqiTwosP0HWy4VbSn2UmOfEjs34IHKMDteZGBUoXxeMtAqwvd3z1wVdMfmLNveGQ9N3SaFoANjlqZhc9MxZW+jIligyPnwrGX3RdLH3P96VLsYegLcGsyF7VzExZ8jgA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754433010; c=relaxed/simple; bh=J7l9bJPT2xll8QmdyoGz4D6kdDet0QE/TANAjwOgrDo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=lQz7gKlexyuoSFQDuXplNuM0DL9ymMiWQcchxRMWP+4YyPvX9bntweZcul9k7n2YJGaiRfeFkfGCHTAoHGlitMpq4R0O/hN6Jh3JJN+DRhirNJ0KH8Y+gu4JIBKyoxuF0OMCU4n6fculr8b+D0aAAh0FBlf1Xi5ZqKTvMCI0fIo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ZFNS1a85; 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="ZFNS1a85" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 63E88C4CEFA; Tue, 5 Aug 2025 22:30:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754433009; bh=J7l9bJPT2xll8QmdyoGz4D6kdDet0QE/TANAjwOgrDo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZFNS1a85za7GpfUoLXTwGjDCv5IXRSRQuIA3+z49wtvO+VrZscELL+1ERjMskUWuJ TwzHx2s9wT2VI85C51XshvQuu/LnzJbVueUOmZhGO9y8+0rfBWwqs85E48FEe/ZSTB 8cjVIjmOSLpz8OGRmAnHX305vGaZhKF5Kj4NR7829UiMTZJBZq+4uacJPahOoYFvPe dkswDlwx4YaSz6jBB/Id555kdFVDHaH7kAnccbHP1FJcRXRdm3cJ2P+J18+s6JxJkD ERWtuH8r1pA3GUN84ampNtw35O957Ji7eBceu71gCV4Co9KdrWCBgzcZQFiEHSzhnr uhjcjb0HyNz/Q== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, sparclinux@vger.kernel.org, Eric Biggers Subject: [PATCH v2 5/7] lib/crypto: sparc/md5: Migrate optimized code into library Date: Tue, 5 Aug 2025 15:28:53 -0700 Message-ID: <20250805222855.10362-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250805222855.10362-1-ebiggers@kernel.org> References: <20250805222855.10362-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 sparc-optimized MD5 code via sparc-specific crypto_shash algorithms, instead just implement the md5_blocks() library function. This is much simpler, it makes the MD5 library functions be sparc-optimized, and it fixes the longstanding issue where the sparc-optimized MD5 code was disabled by default. MD5 still remains available through crypto_shash, but individual architectures no longer need to handle it. Note: to see the diff from arch/sparc/crypto/md5_glue.c to lib/crypto/sparc/md5.h, view this commit with 'git show -M10'. Signed-off-by: Eric Biggers --- arch/sparc/crypto/Kconfig | 10 - arch/sparc/crypto/Makefile | 4 - arch/sparc/crypto/md5_glue.c | 174 ------------------ lib/crypto/Kconfig | 1 + lib/crypto/Makefile | 1 + lib/crypto/sparc/md5.h | 48 +++++ .../crypto =3D> lib/crypto/sparc}/md5_asm.S | 0 7 files changed, 50 insertions(+), 188 deletions(-) delete mode 100644 arch/sparc/crypto/md5_glue.c create mode 100644 lib/crypto/sparc/md5.h rename {arch/sparc/crypto =3D> lib/crypto/sparc}/md5_asm.S (100%) diff --git a/arch/sparc/crypto/Kconfig b/arch/sparc/crypto/Kconfig index f5b2e720fec3c..f755da9795346 100644 --- a/arch/sparc/crypto/Kconfig +++ b/arch/sparc/crypto/Kconfig @@ -14,20 +14,10 @@ config CRYPTO_DES_SPARC64 Length-preserving ciphers: DES with ECB and CBC modes Length-preserving ciphers: Tripe DES EDE with ECB and CBC modes =20 Architecture: sparc64 =20 -config CRYPTO_MD5_SPARC64 - tristate "Digests: MD5" - depends on SPARC64 - select CRYPTO_MD5 - select CRYPTO_HASH - help - MD5 message digest algorithm (RFC1321) - - Architecture: sparc64 using crypto instructions, when available - config CRYPTO_AES_SPARC64 tristate "Ciphers: AES, modes: ECB, CBC, CTR" depends on SPARC64 select CRYPTO_SKCIPHER help diff --git a/arch/sparc/crypto/Makefile b/arch/sparc/crypto/Makefile index 0d05a17988c4c..7b4796842ddd7 100644 --- a/arch/sparc/crypto/Makefile +++ b/arch/sparc/crypto/Makefile @@ -1,16 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 # # Arch-specific CryptoAPI modules. # =20 -obj-$(CONFIG_CRYPTO_MD5_SPARC64) +=3D md5-sparc64.o - obj-$(CONFIG_CRYPTO_AES_SPARC64) +=3D aes-sparc64.o obj-$(CONFIG_CRYPTO_DES_SPARC64) +=3D des-sparc64.o obj-$(CONFIG_CRYPTO_CAMELLIA_SPARC64) +=3D camellia-sparc64.o =20 -md5-sparc64-y :=3D md5_asm.o md5_glue.o - aes-sparc64-y :=3D aes_asm.o aes_glue.o des-sparc64-y :=3D des_asm.o des_glue.o camellia-sparc64-y :=3D camellia_asm.o camellia_glue.o diff --git a/arch/sparc/crypto/md5_glue.c b/arch/sparc/crypto/md5_glue.c deleted file mode 100644 index b3615f0cdf626..0000000000000 --- a/arch/sparc/crypto/md5_glue.c +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* Glue code for MD5 hashing optimized for sparc64 crypto opcodes. - * - * This is based largely upon arch/x86/crypto/sha1_ssse3_glue.c - * and crypto/md5.c which are: - * - * Copyright (c) Alan Smithee. - * Copyright (c) Andrew McDonald - * Copyright (c) Jean-Francois Dive - * Copyright (c) Mathias Krause - * Copyright (c) Cryptoapi developers. - * Copyright (c) 2002 James Morris - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct sparc_md5_state { - __le32 hash[MD5_HASH_WORDS]; - u64 byte_count; -}; - -asmlinkage void md5_sparc64_transform(__le32 *digest, const char *data, - unsigned int rounds); - -static int md5_sparc64_init(struct shash_desc *desc) -{ - struct sparc_md5_state *mctx =3D shash_desc_ctx(desc); - - mctx->hash[0] =3D cpu_to_le32(MD5_H0); - mctx->hash[1] =3D cpu_to_le32(MD5_H1); - mctx->hash[2] =3D cpu_to_le32(MD5_H2); - mctx->hash[3] =3D cpu_to_le32(MD5_H3); - mctx->byte_count =3D 0; - - return 0; -} - -static int md5_sparc64_update(struct shash_desc *desc, const u8 *data, - unsigned int len) -{ - struct sparc_md5_state *sctx =3D shash_desc_ctx(desc); - - sctx->byte_count +=3D round_down(len, MD5_HMAC_BLOCK_SIZE); - md5_sparc64_transform(sctx->hash, data, len / MD5_HMAC_BLOCK_SIZE); - return len - round_down(len, MD5_HMAC_BLOCK_SIZE); -} - -/* Add padding and return the message digest. */ -static int md5_sparc64_finup(struct shash_desc *desc, const u8 *src, - unsigned int offset, u8 *out) -{ - struct sparc_md5_state *sctx =3D shash_desc_ctx(desc); - __le64 block[MD5_BLOCK_WORDS] =3D {}; - u8 *p =3D memcpy(block, src, offset); - __le32 *dst =3D (__le32 *)out; - __le64 *pbits; - int i; - - src =3D p; - p +=3D offset; - *p++ =3D 0x80; - sctx->byte_count +=3D offset; - pbits =3D &block[(MD5_BLOCK_WORDS / (offset > 55 ? 1 : 2)) - 1]; - *pbits =3D cpu_to_le64(sctx->byte_count << 3); - md5_sparc64_transform(sctx->hash, src, (pbits - block + 1) / 8); - memzero_explicit(block, sizeof(block)); - - /* Store state in digest */ - for (i =3D 0; i < MD5_HASH_WORDS; i++) - dst[i] =3D sctx->hash[i]; - - return 0; -} - -static int md5_sparc64_export(struct shash_desc *desc, void *out) -{ - struct sparc_md5_state *sctx =3D shash_desc_ctx(desc); - union { - u8 *u8; - u32 *u32; - u64 *u64; - } p =3D { .u8 =3D out }; - int i; - - for (i =3D 0; i < MD5_HASH_WORDS; i++) - put_unaligned(le32_to_cpu(sctx->hash[i]), p.u32++); - put_unaligned(sctx->byte_count, p.u64); - return 0; -} - -static int md5_sparc64_import(struct shash_desc *desc, const void *in) -{ - struct sparc_md5_state *sctx =3D shash_desc_ctx(desc); - union { - const u8 *u8; - const u32 *u32; - const u64 *u64; - } p =3D { .u8 =3D in }; - int i; - - for (i =3D 0; i < MD5_HASH_WORDS; i++) - sctx->hash[i] =3D cpu_to_le32(get_unaligned(p.u32++)); - sctx->byte_count =3D get_unaligned(p.u64); - return 0; -} - -static struct shash_alg alg =3D { - .digestsize =3D MD5_DIGEST_SIZE, - .init =3D md5_sparc64_init, - .update =3D md5_sparc64_update, - .finup =3D md5_sparc64_finup, - .export =3D md5_sparc64_export, - .import =3D md5_sparc64_import, - .descsize =3D sizeof(struct sparc_md5_state), - .statesize =3D sizeof(struct sparc_md5_state), - .base =3D { - .cra_name =3D "md5", - .cra_driver_name=3D "md5-sparc64", - .cra_priority =3D SPARC_CR_OPCODE_PRIORITY, - .cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .cra_blocksize =3D MD5_HMAC_BLOCK_SIZE, - .cra_module =3D THIS_MODULE, - } -}; - -static bool __init sparc64_has_md5_opcode(void) -{ - unsigned long cfr; - - if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO)) - return false; - - __asm__ __volatile__("rd %%asr26, %0" : "=3Dr" (cfr)); - if (!(cfr & CFR_MD5)) - return false; - - return true; -} - -static int __init md5_sparc64_mod_init(void) -{ - if (sparc64_has_md5_opcode()) { - pr_info("Using sparc64 md5 opcode optimized MD5 implementation\n"); - return crypto_register_shash(&alg); - } - pr_info("sparc64 md5 opcode not available.\n"); - return -ENODEV; -} - -static void __exit md5_sparc64_mod_fini(void) -{ - crypto_unregister_shash(&alg); -} - -module_init(md5_sparc64_mod_init); -module_exit(md5_sparc64_mod_fini); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("MD5 Message Digest Algorithm, sparc64 md5 opcode accel= erated"); - -MODULE_ALIAS_CRYPTO("md5"); - -#include "crop_devid.c" diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index cfbbfaae9fe29..2ca1d5b37dc0e 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -110,10 +110,11 @@ config CRYPTO_LIB_MD5 config CRYPTO_LIB_MD5_ARCH bool depends on CRYPTO_LIB_MD5 && !UML default y if MIPS && CPU_CAVIUM_OCTEON default y if PPC + default y if SPARC64 =20 config CRYPTO_LIB_POLY1305_RSIZE int default 2 if MIPS default 11 if X86_64 diff --git a/lib/crypto/Makefile b/lib/crypto/Makefile index 8360054481b84..e52a08937390c 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -64,10 +64,11 @@ libdes-y :=3D des.o obj-$(CONFIG_CRYPTO_LIB_MD5) +=3D libmd5.o libmd5-y :=3D md5.o ifeq ($(CONFIG_CRYPTO_LIB_MD5_ARCH),y) CFLAGS_md5.o +=3D -I$(src)/$(SRCARCH) libmd5-$(CONFIG_PPC) +=3D powerpc/md5-asm.o +libmd5-$(CONFIG_SPARC) +=3D sparc/md5_asm.o endif # CONFIG_CRYPTO_LIB_MD5_ARCH =20 ##########################################################################= ###### =20 obj-$(CONFIG_CRYPTO_LIB_POLY1305) +=3D libpoly1305.o diff --git a/lib/crypto/sparc/md5.h b/lib/crypto/sparc/md5.h new file mode 100644 index 0000000000000..3f1b0ed8c0b3f --- /dev/null +++ b/lib/crypto/sparc/md5.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * MD5 accelerated using the sparc64 crypto opcodes + * + * Copyright (c) Alan Smithee. + * Copyright (c) Andrew McDonald + * Copyright (c) Jean-Francois Dive + * Copyright (c) Mathias Krause + * Copyright (c) Cryptoapi developers. + * Copyright (c) 2002 James Morris + */ + +#include +#include +#include + +static __ro_after_init DEFINE_STATIC_KEY_FALSE(have_md5_opcodes); + +asmlinkage void md5_sparc64_transform(struct md5_block_state *state, + const u8 *data, size_t nblocks); + +static void md5_blocks(struct md5_block_state *state, + const u8 *data, size_t nblocks) +{ + if (static_branch_likely(&have_md5_opcodes)) { + cpu_to_le32_array(state->h, ARRAY_SIZE(state->h)); + md5_sparc64_transform(state, data, nblocks); + le32_to_cpu_array(state->h, ARRAY_SIZE(state->h)); + } else { + md5_blocks_generic(state, data, nblocks); + } +} + +#define md5_mod_init_arch md5_mod_init_arch +static inline void md5_mod_init_arch(void) +{ + unsigned long cfr; + + if (!(sparc64_elf_hwcap & HWCAP_SPARC_CRYPTO)) + return; + + __asm__ __volatile__("rd %%asr26, %0" : "=3Dr" (cfr)); + if (!(cfr & CFR_MD5)) + return; + + static_branch_enable(&have_md5_opcodes); + pr_info("Using sparc64 md5 opcode optimized MD5 implementation\n"); +} diff --git a/arch/sparc/crypto/md5_asm.S b/lib/crypto/sparc/md5_asm.S similarity index 100% rename from arch/sparc/crypto/md5_asm.S rename to lib/crypto/sparc/md5_asm.S --=20 2.50.1 From nobody Sun Oct 5 10:44:55 2025 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 4101D264612; Tue, 5 Aug 2025 22:30: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=1754433011; cv=none; b=a4VUXlFLZ10D/l09ivOeWc0+sXyCR+0SDybYVTSlDvgXQqt2/ep96sBW8E1CQIRSMtFi8+ejntp89u317OXbthPBRaSboCMUElAJAaOpi+VOv3j7ybHWw8brKsykYUhjSQsGBFhfxq+KHWeaAqMdj758NUm0QaOv/i44TwZtsj8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754433011; c=relaxed/simple; bh=fiYchuo+RVrtqKxrjd7Ts9LYrhDRRyPxeI/QJOoy2Wc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YdMLJ144x0aRqgAdoUlTJtlJ8OmNZL2hBhCPecAzRIsFGOyod6vwEYPUWx7v7nJSzwqEuhBltGZjFeidO3Ohv3t172qcjVhOWisfXJg8vnMJx2yHutRbfqHIWRDpPfteQYQxs6jQnQALnmow5K4Xg3VNferRMGNzWSBC40nVGE4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=SEdq/W8G; 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="SEdq/W8G" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 16478C4CEF0; Tue, 5 Aug 2025 22:30:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754433010; bh=fiYchuo+RVrtqKxrjd7Ts9LYrhDRRyPxeI/QJOoy2Wc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=SEdq/W8Gx2Hfn0Su+MvFBjF1TieETnYPJBE3kmvYVDSNxWaoRPFlJ5kemkfAUux1o 2SEp13wXzG7jY2lPW98eAINbVzXJ8V0623ePTC7XShYUHMDvvIIAN+Erj0h5FcFCzw tlHqKYmubwbPtTKvdfI+ki5M8QTsnPDri04XZAFavIux+UkE4NvjpZuoWCfs1oQy4P 3eZttxqx5JqHuVIK4Aqk95S+yHtof03KUk0JghtugbLC8x3fRVyWNuj4HwcSUycJPI 1PqQz+R076naLdNhzQGUjBeYD8FHMxATnW5cbnl12EBEHAmM2/5RyVlkw9ouzx8iGB oHrCNrnVIbQvg== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, sparclinux@vger.kernel.org, Eric Biggers Subject: [PATCH v2 6/7] crypto: md5 - Wrap library and add HMAC support Date: Tue, 5 Aug 2025 15:28:54 -0700 Message-ID: <20250805222855.10362-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250805222855.10362-1-ebiggers@kernel.org> References: <20250805222855.10362-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" Reimplement crypto/md5.c on top of the new MD5 library functions. Also add support for HMAC-MD5, again just wrapping the library functions. This closely mirrors crypto/sha1.c. Signed-off-by: Eric Biggers --- crypto/Kconfig | 2 +- crypto/md5.c | 359 ++++++++++++++++++-------------------- crypto/testmgr.c | 3 + drivers/crypto/img-hash.c | 2 +- 4 files changed, 171 insertions(+), 195 deletions(-) diff --git a/crypto/Kconfig b/crypto/Kconfig index 23bd98981ae8e..331c4fbb158b2 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -937,11 +937,11 @@ config CRYPTO_MD4 =20 config CRYPTO_MD5 tristate "MD5" select CRYPTO_HASH help - MD5 message digest algorithm (RFC1321) + MD5 message digest algorithm (RFC1321), including HMAC support. =20 config CRYPTO_MICHAEL_MIC tristate "Michael MIC" select CRYPTO_HASH help diff --git a/crypto/md5.c b/crypto/md5.c index 32c0819f51185..d05c53e6f3c2c 100644 --- a/crypto/md5.c +++ b/crypto/md5.c @@ -1,224 +1,197 @@ -/*=20 - * Cryptographic API. - * - * MD5 Message Digest Algorithm (RFC1321). - * - * Derived from cryptoapi implementation, originally based on the - * public domain implementation written by Colin Plumb in 1993. - * - * Copyright (c) Cryptoapi developers. - * Copyright (c) 2002 James Morris - *=20 - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the F= ree - * Software Foundation; either version 2 of the License, or (at your optio= n)=20 - * any later version. +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Crypto API support for MD5 and HMAC-MD5 * + * Copyright 2025 Google LLC */ #include #include #include #include -#include + +/* + * Export and import functions. crypto_shash wants a particular format th= at + * matches that used by some legacy drivers. It currently is the same as = the + * library MD5 context, except the value in bytecount must be block-aligne= d and + * the remainder must be stored in an extra u8 appended to the struct. + */ + +#define MD5_SHASH_STATE_SIZE (sizeof(struct md5_ctx) + 1) +static_assert(sizeof(struct md5_ctx) =3D=3D sizeof(struct md5_state)); +static_assert(offsetof(struct md5_ctx, state) =3D=3D offsetof(struct md5_s= tate, hash)); +static_assert(offsetof(struct md5_ctx, bytecount) =3D=3D offsetof(struct m= d5_state, byte_count)); +static_assert(offsetof(struct md5_ctx, buf) =3D=3D offsetof(struct md5_sta= te, block)); + +static int __crypto_md5_export(const struct md5_ctx *ctx0, void *out) +{ + struct md5_ctx ctx =3D *ctx0; + unsigned int partial; + u8 *p =3D out; + + partial =3D ctx.bytecount % MD5_BLOCK_SIZE; + ctx.bytecount -=3D partial; + memcpy(p, &ctx, sizeof(ctx)); + p +=3D sizeof(ctx); + *p =3D partial; + return 0; +} + +static int __crypto_md5_import(struct md5_ctx *ctx, const void *in) +{ + const u8 *p =3D in; + + memcpy(ctx, p, sizeof(*ctx)); + p +=3D sizeof(*ctx); + ctx->bytecount +=3D *p; + return 0; +} =20 const u8 md5_zero_message_hash[MD5_DIGEST_SIZE] =3D { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e, }; EXPORT_SYMBOL_GPL(md5_zero_message_hash); =20 -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -#define MD5STEP(f, w, x, y, z, in, s) \ - (w +=3D f(x, y, z) + in, w =3D (w<>(32-s)) + x) - -static void md5_transform(__u32 *hash, __u32 const *in) -{ - u32 a, b, c, d; - - a =3D hash[0]; - b =3D hash[1]; - c =3D hash[2]; - d =3D hash[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - hash[0] +=3D a; - hash[1] +=3D b; - hash[2] +=3D c; - hash[3] +=3D d; -} - -static inline void md5_transform_helper(struct md5_state *ctx, - u32 block[MD5_BLOCK_WORDS]) -{ - le32_to_cpu_array(block, MD5_BLOCK_WORDS); - md5_transform(ctx->hash, block); -} - -static int md5_init(struct shash_desc *desc) -{ - struct md5_state *mctx =3D shash_desc_ctx(desc); - - mctx->hash[0] =3D MD5_H0; - mctx->hash[1] =3D MD5_H1; - mctx->hash[2] =3D MD5_H2; - mctx->hash[3] =3D MD5_H3; - mctx->byte_count =3D 0; +#define MD5_CTX(desc) ((struct md5_ctx *)shash_desc_ctx(desc)) =20 +static int crypto_md5_init(struct shash_desc *desc) +{ + md5_init(MD5_CTX(desc)); return 0; } =20 -static int md5_update(struct shash_desc *desc, const u8 *data, unsigned in= t len) -{ - struct md5_state *mctx =3D shash_desc_ctx(desc); - u32 block[MD5_BLOCK_WORDS]; - - mctx->byte_count +=3D len; - do { - memcpy(block, data, sizeof(block)); - md5_transform_helper(mctx, block); - data +=3D sizeof(block); - len -=3D sizeof(block); - } while (len >=3D sizeof(block)); - memzero_explicit(block, sizeof(block)); - mctx->byte_count -=3D len; - return len; -} - -static int md5_finup(struct shash_desc *desc, const u8 *data, unsigned int= len, - u8 *out) -{ - struct md5_state *mctx =3D shash_desc_ctx(desc); - u32 block[MD5_BLOCK_WORDS]; - unsigned int offset; - int padding; - char *p; - - memcpy(block, data, len); - - offset =3D len; - p =3D (char *)block + offset; - padding =3D 56 - (offset + 1); - - *p++ =3D 0x80; - if (padding < 0) { - memset(p, 0x00, padding + sizeof (u64)); - md5_transform_helper(mctx, block); - p =3D (char *)block; - padding =3D 56; - } - - memset(p, 0, padding); - mctx->byte_count +=3D len; - block[14] =3D mctx->byte_count << 3; - block[15] =3D mctx->byte_count >> 29; - le32_to_cpu_array(block, (sizeof(block) - sizeof(u64)) / sizeof(u32)); - md5_transform(mctx->hash, block); - memzero_explicit(block, sizeof(block)); - cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32)); - memcpy(out, mctx->hash, sizeof(mctx->hash)); +static int crypto_md5_update(struct shash_desc *desc, + const u8 *data, unsigned int len) +{ + md5_update(MD5_CTX(desc), data, len); + return 0; +} =20 +static int crypto_md5_final(struct shash_desc *desc, u8 *out) +{ + md5_final(MD5_CTX(desc), out); return 0; } =20 -static struct shash_alg alg =3D { - .digestsize =3D MD5_DIGEST_SIZE, - .init =3D md5_init, - .update =3D md5_update, - .finup =3D md5_finup, - .descsize =3D MD5_STATE_SIZE, - .base =3D { - .cra_name =3D "md5", - .cra_driver_name =3D "md5-generic", - .cra_flags =3D CRYPTO_AHASH_ALG_BLOCK_ONLY, - .cra_blocksize =3D MD5_HMAC_BLOCK_SIZE, - .cra_module =3D THIS_MODULE, - } -}; +static int crypto_md5_digest(struct shash_desc *desc, + const u8 *data, unsigned int len, u8 *out) +{ + md5(data, len, out); + return 0; +} + +static int crypto_md5_export(struct shash_desc *desc, void *out) +{ + return __crypto_md5_export(MD5_CTX(desc), out); +} + +static int crypto_md5_import(struct shash_desc *desc, const void *in) +{ + return __crypto_md5_import(MD5_CTX(desc), in); +} =20 -static int __init md5_mod_init(void) +#define HMAC_MD5_KEY(tfm) ((struct hmac_md5_key *)crypto_shash_ctx(tfm)) +#define HMAC_MD5_CTX(desc) ((struct hmac_md5_ctx *)shash_desc_ctx(desc)) + +static int crypto_hmac_md5_setkey(struct crypto_shash *tfm, + const u8 *raw_key, unsigned int keylen) +{ + hmac_md5_preparekey(HMAC_MD5_KEY(tfm), raw_key, keylen); + return 0; +} + +static int crypto_hmac_md5_init(struct shash_desc *desc) +{ + hmac_md5_init(HMAC_MD5_CTX(desc), HMAC_MD5_KEY(desc->tfm)); + return 0; +} + +static int crypto_hmac_md5_update(struct shash_desc *desc, + const u8 *data, unsigned int len) +{ + hmac_md5_update(HMAC_MD5_CTX(desc), data, len); + return 0; +} + +static int crypto_hmac_md5_final(struct shash_desc *desc, u8 *out) +{ + hmac_md5_final(HMAC_MD5_CTX(desc), out); + return 0; +} + +static int crypto_hmac_md5_digest(struct shash_desc *desc, + const u8 *data, unsigned int len, u8 *out) +{ + hmac_md5(HMAC_MD5_KEY(desc->tfm), data, len, out); + return 0; +} + +static int crypto_hmac_md5_export(struct shash_desc *desc, void *out) { - return crypto_register_shash(&alg); + return __crypto_md5_export(&HMAC_MD5_CTX(desc)->hash_ctx, out); } =20 -static void __exit md5_mod_fini(void) +static int crypto_hmac_md5_import(struct shash_desc *desc, const void *in) { - crypto_unregister_shash(&alg); + struct hmac_md5_ctx *ctx =3D HMAC_MD5_CTX(desc); + + ctx->ostate =3D HMAC_MD5_KEY(desc->tfm)->ostate; + return __crypto_md5_import(&ctx->hash_ctx, in); } =20 -module_init(md5_mod_init); -module_exit(md5_mod_fini); +static struct shash_alg algs[] =3D { + { + .base.cra_name =3D "md5", + .base.cra_driver_name =3D "md5-lib", + .base.cra_priority =3D 300, + .base.cra_blocksize =3D MD5_BLOCK_SIZE, + .base.cra_module =3D THIS_MODULE, + .digestsize =3D MD5_DIGEST_SIZE, + .init =3D crypto_md5_init, + .update =3D crypto_md5_update, + .final =3D crypto_md5_final, + .digest =3D crypto_md5_digest, + .export =3D crypto_md5_export, + .import =3D crypto_md5_import, + .descsize =3D sizeof(struct md5_ctx), + .statesize =3D MD5_SHASH_STATE_SIZE, + }, + { + .base.cra_name =3D "hmac(md5)", + .base.cra_driver_name =3D "hmac-md5-lib", + .base.cra_priority =3D 300, + .base.cra_blocksize =3D MD5_BLOCK_SIZE, + .base.cra_ctxsize =3D sizeof(struct hmac_md5_key), + .base.cra_module =3D THIS_MODULE, + .digestsize =3D MD5_DIGEST_SIZE, + .setkey =3D crypto_hmac_md5_setkey, + .init =3D crypto_hmac_md5_init, + .update =3D crypto_hmac_md5_update, + .final =3D crypto_hmac_md5_final, + .digest =3D crypto_hmac_md5_digest, + .export =3D crypto_hmac_md5_export, + .import =3D crypto_hmac_md5_import, + .descsize =3D sizeof(struct hmac_md5_ctx), + .statesize =3D MD5_SHASH_STATE_SIZE, + }, +}; + +static int __init crypto_md5_mod_init(void) +{ + return crypto_register_shashes(algs, ARRAY_SIZE(algs)); +} +module_init(crypto_md5_mod_init); + +static void __exit crypto_md5_mod_exit(void) +{ + crypto_unregister_shashes(algs, ARRAY_SIZE(algs)); +} +module_exit(crypto_md5_mod_exit); =20 MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("MD5 Message Digest Algorithm"); +MODULE_DESCRIPTION("Crypto API support for MD5 and HMAC-MD5"); + MODULE_ALIAS_CRYPTO("md5"); +MODULE_ALIAS_CRYPTO("md5-lib"); +MODULE_ALIAS_CRYPTO("hmac(md5)"); +MODULE_ALIAS_CRYPTO("hmac-md5-lib"); diff --git a/crypto/testmgr.c b/crypto/testmgr.c index ee33ba21ae2bc..beab926ba102e 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -4176,10 +4176,11 @@ static const struct alg_test_desc alg_test_descs[] = =3D { .suite =3D { .cprng =3D __VECS(ansi_cprng_aes_tv_template) } }, { .alg =3D "authenc(hmac(md5),ecb(cipher_null))", + .generic_driver =3D "authenc(hmac-md5-lib,ecb-cipher_null)", .test =3D alg_test_aead, .suite =3D { .aead =3D __VECS(hmac_md5_ecb_cipher_null_tv_template) } }, { @@ -5062,10 +5063,11 @@ static const struct alg_test_desc alg_test_descs[] = =3D { .suite =3D { .cipher =3D __VECS(aes_hctr2_tv_template) } }, { .alg =3D "hmac(md5)", + .generic_driver =3D "hmac-md5-lib", .test =3D alg_test_hash, .suite =3D { .hash =3D __VECS(hmac_md5_tv_template) } }, { @@ -5248,10 +5250,11 @@ static const struct alg_test_desc alg_test_descs[] = =3D { .suite =3D { .hash =3D __VECS(md4_tv_template) } }, { .alg =3D "md5", + .generic_driver =3D "md5-lib", .test =3D alg_test_hash, .suite =3D { .hash =3D __VECS(md5_tv_template) } }, { diff --git a/drivers/crypto/img-hash.c b/drivers/crypto/img-hash.c index 76b7ecb5624b1..f22c12e36b56c 100644 --- a/drivers/crypto/img-hash.c +++ b/drivers/crypto/img-hash.c @@ -698,11 +698,11 @@ static int img_hash_cra_init(struct crypto_tfm *tfm, = const char *alg_name) return 0; } =20 static int img_hash_cra_md5_init(struct crypto_tfm *tfm) { - return img_hash_cra_init(tfm, "md5-generic"); + return img_hash_cra_init(tfm, "md5-lib"); } =20 static int img_hash_cra_sha1_init(struct crypto_tfm *tfm) { return img_hash_cra_init(tfm, "sha1-lib"); --=20 2.50.1 From nobody Sun Oct 5 10:44:55 2025 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 675A929ACCE; Tue, 5 Aug 2025 22:30:11 +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=1754433011; cv=none; b=mlUZu+RsA3qNY/hjpP4YXYu12RYO0p5lLD6CrsjAheaw/K0hL8yWGw0WtUKffgLgJ82Arpo3vTsOlLEPnsGdrLocCN3yvo/1xC9K1aREtr1yJ9nQ1JDYG29I5hAGBVAsgCTGyws3EldssVMJDIK4j4vJKCKbiXEQVU4zgpsDjeo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754433011; c=relaxed/simple; bh=boThjt8cR7TxwRjjaFjdaDJhkGbA4kE6Mndg6Kr8QuE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hRw63BihO5Nv0JELx/uItL3PQXSubB0rVNttsR+7MsuApA57LUTL9PuyNCgiStJv9c75PmrxBZ822g8WWWGC/SBoLaWxvG+MKM11/Ehz1CbUoX5sC3yZwqxYqFULqMBaSxdizSNYy6xs/eFkWdtDEjaLoxZja8YGeFBvUP6mI6s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RSKW7I4L; 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="RSKW7I4L" Received: by smtp.kernel.org (Postfix) with ESMTPSA id BE1FFC4CEF4; Tue, 5 Aug 2025 22:30:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754433011; bh=boThjt8cR7TxwRjjaFjdaDJhkGbA4kE6Mndg6Kr8QuE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RSKW7I4L7nNMPftqpR3gqPEVjBLkgUbf4jfOejiYcOvrQzTTY6Na45OuQbsjxTrTi LgFnrzTt8k0+PmTr53GyzoYE5kSMR48pz+V8wTPlUaXoOKH2BEY+H385TQPPTiHnRR iMrj4yABBzlXQ5EA9lZuAImMTyh2DN4Hm0j9gasflky9rzaSDyRQwuBHPfmVrseXmn XEWFLAEFG5U/gondCiMw1cRi1+QH/hwfeVkJ+0v13FojgedTdBtjUN+f4v1ytNNnwB Gggw228sKUC3lFy5qYxnW4NzAijJH5A/lVaISUtgJyAJ61/B/TsVCQ24dAdvdOvJaR nmQIiDGYWRG8w== From: Eric Biggers To: linux-crypto@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Ard Biesheuvel , "Jason A . Donenfeld" , linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, sparclinux@vger.kernel.org, Eric Biggers Subject: [PATCH v2 7/7] lib/crypto: tests: Add KUnit tests for MD5 and HMAC-MD5 Date: Tue, 5 Aug 2025 15:28:55 -0700 Message-ID: <20250805222855.10362-8-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250805222855.10362-1-ebiggers@kernel.org> References: <20250805222855.10362-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 a KUnit test suite for the MD5 library functions, including the corresponding HMAC support. The core test logic is in the previously-added hash-test-template.h. This commit just adds the actual KUnit suite, and it adds the generated test vectors to the tree so that gen-hash-testvecs.py won't have to be run at build time. Signed-off-by: Eric Biggers --- lib/crypto/tests/Kconfig | 10 ++ lib/crypto/tests/Makefile | 1 + lib/crypto/tests/md5-testvecs.h | 186 ++++++++++++++++++++++++++++++++ lib/crypto/tests/md5_kunit.c | 39 +++++++ 4 files changed, 236 insertions(+) create mode 100644 lib/crypto/tests/md5-testvecs.h create mode 100644 lib/crypto/tests/md5_kunit.c diff --git a/lib/crypto/tests/Kconfig b/lib/crypto/tests/Kconfig index de7e8babb6afc..c21d53fd4b0ce 100644 --- a/lib/crypto/tests/Kconfig +++ b/lib/crypto/tests/Kconfig @@ -1,7 +1,17 @@ # SPDX-License-Identifier: GPL-2.0-or-later =20 +config CRYPTO_LIB_MD5_KUNIT_TEST + tristate "KUnit tests for MD5" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS + select CRYPTO_LIB_BENCHMARK_VISIBLE + select CRYPTO_LIB_MD5 + help + KUnit tests for the MD5 cryptographic hash function and its + corresponding HMAC. + config CRYPTO_LIB_POLY1305_KUNIT_TEST tristate "KUnit tests for Poly1305" if !KUNIT_ALL_TESTS depends on KUNIT default KUNIT_ALL_TESTS || CRYPTO_SELFTESTS select CRYPTO_LIB_BENCHMARK_VISIBLE diff --git a/lib/crypto/tests/Makefile b/lib/crypto/tests/Makefile index 8601dccd6fdda..f6f82c6f9cb5d 100644 --- a/lib/crypto/tests/Makefile +++ b/lib/crypto/tests/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later =20 +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 diff --git a/lib/crypto/tests/md5-testvecs.h b/lib/crypto/tests/md5-testvec= s.h new file mode 100644 index 0000000000000..be6727feb2966 --- /dev/null +++ b/lib/crypto/tests/md5-testvecs.h @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* This file was generated by: ./scripts/crypto/gen-hash-testvecs.py md5 */ + +static const struct { + size_t data_len; + u8 digest[MD5_DIGEST_SIZE]; +} hash_testvecs[] =3D { + { + .data_len =3D 0, + .digest =3D { + 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e, + }, + }, + { + .data_len =3D 1, + .digest =3D { + 0x16, 0x7b, 0x86, 0xf2, 0x1d, 0xf3, 0x76, 0xc9, + 0x6f, 0x10, 0xa0, 0x61, 0x5b, 0x14, 0x20, 0x0b, + }, + }, + { + .data_len =3D 2, + .digest =3D { + 0x2d, 0x30, 0x96, 0xc7, 0x43, 0x40, 0xed, 0xb2, + 0xfb, 0x84, 0x63, 0x9a, 0xec, 0xc7, 0x3c, 0x3c, + }, + }, + { + .data_len =3D 3, + .digest =3D { + 0xe5, 0x0f, 0xce, 0xe0, 0xc8, 0xff, 0x4e, 0x08, + 0x5e, 0x19, 0xe5, 0xf2, 0x08, 0x11, 0x19, 0x16, + }, + }, + { + .data_len =3D 16, + .digest =3D { + 0xe8, 0xca, 0x29, 0x05, 0x2f, 0xd1, 0xf3, 0x99, + 0x40, 0x71, 0xf5, 0xc2, 0xf7, 0xf8, 0x17, 0x3e, + }, + }, + { + .data_len =3D 32, + .digest =3D { + 0xe3, 0x20, 0xc1, 0xd8, 0x21, 0x14, 0x44, 0x59, + 0x1a, 0xf5, 0x91, 0xaf, 0x69, 0xbe, 0x93, 0x9d, + }, + }, + { + .data_len =3D 48, + .digest =3D { + 0xfb, 0x06, 0xb0, 0xf0, 0x00, 0x10, 0x4b, 0x68, + 0x3d, 0x75, 0xf9, 0x70, 0xde, 0xbb, 0x32, 0x16, + }, + }, + { + .data_len =3D 49, + .digest =3D { + 0x52, 0x86, 0x48, 0x8b, 0xae, 0x91, 0x7c, 0x4e, + 0xc2, 0x2a, 0x69, 0x07, 0x35, 0xcc, 0xb2, 0x88, + }, + }, + { + .data_len =3D 63, + .digest =3D { + 0xfa, 0xd3, 0xf6, 0xe6, 0x7b, 0x1a, 0xc6, 0x05, + 0x73, 0x35, 0x02, 0xab, 0xc7, 0xb3, 0x47, 0xcb, + }, + }, + { + .data_len =3D 64, + .digest =3D { + 0xc5, 0x59, 0x29, 0xe9, 0x0a, 0x4a, 0x86, 0x43, + 0x7c, 0xaf, 0xdf, 0x83, 0xd3, 0xb8, 0x33, 0x5f, + }, + }, + { + .data_len =3D 65, + .digest =3D { + 0x80, 0x05, 0x75, 0x39, 0xec, 0x44, 0x8a, 0x81, + 0xe7, 0x6e, 0x8d, 0xd1, 0xc6, 0xeb, 0xc2, 0xf0, + }, + }, + { + .data_len =3D 127, + .digest =3D { + 0x3f, 0x02, 0xe8, 0xc6, 0xb8, 0x6a, 0x39, 0xc3, + 0xa4, 0x1c, 0xd9, 0x8f, 0x4a, 0x71, 0x40, 0x30, + }, + }, + { + .data_len =3D 128, + .digest =3D { + 0x89, 0x4f, 0x79, 0x3e, 0xff, 0x0c, 0x22, 0x60, + 0xa2, 0xdc, 0x10, 0x5f, 0x23, 0x0a, 0xe7, 0xc6, + }, + }, + { + .data_len =3D 129, + .digest =3D { + 0x06, 0x56, 0x61, 0xb8, 0x8a, 0x82, 0x77, 0x1b, + 0x2c, 0x35, 0xb8, 0x9f, 0xd6, 0xf7, 0xbd, 0x5a, + }, + }, + { + .data_len =3D 256, + .digest =3D { + 0x5d, 0xdf, 0x7d, 0xc8, 0x43, 0x96, 0x3b, 0xdb, + 0xc7, 0x0e, 0x44, 0x42, 0x23, 0xf7, 0xed, 0xdf, + }, + }, + { + .data_len =3D 511, + .digest =3D { + 0xf6, 0x5f, 0x26, 0x51, 0x8a, 0x5a, 0x46, 0x8f, + 0x48, 0x72, 0x90, 0x74, 0x9d, 0x87, 0xbd, 0xdf, + }, + }, + { + .data_len =3D 513, + .digest =3D { + 0xd8, 0x2c, 0xc9, 0x76, 0xfa, 0x67, 0x2e, 0xa6, + 0xc8, 0x12, 0x4a, 0x64, 0xaa, 0x0b, 0x3d, 0xbd, + }, + }, + { + .data_len =3D 1000, + .digest =3D { + 0xe2, 0x7e, 0xb4, 0x5f, 0xe1, 0x74, 0x51, 0xfc, + 0xe0, 0xc8, 0xd5, 0xe6, 0x8b, 0x40, 0xd2, 0x0e, + }, + }, + { + .data_len =3D 3333, + .digest =3D { + 0xcd, 0x7d, 0x56, 0xa9, 0x4c, 0x47, 0xea, 0xc2, + 0x34, 0x0b, 0x84, 0x05, 0xf9, 0xad, 0xbb, 0x46, + }, + }, + { + .data_len =3D 4096, + .digest =3D { + 0x63, 0x6e, 0x58, 0xb3, 0x94, 0x6b, 0x83, 0x5f, + 0x1f, 0x0e, 0xd3, 0x66, 0x78, 0x71, 0x98, 0x42, + }, + }, + { + .data_len =3D 4128, + .digest =3D { + 0x9d, 0x68, 0xfc, 0x26, 0x8b, 0x4c, 0xa8, 0xe7, + 0x30, 0x0b, 0x19, 0x52, 0x6e, 0xa5, 0x65, 0x1c, + }, + }, + { + .data_len =3D 4160, + .digest =3D { + 0x1c, 0xaa, 0x7d, 0xee, 0x91, 0x01, 0xe2, 0x5a, + 0xec, 0xe9, 0xde, 0x57, 0x0a, 0xb6, 0x4c, 0x2f, + }, + }, + { + .data_len =3D 4224, + .digest =3D { + 0x1b, 0x31, 0xe3, 0x14, 0x07, 0x16, 0x17, 0xc6, + 0x98, 0x79, 0x88, 0x23, 0xb6, 0x3b, 0x25, 0xc4, + }, + }, + { + .data_len =3D 16384, + .digest =3D { + 0xc6, 0x3d, 0x56, 0x90, 0xf0, 0xf6, 0xe6, 0x50, + 0xf4, 0x76, 0x78, 0x67, 0xa3, 0xdd, 0x62, 0x7b, + }, + }, +}; + +static const u8 hash_testvec_consolidated[MD5_DIGEST_SIZE] =3D { + 0x70, 0x86, 0x9e, 0x6c, 0xa4, 0xc6, 0x71, 0x43, + 0x26, 0x02, 0x1b, 0x3f, 0xfd, 0x56, 0x9f, 0xa6, +}; + +static const u8 hmac_testvec_consolidated[MD5_DIGEST_SIZE] =3D { + 0x10, 0x02, 0x74, 0xf6, 0x4d, 0xb3, 0x3c, 0xc7, + 0xa1, 0xf7, 0xe6, 0xd4, 0x32, 0x64, 0xfa, 0x6d, +}; diff --git a/lib/crypto/tests/md5_kunit.c b/lib/crypto/tests/md5_kunit.c new file mode 100644 index 0000000000000..38bd52c25ae3e --- /dev/null +++ b/lib/crypto/tests/md5_kunit.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright 2025 Google LLC + */ +#include +#include "md5-testvecs.h" + +#define HASH md5 +#define HASH_CTX md5_ctx +#define HASH_SIZE MD5_DIGEST_SIZE +#define HASH_INIT md5_init +#define HASH_UPDATE md5_update +#define HASH_FINAL md5_final +#define HMAC_KEY hmac_md5_key +#define HMAC_CTX hmac_md5_ctx +#define HMAC_PREPAREKEY hmac_md5_preparekey +#define HMAC_INIT hmac_md5_init +#define HMAC_UPDATE hmac_md5_update +#define HMAC_FINAL hmac_md5_final +#define HMAC hmac_md5 +#define HMAC_USINGRAWKEY hmac_md5_usingrawkey +#include "hash-test-template.h" + +static struct kunit_case hash_test_cases[] =3D { + HASH_KUNIT_CASES, + KUNIT_CASE(benchmark_hash), + {}, +}; + +static struct kunit_suite hash_test_suite =3D { + .name =3D "md5", + .test_cases =3D hash_test_cases, + .suite_init =3D hash_suite_init, + .suite_exit =3D hash_suite_exit, +}; +kunit_test_suite(hash_test_suite); + +MODULE_DESCRIPTION("KUnit tests and benchmark for MD5 and HMAC-MD5"); +MODULE_LICENSE("GPL"); --=20 2.50.1