Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lib/crypto: powerpc/md5: Migrate optimized code into library

Instead of exposing the powerpc-optimized MD5 code via powerpc-specific
crypto_shash algorithms, instead just implement the md5_blocks() library
function. This is much simpler, it makes the MD5 library functions be
powerpc-optimized, and it fixes the longstanding issue where the
powerpc-optimized MD5 code was disabled by default. MD5 still remains
available through crypto_shash, but individual architectures no longer
need to handle it.

Link: https://lore.kernel.org/r/20250805222855.10362-5-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>

+14 -111
-1
arch/powerpc/configs/powernv_defconfig
··· 320 320 CONFIG_CRYPTO_BENCHMARK=m 321 321 CONFIG_CRYPTO_PCBC=m 322 322 CONFIG_CRYPTO_HMAC=y 323 - CONFIG_CRYPTO_MD5_PPC=m 324 323 CONFIG_CRYPTO_MICHAEL_MIC=m 325 324 CONFIG_CRYPTO_SHA256=y 326 325 CONFIG_CRYPTO_WP512=m
-1
arch/powerpc/configs/ppc64_defconfig
··· 387 387 CONFIG_CRYPTO_SHA256=y 388 388 CONFIG_CRYPTO_WP512=m 389 389 CONFIG_CRYPTO_LZO=m 390 - CONFIG_CRYPTO_MD5_PPC=m 391 390 CONFIG_CRYPTO_AES_GCM_P10=m 392 391 CONFIG_CRYPTO_DEV_NX=y 393 392 CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
-8
arch/powerpc/crypto/Kconfig
··· 15 15 Architecture: PowerPC64 16 16 - Little-endian 17 17 18 - config CRYPTO_MD5_PPC 19 - tristate "Digests: MD5" 20 - select CRYPTO_HASH 21 - help 22 - MD5 message digest algorithm (RFC1321) 23 - 24 - Architecture: powerpc 25 - 26 18 config CRYPTO_AES_PPC_SPE 27 19 tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS (SPE)" 28 20 depends on SPE
-2
arch/powerpc/crypto/Makefile
··· 6 6 # 7 7 8 8 obj-$(CONFIG_CRYPTO_AES_PPC_SPE) += aes-ppc-spe.o 9 - obj-$(CONFIG_CRYPTO_MD5_PPC) += md5-ppc.o 10 9 obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o 11 10 obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o 12 11 obj-$(CONFIG_CRYPTO_CURVE25519_PPC64) += curve25519-ppc64le.o 13 12 14 13 aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o 15 - md5-ppc-y := md5-asm.o md5-glue.o 16 14 aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-ppc.o 17 15 vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o 18 16 curve25519-ppc64le-y := curve25519-ppc64le-core.o curve25519-ppc64le_asm.o
arch/powerpc/crypto/md5-asm.S lib/crypto/powerpc/md5-asm.S
-99
arch/powerpc/crypto/md5-glue.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - /* 3 - * Glue code for MD5 implementation for PPC assembler 4 - * 5 - * Based on generic implementation. 6 - * 7 - * Copyright (c) 2015 Markus Stockhausen <stockhausen@collogia.de> 8 - */ 9 - 10 - #include <crypto/internal/hash.h> 11 - #include <crypto/md5.h> 12 - #include <linux/kernel.h> 13 - #include <linux/module.h> 14 - #include <linux/string.h> 15 - 16 - extern void ppc_md5_transform(u32 *state, const u8 *src, u32 blocks); 17 - 18 - static int ppc_md5_init(struct shash_desc *desc) 19 - { 20 - struct md5_state *sctx = shash_desc_ctx(desc); 21 - 22 - sctx->hash[0] = MD5_H0; 23 - sctx->hash[1] = MD5_H1; 24 - sctx->hash[2] = MD5_H2; 25 - sctx->hash[3] = MD5_H3; 26 - sctx->byte_count = 0; 27 - 28 - return 0; 29 - } 30 - 31 - static int ppc_md5_update(struct shash_desc *desc, const u8 *data, 32 - unsigned int len) 33 - { 34 - struct md5_state *sctx = shash_desc_ctx(desc); 35 - 36 - sctx->byte_count += round_down(len, MD5_HMAC_BLOCK_SIZE); 37 - ppc_md5_transform(sctx->hash, data, len >> 6); 38 - return len - round_down(len, MD5_HMAC_BLOCK_SIZE); 39 - } 40 - 41 - static int ppc_md5_finup(struct shash_desc *desc, const u8 *src, 42 - unsigned int offset, u8 *out) 43 - { 44 - struct md5_state *sctx = shash_desc_ctx(desc); 45 - __le64 block[MD5_BLOCK_WORDS] = {}; 46 - u8 *p = memcpy(block, src, offset); 47 - __le32 *dst = (__le32 *)out; 48 - __le64 *pbits; 49 - 50 - src = p; 51 - p += offset; 52 - *p++ = 0x80; 53 - sctx->byte_count += offset; 54 - pbits = &block[(MD5_BLOCK_WORDS / (offset > 55 ? 1 : 2)) - 1]; 55 - *pbits = cpu_to_le64(sctx->byte_count << 3); 56 - ppc_md5_transform(sctx->hash, src, (pbits - block + 1) / 8); 57 - memzero_explicit(block, sizeof(block)); 58 - 59 - dst[0] = cpu_to_le32(sctx->hash[0]); 60 - dst[1] = cpu_to_le32(sctx->hash[1]); 61 - dst[2] = cpu_to_le32(sctx->hash[2]); 62 - dst[3] = cpu_to_le32(sctx->hash[3]); 63 - return 0; 64 - } 65 - 66 - static struct shash_alg alg = { 67 - .digestsize = MD5_DIGEST_SIZE, 68 - .init = ppc_md5_init, 69 - .update = ppc_md5_update, 70 - .finup = ppc_md5_finup, 71 - .descsize = MD5_STATE_SIZE, 72 - .base = { 73 - .cra_name = "md5", 74 - .cra_driver_name= "md5-ppc", 75 - .cra_priority = 200, 76 - .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 77 - .cra_blocksize = MD5_HMAC_BLOCK_SIZE, 78 - .cra_module = THIS_MODULE, 79 - } 80 - }; 81 - 82 - static int __init ppc_md5_mod_init(void) 83 - { 84 - return crypto_register_shash(&alg); 85 - } 86 - 87 - static void __exit ppc_md5_mod_fini(void) 88 - { 89 - crypto_unregister_shash(&alg); 90 - } 91 - 92 - module_init(ppc_md5_mod_init); 93 - module_exit(ppc_md5_mod_fini); 94 - 95 - MODULE_LICENSE("GPL"); 96 - MODULE_DESCRIPTION("MD5 Secure Hash Algorithm, PPC assembler"); 97 - 98 - MODULE_ALIAS_CRYPTO("md5"); 99 - MODULE_ALIAS_CRYPTO("md5-ppc");
+1
lib/crypto/Kconfig
··· 111 111 bool 112 112 depends on CRYPTO_LIB_MD5 && !UML 113 113 default y if MIPS && CPU_CAVIUM_OCTEON 114 + default y if PPC 114 115 115 116 config CRYPTO_LIB_POLY1305_RSIZE 116 117 int
+1
lib/crypto/Makefile
··· 65 65 libmd5-y := md5.o 66 66 ifeq ($(CONFIG_CRYPTO_LIB_MD5_ARCH),y) 67 67 CFLAGS_md5.o += -I$(src)/$(SRCARCH) 68 + libmd5-$(CONFIG_PPC) += powerpc/md5-asm.o 68 69 endif # CONFIG_CRYPTO_LIB_MD5_ARCH 69 70 70 71 ################################################################################
+12
lib/crypto/powerpc/md5.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * MD5 optimized for PowerPC 4 + */ 5 + 6 + void ppc_md5_transform(u32 *state, const u8 *data, size_t nblocks); 7 + 8 + static void md5_blocks(struct md5_block_state *state, 9 + const u8 *data, size_t nblocks) 10 + { 11 + ppc_md5_transform(state->h, data, nblocks); 12 + }