From nobody Sun Oct 5 12:46:13 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 F20961F7060; Sun, 3 Aug 2025 20:45:30 +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=1754253931; cv=none; b=f/3YBKRP/wa/3R2m3aJ24RDNci7BOEAd3gArS6hIW6sSUpAV8RdBqH1Pk/xDnJ8acB6A6VUkXVCnZTyYDjUQWmsjFY9oFGma0BKId3sujcGMvKoOV3ydLOmKaboUc/tZTGUh/qNYshmAAuNT4YNG2mPOWQrUUUptXz8KdHO+3qo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253931; c=relaxed/simple; bh=kOLqgrnl4tWnh+WKFtl52eqWac73t7nW7tHwI5o4EzY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=n8ohiHlTjWNvyZV8EFAtiXS+z4q4ixLpBfQX13ORLxnlTfKk4mgZfIvKxeEFaE7txxXYfbmSFnLWjC6HaD6QhXd7UY+XpAFYoUc9o+lvN3btmu5t6cQnZHIvYz6Vq/XDPjUkjf6vkizWVXXMqHQCpwK8rVfeMxjlQhsNYyo7P9w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qaoBwU0x; 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="qaoBwU0x" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 10375C4CEFA; Sun, 3 Aug 2025 20:45:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754253930; bh=kOLqgrnl4tWnh+WKFtl52eqWac73t7nW7tHwI5o4EzY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qaoBwU0xAivrRD0noa/vc3+65roQolq1SSiKTZuuzE5WS3L3+Ut6OEU+DhWzS+8Gl YygAKB/z0pKalQ3vN6r/NUodOi13X4SrHPwwykCB37rznwR/A8nC4r8RUq789GUqbG WOgsIIRsMEhZ+MVlGIoq/kvoA+3HmDUsRXngkKJauomPLSvNTECe6+jtPeTFlFeOG1 Wgdw30lHqvbXluA75xC7AiqCuqYjSORORo7Wtp+Znf9iZnZHcbZDgYwp9v/5p+jqF7 mkbZrO4XRuvmSRpW6E7rRn9DrErOSYEHfItibttWqMWN+UZAV/2segIuzVcVrL0XI+ Sk2l3FMA/oGNg== 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 1/7] mips: cavium-octeon: Remove Octeon optimized MD5 code Date: Sun, 3 Aug 2025 13:44:27 -0700 Message-ID: <20250803204433.75703-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250803204433.75703-1-ebiggers@kernel.org> References: <20250803204433.75703-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" MD5 is insecure, is no longer commonly used, and has never been optimized for the most common architectures in the kernel. Only mips, powerpc, and sparc have optimized MD5 code in the kernel. Of these, only the powerpc one is actually testable in QEMU. The mips one works only on Cavium Octeon SoCs. Taken together, it's clear that it's time to retire these additional MD5 implementations, and focus maintenance on the MD5 generic C code. This commit removes the Cavium Octeon optimized MD5 code. 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 - arch/mips/include/asm/octeon/crypto.h | 21 +- 5 files changed, 4 insertions(+), 244 deletions(-) delete mode 100644 arch/mips/cavium-octeon/crypto/octeon-md5.c 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/arch/mips/include/asm/octeon/crypto.h b/arch/mips/include/asm/= octeon/crypto.h index cb68f9e284bba..76601e9153d87 100644 --- a/arch/mips/include/asm/octeon/crypto.h +++ b/arch/mips/include/asm/octeon/crypto.h @@ -3,43 +3,41 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * * Copyright (C) 2012-2013 Cavium Inc., All Rights Reserved. * - * MD5/SHA1/SHA256/SHA512 instruction definitions added by + * SHA1, SHA256, and SHA512 instruction definitions added by * Aaro Koskinen . * */ #ifndef __LINUX_OCTEON_CRYPTO_H #define __LINUX_OCTEON_CRYPTO_H =20 #include #include =20 -#define OCTEON_CR_OPCODE_PRIORITY 300 - extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *state); extern void octeon_crypto_disable(struct octeon_cop2_state *state, unsigned long flags); =20 /* - * Macros needed to implement MD5/SHA1/SHA256: + * Macros needed to implement SHA1 and SHA256: */ =20 /* - * The index can be 0-1 (MD5) or 0-2 (SHA1), 0-3 (SHA256). + * The index can be 0-2 (SHA1) or 0-3 (SHA256). */ #define write_octeon_64bit_hash_dword(value, index) \ do { \ __asm__ __volatile__ ( \ "dmtc2 %[rt],0x0048+" STR(index) \ : \ : [rt] "d" (cpu_to_be64(value))); \ } while (0) =20 /* - * The index can be 0-1 (MD5) or 0-2 (SHA1), 0-3 (SHA256). + * The index can be 0-2 (SHA1) or 0-3 (SHA256). */ #define read_octeon_64bit_hash_dword(index) \ ({ \ __be64 __value; \ \ @@ -60,21 +58,10 @@ do { \ "dmtc2 %[rt],0x0040+" STR(index) \ : \ : [rt] "d" (cpu_to_be64(value))); \ } while (0) =20 -/* - * The value is the final block dword (64-bit). - */ -#define octeon_md5_start(value) \ -do { \ - __asm__ __volatile__ ( \ - "dmtc2 %[rt],0x4047" \ - : \ - : [rt] "d" (cpu_to_be64(value))); \ -} while (0) - /* * The value is the final block dword (64-bit). */ #define octeon_sha1_start(value) \ do { \ --=20 2.50.1 From nobody Sun Oct 5 12:46:13 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 020B02040A8; Sun, 3 Aug 2025 20:45:31 +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=1754253932; cv=none; b=QEKj2RNJe+qYwa5peUw730MQNhD5rjX3NoVVI5ahx3zwxJR/wmF5vGXjznmUmKaa9mLXhIvqq8nHfT2Vino7g1h0JbDyMCqakEbUiKfG4/MXESNpKcDpZH+/8YJLShxsCD/VHkx8mYmvfxJCyPA0wAO++YUEToGBkFEJXXGN+E8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253932; c=relaxed/simple; bh=VRc4KV6AcWRLoeXQnbyPvjrtyrIbJyC0ogU8BITtRHo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UTb/rXLCEoYTB5N2mWybErzNG4m+WivvYPGIcH5VmfUj556+NIlZhcPGtEVvPMT8DLoHaaDwHyJEbbIgcoBJFFxkJaRga0hKToy2f7tjzXZddBl5Debka4lHalufgDloSZ3k/7JkF+/NWszCiHNkx4yTpIoGekzBJUEkOrmqMc4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=N+KsnGpw; 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="N+KsnGpw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E213FC4CEF8; Sun, 3 Aug 2025 20:45:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754253931; bh=VRc4KV6AcWRLoeXQnbyPvjrtyrIbJyC0ogU8BITtRHo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=N+KsnGpwwuxsYDM6Sea4+60NJiUpAY1xBL7i4Ncuh9/IGMN+PP98T5E33HylbqP5x ywCULf8wxqBHVYCyozXKT5KtiYKzTnv6N2133o0uDoVwjmQAZ0g7ISNmkU7ynDCy0u Z3AbK/lF0H4tUAlfc/8/8EXgbifVXGEzY1sT7mFWbjeWMNlnFb/aIdS5hLN1Dqj2PB SC/MQLHXzpVPseIOmW/BdQitYsHQbMCgpSg1DmhcS/w6aQ/UiRww15xIqbPCEC21Qt auxAaPZr3YaHE+cATbrrESlpIvPJSquumBHOI/8luwN/6JuUf77351xY1YfZ/qoJEU lsW4TtCEcyKYA== 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 2/7] mips: cavium-octeon: Move octeon-crypto.c into parent dir Date: Sun, 3 Aug 2025 13:44:28 -0700 Message-ID: <20250803204433.75703-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250803204433.75703-1-ebiggers@kernel.org> References: <20250803204433.75703-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 12:46:13 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 C3C6220F063; Sun, 3 Aug 2025 20:45:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253932; cv=none; b=i0G6++9QNfKJ5NIelAVcSthCtLrs4o18FZSz6Sh+OHubelUVBrcegV0sHBx8dIgoeQSsgQg6vF3P+aVGigN2mCqHzQLpmmTsi1jTBladxyCLfBXuACrGPucWb/1P7zhHPl+GSHYhmb019L+hVfl/i8zmwaaK6O3WmNqeamWmy2g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253932; c=relaxed/simple; bh=WVzR/sPd61gpCZfbjnLKuwGbqa/5KZl8JqrIevNYQJY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cqlIgHExb0d2h3QwyOZ/9aC26ESry/hufJwpFXWyT0xGDny70L2qr7eV4RrhyGpBgVUndeB7bY9CkDMcod4feCJuFXQUvHyG4grw9LwqrOhgJ4ech2NjEngMV/ljKDx4cwWCc7nMKo8EOlrEf2yZjaeT6SK13PQFMx0UbsDKPqs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=em3JLHcL; 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="em3JLHcL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B6172C4CEEB; Sun, 3 Aug 2025 20:45:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754253932; bh=WVzR/sPd61gpCZfbjnLKuwGbqa/5KZl8JqrIevNYQJY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=em3JLHcLtmxSZWK3sYVpF8WjDvuR5tBSYkjsKrj753tYews9fL+SBR6QDzUxyfTYW 6dUr8h48QEQp0Yt7nCafb4/Y7a6zpEV0EYCIMYGU9MEu2jVvtE5Bj820QuMp9G+wwE RMym8ucmrUAbUToZiQCoFocCuYcHeldhFBJEyCSBZ2fbCNmuLJtbl/pYq5wRt63CdO PxVwWbhNMR5HaC4Vr5q4AVaTcnyEpm8wxqAc5tMMRd+W5V8n0hrWA87udqunvUyM/F 1bfRGzjm0BX01yBncYqBbZNyhCHBeeJ2UuBckN5JYNRtm9WdnjIRbLfJG3JEzyTtQp XRLuNmk8+gJWg== 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 3/7] crypto: powerpc/md5 - Remove PowerPC optimized MD5 code Date: Sun, 3 Aug 2025 13:44:29 -0700 Message-ID: <20250803204433.75703-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250803204433.75703-1-ebiggers@kernel.org> References: <20250803204433.75703-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" MD5 is insecure, is no longer commonly used, and has never been optimized for the most common architectures in the kernel. Only mips, powerpc, and sparc have optimized MD5 code in the kernel. Of these, only the powerpc one is actually testable in QEMU. The mips one works only on Cavium Octeon SoCs. Taken together, it's clear that it's time to retire these additional MD5 implementations, and focus maintenance on the MD5 generic C code. This commit removes the PowerPC optimized MD5 code. 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-asm.S | 235 ------------------------- arch/powerpc/crypto/md5-glue.c | 99 ----------- 6 files changed, 346 deletions(-) delete mode 100644 arch/powerpc/crypto/md5-asm.S delete mode 100644 arch/powerpc/crypto/md5-glue.c 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-asm.S b/arch/powerpc/crypto/md5-asm.S deleted file mode 100644 index fa6bc440cf4ac..0000000000000 --- a/arch/powerpc/crypto/md5-asm.S +++ /dev/null @@ -1,235 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Fast MD5 implementation for PPC - * - * Copyright (c) 2015 Markus Stockhausen - */ -#include -#include -#include - -#define rHP r3 -#define rWP r4 - -#define rH0 r0 -#define rH1 r6 -#define rH2 r7 -#define rH3 r5 - -#define rW00 r8 -#define rW01 r9 -#define rW02 r10 -#define rW03 r11 -#define rW04 r12 -#define rW05 r14 -#define rW06 r15 -#define rW07 r16 -#define rW08 r17 -#define rW09 r18 -#define rW10 r19 -#define rW11 r20 -#define rW12 r21 -#define rW13 r22 -#define rW14 r23 -#define rW15 r24 - -#define rT0 r25 -#define rT1 r26 - -#define INITIALIZE \ - PPC_STLU r1,-INT_FRAME_SIZE(r1); \ - SAVE_GPRS(14, 26, r1) /* push registers onto stack */ - -#define FINALIZE \ - REST_GPRS(14, 26, r1); /* pop registers from stack */ \ - addi r1,r1,INT_FRAME_SIZE - -#ifdef __BIG_ENDIAN__ -#define LOAD_DATA(reg, off) \ - lwbrx reg,0,rWP; /* load data */ -#define INC_PTR \ - addi rWP,rWP,4; /* increment per word */ -#define NEXT_BLOCK /* nothing to do */ -#else -#define LOAD_DATA(reg, off) \ - lwz reg,off(rWP); /* load data */ -#define INC_PTR /* nothing to do */ -#define NEXT_BLOCK \ - addi rWP,rWP,64; /* increment per block */ -#endif - -#define R_00_15(a, b, c, d, w0, w1, p, q, off, k0h, k0l, k1h, k1l) \ - LOAD_DATA(w0, off) /* W */ \ - and rT0,b,c; /* 1: f =3D b and c */ \ - INC_PTR /* ptr++ */ \ - andc rT1,d,b; /* 1: f' =3D ~b and d */ \ - LOAD_DATA(w1, off+4) /* W */ \ - or rT0,rT0,rT1; /* 1: f =3D f or f' */ \ - addi w0,w0,k0l; /* 1: wk =3D w + k */ \ - add a,a,rT0; /* 1: a =3D a + f */ \ - addis w0,w0,k0h; /* 1: wk =3D w + k' */ \ - addis w1,w1,k1h; /* 2: wk =3D w + k */ \ - add a,a,w0; /* 1: a =3D a + wk */ \ - addi w1,w1,k1l; /* 2: wk =3D w + k' */ \ - rotrwi a,a,p; /* 1: a =3D a rotl x */ \ - add d,d,w1; /* 2: a =3D a + wk */ \ - add a,a,b; /* 1: a =3D a + b */ \ - and rT0,a,b; /* 2: f =3D b and c */ \ - andc rT1,c,a; /* 2: f' =3D ~b and d */ \ - or rT0,rT0,rT1; /* 2: f =3D f or f' */ \ - add d,d,rT0; /* 2: a =3D a + f */ \ - INC_PTR /* ptr++ */ \ - rotrwi d,d,q; /* 2: a =3D a rotl x */ \ - add d,d,a; /* 2: a =3D a + b */ - -#define R_16_31(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ - andc rT0,c,d; /* 1: f =3D c and ~d */ \ - and rT1,b,d; /* 1: f' =3D b and d */ \ - addi w0,w0,k0l; /* 1: wk =3D w + k */ \ - or rT0,rT0,rT1; /* 1: f =3D f or f' */ \ - addis w0,w0,k0h; /* 1: wk =3D w + k' */ \ - add a,a,rT0; /* 1: a =3D a + f */ \ - addi w1,w1,k1l; /* 2: wk =3D w + k */ \ - add a,a,w0; /* 1: a =3D a + wk */ \ - addis w1,w1,k1h; /* 2: wk =3D w + k' */ \ - andc rT0,b,c; /* 2: f =3D c and ~d */ \ - rotrwi a,a,p; /* 1: a =3D a rotl x */ \ - add a,a,b; /* 1: a =3D a + b */ \ - add d,d,w1; /* 2: a =3D a + wk */ \ - and rT1,a,c; /* 2: f' =3D b and d */ \ - or rT0,rT0,rT1; /* 2: f =3D f or f' */ \ - add d,d,rT0; /* 2: a =3D a + f */ \ - rotrwi d,d,q; /* 2: a =3D a rotl x */ \ - add d,d,a; /* 2: a =3D a +b */ - -#define R_32_47(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ - xor rT0,b,c; /* 1: f' =3D b xor c */ \ - addi w0,w0,k0l; /* 1: wk =3D w + k */ \ - xor rT1,rT0,d; /* 1: f =3D f xor f' */ \ - addis w0,w0,k0h; /* 1: wk =3D w + k' */ \ - add a,a,rT1; /* 1: a =3D a + f */ \ - addi w1,w1,k1l; /* 2: wk =3D w + k */ \ - add a,a,w0; /* 1: a =3D a + wk */ \ - addis w1,w1,k1h; /* 2: wk =3D w + k' */ \ - rotrwi a,a,p; /* 1: a =3D a rotl x */ \ - add d,d,w1; /* 2: a =3D a + wk */ \ - add a,a,b; /* 1: a =3D a + b */ \ - xor rT1,rT0,a; /* 2: f =3D b xor f' */ \ - add d,d,rT1; /* 2: a =3D a + f */ \ - rotrwi d,d,q; /* 2: a =3D a rotl x */ \ - add d,d,a; /* 2: a =3D a + b */ - -#define R_48_63(a, b, c, d, w0, w1, p, q, k0h, k0l, k1h, k1l) \ - addi w0,w0,k0l; /* 1: w =3D w + k */ \ - orc rT0,b,d; /* 1: f =3D b or ~d */ \ - addis w0,w0,k0h; /* 1: w =3D w + k' */ \ - xor rT0,rT0,c; /* 1: f =3D f xor c */ \ - add a,a,w0; /* 1: a =3D a + wk */ \ - addi w1,w1,k1l; /* 2: w =3D w + k */ \ - add a,a,rT0; /* 1: a =3D a + f */ \ - addis w1,w1,k1h; /* 2: w =3D w + k' */ \ - rotrwi a,a,p; /* 1: a =3D a rotl x */ \ - add a,a,b; /* 1: a =3D a + b */ \ - orc rT0,a,c; /* 2: f =3D b or ~d */ \ - add d,d,w1; /* 2: a =3D a + wk */ \ - xor rT0,rT0,b; /* 2: f =3D f xor c */ \ - add d,d,rT0; /* 2: a =3D a + f */ \ - rotrwi d,d,q; /* 2: a =3D a rotl x */ \ - add d,d,a; /* 2: a =3D a + b */ - -_GLOBAL(ppc_md5_transform) - INITIALIZE - - mtctr r5 - lwz rH0,0(rHP) - lwz rH1,4(rHP) - lwz rH2,8(rHP) - lwz rH3,12(rHP) - -ppc_md5_main: - R_00_15(rH0, rH1, rH2, rH3, rW00, rW01, 25, 20, 0, - 0xd76b, -23432, 0xe8c8, -18602) - R_00_15(rH2, rH3, rH0, rH1, rW02, rW03, 15, 10, 8, - 0x2420, 0x70db, 0xc1be, -12562) - R_00_15(rH0, rH1, rH2, rH3, rW04, rW05, 25, 20, 16, - 0xf57c, 0x0faf, 0x4788, -14806) - R_00_15(rH2, rH3, rH0, rH1, rW06, rW07, 15, 10, 24, - 0xa830, 0x4613, 0xfd47, -27391) - R_00_15(rH0, rH1, rH2, rH3, rW08, rW09, 25, 20, 32, - 0x6981, -26408, 0x8b45, -2129) - R_00_15(rH2, rH3, rH0, rH1, rW10, rW11, 15, 10, 40, - 0xffff, 0x5bb1, 0x895d, -10306) - R_00_15(rH0, rH1, rH2, rH3, rW12, rW13, 25, 20, 48, - 0x6b90, 0x1122, 0xfd98, 0x7193) - R_00_15(rH2, rH3, rH0, rH1, rW14, rW15, 15, 10, 56, - 0xa679, 0x438e, 0x49b4, 0x0821) - - R_16_31(rH0, rH1, rH2, rH3, rW01, rW06, 27, 23, - 0x0d56, 0x6e0c, 0x1810, 0x6d2d) - R_16_31(rH2, rH3, rH0, rH1, rW11, rW00, 18, 12, - 0x9d02, -32109, 0x124c, 0x2332) - R_16_31(rH0, rH1, rH2, rH3, rW05, rW10, 27, 23, - 0x8ea7, 0x4a33, 0x0245, -18270) - R_16_31(rH2, rH3, rH0, rH1, rW15, rW04, 18, 12, - 0x8eee, -8608, 0xf258, -5095) - R_16_31(rH0, rH1, rH2, rH3, rW09, rW14, 27, 23, - 0x969d, -10697, 0x1cbe, -15288) - R_16_31(rH2, rH3, rH0, rH1, rW03, rW08, 18, 12, - 0x3317, 0x3e99, 0xdbd9, 0x7c15) - R_16_31(rH0, rH1, rH2, rH3, rW13, rW02, 27, 23, - 0xac4b, 0x7772, 0xd8cf, 0x331d) - R_16_31(rH2, rH3, rH0, rH1, rW07, rW12, 18, 12, - 0x6a28, 0x6dd8, 0x219a, 0x3b68) - - R_32_47(rH0, rH1, rH2, rH3, rW05, rW08, 28, 21, - 0x29cb, 0x28e5, 0x4218, -7788) - R_32_47(rH2, rH3, rH0, rH1, rW11, rW14, 16, 9, - 0x473f, 0x06d1, 0x3aae, 0x3036) - R_32_47(rH0, rH1, rH2, rH3, rW01, rW04, 28, 21, - 0xaea1, -15134, 0x640b, -11295) - R_32_47(rH2, rH3, rH0, rH1, rW07, rW10, 16, 9, - 0x8f4c, 0x4887, 0xbc7c, -22499) - R_32_47(rH0, rH1, rH2, rH3, rW13, rW00, 28, 21, - 0x7eb8, -27199, 0x00ea, 0x6050) - R_32_47(rH2, rH3, rH0, rH1, rW03, rW06, 16, 9, - 0xe01a, 0x22fe, 0x4447, 0x69c5) - R_32_47(rH0, rH1, rH2, rH3, rW09, rW12, 28, 21, - 0xb7f3, 0x0253, 0x59b1, 0x4d5b) - R_32_47(rH2, rH3, rH0, rH1, rW15, rW02, 16, 9, - 0x4701, -27017, 0xc7bd, -19859) - - R_48_63(rH0, rH1, rH2, rH3, rW00, rW07, 26, 22, - 0x0988, -1462, 0x4c70, -19401) - R_48_63(rH2, rH3, rH0, rH1, rW14, rW05, 17, 11, - 0xadaf, -5221, 0xfc99, 0x66f7) - R_48_63(rH0, rH1, rH2, rH3, rW12, rW03, 26, 22, - 0x7e80, -16418, 0xba1e, -25587) - R_48_63(rH2, rH3, rH0, rH1, rW10, rW01, 17, 11, - 0x4130, 0x380d, 0xe0c5, 0x738d) - lwz rW00,0(rHP) - R_48_63(rH0, rH1, rH2, rH3, rW08, rW15, 26, 22, - 0xe837, -30770, 0xde8a, 0x69e8) - lwz rW14,4(rHP) - R_48_63(rH2, rH3, rH0, rH1, rW06, rW13, 17, 11, - 0x9e79, 0x260f, 0x256d, -27941) - lwz rW12,8(rHP) - R_48_63(rH0, rH1, rH2, rH3, rW04, rW11, 26, 22, - 0xab75, -20775, 0x4f9e, -28397) - lwz rW10,12(rHP) - R_48_63(rH2, rH3, rH0, rH1, rW02, rW09, 17, 11, - 0x662b, 0x7c56, 0x11b2, 0x0358) - - add rH0,rH0,rW00 - stw rH0,0(rHP) - add rH1,rH1,rW14 - stw rH1,4(rHP) - add rH2,rH2,rW12 - stw rH2,8(rHP) - add rH3,rH3,rW10 - stw rH3,12(rHP) - NEXT_BLOCK - - bdnz ppc_md5_main - - FINALIZE - blr 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"); --=20 2.50.1 From nobody Sun Oct 5 12:46:13 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 4C55D214A64; Sun, 3 Aug 2025 20:45:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253933; cv=none; b=iep8s2dqcEiXSeZqOCkNvyML5RQXfOF0h+z64SaNZfBBOwIXgrAnb0m2ik91DygwNpKdl7cB346A4uWwlW3YjTUJ2sA5a4MllFPR92lFOJWSWbFEfstglRK8jA73qj+HkKlxrWeMqsMCdHTfmRsOys/mUAmGQ1Oa3QpJQUxVG18= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253933; c=relaxed/simple; bh=qJoEmIc3Mge0u7TgtUI5nQSBYyQxiZgMWyRRzuSQVwI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HbptTaFtAl85jxPCyLq1V/EEBYsHkAbqUlYhatGSDzT3AEzPE2U+5m3Iv/DKEwi21iKPv+EH3rvBzkIFCgXAMS6W/Ty97I/9EfO3M13nbD34UHpVwpy4BVdzNKSIERceMjZicmwl9rXEI5r6FEVBsJKler+ZX5aVsLmQSjvKroY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=OwaDkcFh; 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="OwaDkcFh" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8A3F5C4CEFF; Sun, 3 Aug 2025 20:45:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754253933; bh=qJoEmIc3Mge0u7TgtUI5nQSBYyQxiZgMWyRRzuSQVwI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OwaDkcFhcnSmeH2K9mzvipkS4S0wlp7t2TgpcZw1uaxNvwS79mcP3uk9rSzS5e85U WkvEBX5rZbvTwfl6kHuGU8Ao85h4Xq4fz2qy8+FkaWHJ07YYWzkiXTTkyxOPuBLdkg f6MAGeU9/b7jOopNP4MOFiroIXDFdGITiQm5fooGcgxVstF2UGhKE2DTKUI6b9L3Di cg1MDzGB+EM2q3copfW097xhyFI9bCGNqigAYSpDEodb9dz9VuS4KTzhohFbrMGfZ6 7m7uU4y0qI0bUjjOLFV9qD4HizaAvIWi0h8Uv76EhP42n7uhwqyyBD0EP/jNgjOAoQ RKVbJUKGqsjUA== 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 4/7] crypto: sparc/md5 - Remove SPARC64 optimized MD5 code Date: Sun, 3 Aug 2025 13:44:30 -0700 Message-ID: <20250803204433.75703-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250803204433.75703-1-ebiggers@kernel.org> References: <20250803204433.75703-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" MD5 is insecure, is no longer commonly used, and has never been optimized for the most common architectures in the kernel. Only mips, powerpc, and sparc have optimized MD5 code in the kernel. Of these, only the powerpc one is actually testable in QEMU. The mips one works only on Cavium Octeon SoCs. Taken together, it's clear that it's time to retire these additional MD5 implementations, and focus maintenance on the MD5 generic C code. This commit removes the SPARC64 optimized MD5 code. Signed-off-by: Eric Biggers --- arch/sparc/crypto/Kconfig | 10 -- arch/sparc/crypto/Makefile | 4 - arch/sparc/crypto/md5_asm.S | 70 -------------- arch/sparc/crypto/md5_glue.c | 174 ----------------------------------- 4 files changed, 258 deletions(-) delete mode 100644 arch/sparc/crypto/md5_asm.S delete mode 100644 arch/sparc/crypto/md5_glue.c 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_asm.S b/arch/sparc/crypto/md5_asm.S deleted file mode 100644 index 60b544e4d205b..0000000000000 --- a/arch/sparc/crypto/md5_asm.S +++ /dev/null @@ -1,70 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include -#include -#include - -ENTRY(md5_sparc64_transform) - /* %o0 =3D digest, %o1 =3D data, %o2 =3D rounds */ - VISEntryHalf - ld [%o0 + 0x00], %f0 - ld [%o0 + 0x04], %f1 - andcc %o1, 0x7, %g0 - ld [%o0 + 0x08], %f2 - bne,pn %xcc, 10f - ld [%o0 + 0x0c], %f3 - -1: - ldd [%o1 + 0x00], %f8 - ldd [%o1 + 0x08], %f10 - ldd [%o1 + 0x10], %f12 - ldd [%o1 + 0x18], %f14 - ldd [%o1 + 0x20], %f16 - ldd [%o1 + 0x28], %f18 - ldd [%o1 + 0x30], %f20 - ldd [%o1 + 0x38], %f22 - - MD5 - - subcc %o2, 1, %o2 - bne,pt %xcc, 1b - add %o1, 0x40, %o1 - -5: - st %f0, [%o0 + 0x00] - st %f1, [%o0 + 0x04] - st %f2, [%o0 + 0x08] - st %f3, [%o0 + 0x0c] - retl - VISExitHalf -10: - alignaddr %o1, %g0, %o1 - - ldd [%o1 + 0x00], %f10 -1: - ldd [%o1 + 0x08], %f12 - ldd [%o1 + 0x10], %f14 - ldd [%o1 + 0x18], %f16 - ldd [%o1 + 0x20], %f18 - ldd [%o1 + 0x28], %f20 - ldd [%o1 + 0x30], %f22 - ldd [%o1 + 0x38], %f24 - ldd [%o1 + 0x40], %f26 - - faligndata %f10, %f12, %f8 - faligndata %f12, %f14, %f10 - faligndata %f14, %f16, %f12 - faligndata %f16, %f18, %f14 - faligndata %f18, %f20, %f16 - faligndata %f20, %f22, %f18 - faligndata %f22, %f24, %f20 - faligndata %f24, %f26, %f22 - - MD5 - - subcc %o2, 1, %o2 - fsrc2 %f26, %f10 - bne,pt %xcc, 1b - add %o1, 0x40, %o1 - - ba,a,pt %xcc, 5b -ENDPROC(md5_sparc64_transform) 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" --=20 2.50.1 From nobody Sun Oct 5 12:46:13 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 74A2521ADB7; Sun, 3 Aug 2025 20:45:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253934; cv=none; b=LtZ+62vThsqsdqbgvD97pZNTmS0jdIQb6LLtYXYmXHM2/njkOjysmSwK1w+8qEfqC8X6grxFHVe4Zeg4c8yqiWYYxxe69kZ8/LCFBeeFwc5tlPs2Hl0FDkrB5caDETsMrtYUFYyRNVvZZAD8D8QCYPsucYU2+EMo78oHXUigD4I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253934; c=relaxed/simple; bh=ZKqjBGMT1lPpSPEhosXQ6UaXTwS5COxO+pglv8pCRY0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=osvQ+p9iYLqzQd7m4cGxvr+p2XNd/km3KSmFffq8apKMkrRY7R/zI1P9I1koP38wDF9Jj4TlF+TV+TMuWEAasGGDTrhpGvNBbntiHfBP7fyWBrhzbU5Y1rfdAHoXF6UVr2mqsWGRhYQNK8IzHiQQglb0GxrIv0BcRxBTT8W3BeE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NOK0sEaw; 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="NOK0sEaw" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5E507C4CEF9; Sun, 3 Aug 2025 20:45:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754253934; bh=ZKqjBGMT1lPpSPEhosXQ6UaXTwS5COxO+pglv8pCRY0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NOK0sEawntaqjNTr10YqcDWlLtWQjR0JYjE2TEA+vuLZwWUer7HGG3wQacp3kNZhJ iIQHx41eboAVWCAuE5p0D4FS9Y0wXogk1psDWboM33Ct8s1Al5eyxrYdaCXVZVSn1K NYc2CJDYxp9QtI+VIH4JH1zZLD2wU/UQxpP7hIdIZ7zwsGy/2zJlqiivmbnjevKjbT fTpLxXSp5YhMV4zVqrgSqYK36l4Bf51KrRM+dpC0jq4kw0ig5o6WAhS3rBvKSY0kb+ nxaSCzmiEZZfMztQbYRXKKXNiTdALn3yM2UtXCm53K+2RI6VwSKn3iEcd53D+35wFL dcRLBgjudZ65g== 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 5/7] lib/crypto: md5: Add MD5 and HMAC-MD5 library functions Date: Sun, 3 Aug 2025 13:44:31 -0700 Message-ID: <20250803204433.75703-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250803204433.75703-1-ebiggers@kernel.org> References: <20250803204433.75703-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; however, support for architecture optimized MD5 implementations isn't included since it is unnecessary. While MD5 is an insecure legacy algorithm, 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 | 6 + lib/crypto/Makefile | 3 + lib/crypto/md5.c | 290 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 479 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..f1b2a51450df2 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -99,10 +99,16 @@ 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_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..252480ab97e9c 100644 --- a/lib/crypto/Makefile +++ b/lib/crypto/Makefile @@ -57,10 +57,13 @@ 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 + 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..17323340963b5 --- /dev/null +++ b/lib/crypto/md5.c @@ -0,0 +1,290 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * MD5 and HMAC-MD5 library functions + * + * md5_transform() is derived from cryptoapi implementation, originally ba= sed on + * the public domain implementation written by Colin Plumb in 1993. + * + * 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_transform(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; +} + +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) { + + if (partial) { + size_t l =3D MD5_BLOCK_SIZE - partial; + + memcpy(&ctx->buf[partial], data, l); + data +=3D l; + len -=3D l; + + md5_transform(&ctx->state, ctx->buf); + } + + while (len >=3D MD5_BLOCK_SIZE) { + md5_transform(&ctx->state, data); + data +=3D MD5_BLOCK_SIZE; + len -=3D 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_transform(&ctx->state, ctx->buf); + 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_transform(&ctx->state, ctx->buf); + + 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_transform(istate, derived_key.b); + + 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_transform(ostate, derived_key.b); + + 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_transform(&ctx->ostate, ctx->hash_ctx.buf); + 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); + +MODULE_DESCRIPTION("MD5 and HMAC-MD5 library functions"); +MODULE_LICENSE("GPL"); --=20 2.50.1 From nobody Sun Oct 5 12:46:13 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 3047821D3CC; Sun, 3 Aug 2025 20:45:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253935; cv=none; b=EWQK/T6F68F3GHyG0IrnaeO+RzZQeydCKO/mSM5/BPyRqzSy4GXs0Mdst3z/XzbJud5j40i/YyEXI3K1JmEzX02iYTLCjZVEFIQpZqeusqduvgDb7mMp61uUh5Cms9SWH8TZ/hgfIMzDjbr9Byda9Daf/sWygOSJphjid4K0BEs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253935; c=relaxed/simple; bh=fiYchuo+RVrtqKxrjd7Ts9LYrhDRRyPxeI/QJOoy2Wc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rRMPzT2R5PsAgdEoDRs6iGn9sMB9a5p1pWQWsxpZBMahyhlHyFY7ds3vw4hclWtH+9Ubf2CiJqywPRBTDpMfA0KVAqRiH+Lf8em4eyIB5TZ55tK2qDuzTLNPjWSdKxFRd5Pth77lWsIk2+PWZoF3amaCm7riceom7RwnEWCvRqE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=qc5jCx85; 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="qc5jCx85" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3293BC4CEFA; Sun, 3 Aug 2025 20:45:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754253934; bh=fiYchuo+RVrtqKxrjd7Ts9LYrhDRRyPxeI/QJOoy2Wc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qc5jCx85M84K5w05XqbmmSLpUlvcDdzhsi76Ie1v7XMMuYk1AQeJw5YbHFHeFXrGG f4xxtUWE/4niOZN8pPu1sGTskOJ2JdfhPZsffG8+KJko5RxKuQlr13CtjtV1xB4+wW vAUFR82FPtBfNh9+UiXjvvJSKH83f3ykc2iweGpLkE0mHkU+OIc2wUMhdNRX2TOWl6 CXCuSCQCOcQUn75tawLHOo/xQbgjFE5XjbXZHKTpbFqTcuO67MS89QBL3JwBJoP//l tWg4sY2tyj8uLNddvC1oFqWeE7j1DWwDG+emhb5Ygc+UZY54rR96dLdqqJjX7NZNSI uR4VwLHXj7e7g== 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 6/7] crypto: md5 - Wrap library and add HMAC support Date: Sun, 3 Aug 2025 13:44:32 -0700 Message-ID: <20250803204433.75703-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250803204433.75703-1-ebiggers@kernel.org> References: <20250803204433.75703-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 12:46:13 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 359E9225417; Sun, 3 Aug 2025 20:45:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253938; cv=none; b=mdqILjX0k04+cfsUInUT9MzbSBX0V+eQuRJlQhZGF8n9KmMenKfGZX9Gal+KvTuSBuO2OO+dLl7YPHA4QC7X2dcrN3SkPBphPrtLGO3fdHKLzplGS9CyWBeXWIqX5YlBBWxiG/UPSWIuNLSLaXqKEFf5Cf4dEBdMpHI3ca8Q/hw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754253938; c=relaxed/simple; bh=boThjt8cR7TxwRjjaFjdaDJhkGbA4kE6Mndg6Kr8QuE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=muaGbHJsp3sisTxFxqnm7en0E8y7vj1Esfx5YDk/pZg4t4G4hN6MAzRS8KaQ6mgbefHaswuVL/qeAzu9Fr5nv6P5IVZH1L4t3LKLY+XhwVZ/L84SaNdakMhFYN/lQIYuWmNdY2x6MnivYoRU428UR4eu8PD3RcjFCvz0nubHoGs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=VUXiCPfP; 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="VUXiCPfP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0B487C4CEF9; Sun, 3 Aug 2025 20:45:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1754253935; bh=boThjt8cR7TxwRjjaFjdaDJhkGbA4kE6Mndg6Kr8QuE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=VUXiCPfPD93bd9FYKlJYo5VE1L3Vtp70mitexZQ/xQUiX7/AtdAwjmFCjnGZTeiLJ FtuWf2ZYSozY8l7BTOQGmwbiGVQcEfnArJcC2shQsXP7wH0zokAFQsk1RgXW7lGgJF RwhNNxnJwwJKIOHZPDASOV3WT8T5wBMTh1Z9lrQIXVQOg3Qa70nzP2Gq90KsS1YS/O iM0SC6XVat7wu1BPipPdk54QNT7NoUuaLFl+GIG64YGWymlKdAyZIe3u3CqmMVizuT v8zd44Bt8jio5UrS7+b5Cz3j0Azs6gY9mExSs9uMoHR+74UfJms1JZGmTti9DAVuwa 8lV9f4HcEuFkA== 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 7/7] lib/crypto: tests: Add KUnit tests for MD5 and HMAC-MD5 Date: Sun, 3 Aug 2025 13:44:33 -0700 Message-ID: <20250803204433.75703-8-ebiggers@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250803204433.75703-1-ebiggers@kernel.org> References: <20250803204433.75703-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