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

Configure Feed

Select the types of activity you want to include in your feed.

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

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

Note: to see the diff from arch/mips/cavium-octeon/crypto/octeon-md5.c
to lib/crypto/mips/md5.h, view this commit with 'git show -M10'.

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

+66 -227
-2
arch/mips/cavium-octeon/crypto/Makefile
··· 4 4 # 5 5 6 6 obj-y += octeon-crypto.o 7 - 8 - obj-$(CONFIG_CRYPTO_MD5_OCTEON) += octeon-md5.o
-214
arch/mips/cavium-octeon/crypto/octeon-md5.c
··· 1 - /* 2 - * Cryptographic API. 3 - * 4 - * MD5 Message Digest Algorithm (RFC1321). 5 - * 6 - * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>. 7 - * 8 - * Based on crypto/md5.c, which is: 9 - * 10 - * Derived from cryptoapi implementation, originally based on the 11 - * public domain implementation written by Colin Plumb in 1993. 12 - * 13 - * Copyright (c) Cryptoapi developers. 14 - * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 15 - * 16 - * This program is free software; you can redistribute it and/or modify it 17 - * under the terms of the GNU General Public License as published by the Free 18 - * Software Foundation; either version 2 of the License, or (at your option) 19 - * any later version. 20 - */ 21 - 22 - #include <asm/octeon/crypto.h> 23 - #include <asm/octeon/octeon.h> 24 - #include <crypto/internal/hash.h> 25 - #include <crypto/md5.h> 26 - #include <linux/kernel.h> 27 - #include <linux/module.h> 28 - #include <linux/string.h> 29 - #include <linux/unaligned.h> 30 - 31 - struct octeon_md5_state { 32 - __le32 hash[MD5_HASH_WORDS]; 33 - u64 byte_count; 34 - }; 35 - 36 - /* 37 - * We pass everything as 64-bit. OCTEON can handle misaligned data. 38 - */ 39 - 40 - static void octeon_md5_store_hash(struct octeon_md5_state *ctx) 41 - { 42 - u64 *hash = (u64 *)ctx->hash; 43 - 44 - write_octeon_64bit_hash_dword(hash[0], 0); 45 - write_octeon_64bit_hash_dword(hash[1], 1); 46 - } 47 - 48 - static void octeon_md5_read_hash(struct octeon_md5_state *ctx) 49 - { 50 - u64 *hash = (u64 *)ctx->hash; 51 - 52 - hash[0] = read_octeon_64bit_hash_dword(0); 53 - hash[1] = read_octeon_64bit_hash_dword(1); 54 - } 55 - 56 - static void octeon_md5_transform(const void *_block) 57 - { 58 - const u64 *block = _block; 59 - 60 - write_octeon_64bit_block_dword(block[0], 0); 61 - write_octeon_64bit_block_dword(block[1], 1); 62 - write_octeon_64bit_block_dword(block[2], 2); 63 - write_octeon_64bit_block_dword(block[3], 3); 64 - write_octeon_64bit_block_dword(block[4], 4); 65 - write_octeon_64bit_block_dword(block[5], 5); 66 - write_octeon_64bit_block_dword(block[6], 6); 67 - octeon_md5_start(block[7]); 68 - } 69 - 70 - static int octeon_md5_init(struct shash_desc *desc) 71 - { 72 - struct octeon_md5_state *mctx = shash_desc_ctx(desc); 73 - 74 - mctx->hash[0] = cpu_to_le32(MD5_H0); 75 - mctx->hash[1] = cpu_to_le32(MD5_H1); 76 - mctx->hash[2] = cpu_to_le32(MD5_H2); 77 - mctx->hash[3] = cpu_to_le32(MD5_H3); 78 - mctx->byte_count = 0; 79 - 80 - return 0; 81 - } 82 - 83 - static int octeon_md5_update(struct shash_desc *desc, const u8 *data, 84 - unsigned int len) 85 - { 86 - struct octeon_md5_state *mctx = shash_desc_ctx(desc); 87 - struct octeon_cop2_state state; 88 - unsigned long flags; 89 - 90 - mctx->byte_count += len; 91 - flags = octeon_crypto_enable(&state); 92 - octeon_md5_store_hash(mctx); 93 - 94 - do { 95 - octeon_md5_transform(data); 96 - data += MD5_HMAC_BLOCK_SIZE; 97 - len -= MD5_HMAC_BLOCK_SIZE; 98 - } while (len >= MD5_HMAC_BLOCK_SIZE); 99 - 100 - octeon_md5_read_hash(mctx); 101 - octeon_crypto_disable(&state, flags); 102 - mctx->byte_count -= len; 103 - return len; 104 - } 105 - 106 - static int octeon_md5_finup(struct shash_desc *desc, const u8 *src, 107 - unsigned int offset, u8 *out) 108 - { 109 - struct octeon_md5_state *mctx = shash_desc_ctx(desc); 110 - int padding = 56 - (offset + 1); 111 - struct octeon_cop2_state state; 112 - u32 block[MD5_BLOCK_WORDS]; 113 - unsigned long flags; 114 - char *p; 115 - 116 - p = memcpy(block, src, offset); 117 - p += offset; 118 - *p++ = 0x80; 119 - 120 - flags = octeon_crypto_enable(&state); 121 - octeon_md5_store_hash(mctx); 122 - 123 - if (padding < 0) { 124 - memset(p, 0x00, padding + sizeof(u64)); 125 - octeon_md5_transform(block); 126 - p = (char *)block; 127 - padding = 56; 128 - } 129 - 130 - memset(p, 0, padding); 131 - mctx->byte_count += offset; 132 - block[14] = mctx->byte_count << 3; 133 - block[15] = mctx->byte_count >> 29; 134 - cpu_to_le32_array(block + 14, 2); 135 - octeon_md5_transform(block); 136 - 137 - octeon_md5_read_hash(mctx); 138 - octeon_crypto_disable(&state, flags); 139 - 140 - memzero_explicit(block, sizeof(block)); 141 - memcpy(out, mctx->hash, sizeof(mctx->hash)); 142 - 143 - return 0; 144 - } 145 - 146 - static int octeon_md5_export(struct shash_desc *desc, void *out) 147 - { 148 - struct octeon_md5_state *ctx = shash_desc_ctx(desc); 149 - union { 150 - u8 *u8; 151 - u32 *u32; 152 - u64 *u64; 153 - } p = { .u8 = out }; 154 - int i; 155 - 156 - for (i = 0; i < MD5_HASH_WORDS; i++) 157 - put_unaligned(le32_to_cpu(ctx->hash[i]), p.u32++); 158 - put_unaligned(ctx->byte_count, p.u64); 159 - return 0; 160 - } 161 - 162 - static int octeon_md5_import(struct shash_desc *desc, const void *in) 163 - { 164 - struct octeon_md5_state *ctx = shash_desc_ctx(desc); 165 - union { 166 - const u8 *u8; 167 - const u32 *u32; 168 - const u64 *u64; 169 - } p = { .u8 = in }; 170 - int i; 171 - 172 - for (i = 0; i < MD5_HASH_WORDS; i++) 173 - ctx->hash[i] = cpu_to_le32(get_unaligned(p.u32++)); 174 - ctx->byte_count = get_unaligned(p.u64); 175 - return 0; 176 - } 177 - 178 - static struct shash_alg alg = { 179 - .digestsize = MD5_DIGEST_SIZE, 180 - .init = octeon_md5_init, 181 - .update = octeon_md5_update, 182 - .finup = octeon_md5_finup, 183 - .export = octeon_md5_export, 184 - .import = octeon_md5_import, 185 - .statesize = MD5_STATE_SIZE, 186 - .descsize = sizeof(struct octeon_md5_state), 187 - .base = { 188 - .cra_name = "md5", 189 - .cra_driver_name= "octeon-md5", 190 - .cra_priority = OCTEON_CR_OPCODE_PRIORITY, 191 - .cra_flags = CRYPTO_AHASH_ALG_BLOCK_ONLY, 192 - .cra_blocksize = MD5_HMAC_BLOCK_SIZE, 193 - .cra_module = THIS_MODULE, 194 - } 195 - }; 196 - 197 - static int __init md5_mod_init(void) 198 - { 199 - if (!octeon_has_crypto()) 200 - return -ENOTSUPP; 201 - return crypto_register_shash(&alg); 202 - } 203 - 204 - static void __exit md5_mod_fini(void) 205 - { 206 - crypto_unregister_shash(&alg); 207 - } 208 - 209 - module_init(md5_mod_init); 210 - module_exit(md5_mod_fini); 211 - 212 - MODULE_LICENSE("GPL"); 213 - MODULE_DESCRIPTION("MD5 Message Digest Algorithm (OCTEON)"); 214 - MODULE_AUTHOR("Aaro Koskinen <aaro.koskinen@iki.fi>");
-1
arch/mips/configs/cavium_octeon_defconfig
··· 155 155 CONFIG_SECURITY_NETWORK=y 156 156 CONFIG_CRYPTO_CBC=y 157 157 CONFIG_CRYPTO_HMAC=y 158 - CONFIG_CRYPTO_MD5_OCTEON=y 159 158 CONFIG_CRYPTO_DES=y 160 159 CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y 161 160 CONFIG_DEBUG_FS=y
-10
arch/mips/crypto/Kconfig
··· 2 2 3 3 menu "Accelerated Cryptographic Algorithms for CPU (mips)" 4 4 5 - config CRYPTO_MD5_OCTEON 6 - tristate "Digests: MD5 (OCTEON)" 7 - depends on CPU_CAVIUM_OCTEON 8 - select CRYPTO_MD5 9 - select CRYPTO_HASH 10 - help 11 - MD5 message digest algorithm (RFC1321) 12 - 13 - Architecture: mips OCTEON using crypto instructions, when available 14 - 15 5 endmenu
+1
lib/crypto/Kconfig
··· 110 110 config CRYPTO_LIB_MD5_ARCH 111 111 bool 112 112 depends on CRYPTO_LIB_MD5 && !UML 113 + default y if MIPS && CPU_CAVIUM_OCTEON 113 114 114 115 config CRYPTO_LIB_POLY1305_RSIZE 115 116 int
+65
lib/crypto/mips/md5.h
··· 1 + /* 2 + * Cryptographic API. 3 + * 4 + * MD5 Message Digest Algorithm (RFC1321). 5 + * 6 + * Adapted for OCTEON by Aaro Koskinen <aaro.koskinen@iki.fi>. 7 + * 8 + * Based on crypto/md5.c, which is: 9 + * 10 + * Derived from cryptoapi implementation, originally based on the 11 + * public domain implementation written by Colin Plumb in 1993. 12 + * 13 + * Copyright (c) Cryptoapi developers. 14 + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au> 15 + * 16 + * This program is free software; you can redistribute it and/or modify it 17 + * under the terms of the GNU General Public License as published by the Free 18 + * Software Foundation; either version 2 of the License, or (at your option) 19 + * any later version. 20 + */ 21 + 22 + #include <asm/octeon/crypto.h> 23 + #include <asm/octeon/octeon.h> 24 + 25 + /* 26 + * We pass everything as 64-bit. OCTEON can handle misaligned data. 27 + */ 28 + 29 + static void md5_blocks(struct md5_block_state *state, 30 + const u8 *data, size_t nblocks) 31 + { 32 + struct octeon_cop2_state cop2_state; 33 + u64 *state64 = (u64 *)state; 34 + unsigned long flags; 35 + 36 + if (!octeon_has_crypto()) 37 + return md5_blocks_generic(state, data, nblocks); 38 + 39 + cpu_to_le32_array(state->h, ARRAY_SIZE(state->h)); 40 + 41 + flags = octeon_crypto_enable(&cop2_state); 42 + write_octeon_64bit_hash_dword(state64[0], 0); 43 + write_octeon_64bit_hash_dword(state64[1], 1); 44 + 45 + do { 46 + const u64 *block = (const u64 *)data; 47 + 48 + write_octeon_64bit_block_dword(block[0], 0); 49 + write_octeon_64bit_block_dword(block[1], 1); 50 + write_octeon_64bit_block_dword(block[2], 2); 51 + write_octeon_64bit_block_dword(block[3], 3); 52 + write_octeon_64bit_block_dword(block[4], 4); 53 + write_octeon_64bit_block_dword(block[5], 5); 54 + write_octeon_64bit_block_dword(block[6], 6); 55 + octeon_md5_start(block[7]); 56 + 57 + data += MD5_BLOCK_SIZE; 58 + } while (--nblocks); 59 + 60 + state64[0] = read_octeon_64bit_hash_dword(0); 61 + state64[1] = read_octeon_64bit_hash_dword(1); 62 + octeon_crypto_disable(&cop2_state, flags); 63 + 64 + le32_to_cpu_array(state->h, ARRAY_SIZE(state->h)); 65 + }