1 // SPDX-License-Identifier: GPL-2.0-only 1 2 /* Glue code for MD5 hashing optimized for spa 3 * 4 * This is based largely upon arch/x86/crypto/ 5 * and crypto/md5.c which are: 6 * 7 * Copyright (c) Alan Smithee. 8 * Copyright (c) Andrew McDonald <andrew@mcdon 9 * Copyright (c) Jean-Francois Dive <jef@linux 10 * Copyright (c) Mathias Krause <minipli@googl 11 * Copyright (c) Cryptoapi developers. 12 * Copyright (c) 2002 James Morris <jmorris@in 13 */ 14 15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fm 16 17 #include <crypto/internal/hash.h> 18 #include <linux/init.h> 19 #include <linux/module.h> 20 #include <linux/mm.h> 21 #include <linux/types.h> 22 #include <crypto/md5.h> 23 24 #include <asm/pstate.h> 25 #include <asm/elf.h> 26 27 #include "opcodes.h" 28 29 asmlinkage void md5_sparc64_transform(u32 *dig 30 unsigned 31 32 static int md5_sparc64_init(struct shash_desc 33 { 34 struct md5_state *mctx = shash_desc_ct 35 36 mctx->hash[0] = MD5_H0; 37 mctx->hash[1] = MD5_H1; 38 mctx->hash[2] = MD5_H2; 39 mctx->hash[3] = MD5_H3; 40 le32_to_cpu_array(mctx->hash, 4); 41 mctx->byte_count = 0; 42 43 return 0; 44 } 45 46 static void __md5_sparc64_update(struct md5_st 47 unsigned int 48 { 49 unsigned int done = 0; 50 51 sctx->byte_count += len; 52 if (partial) { 53 done = MD5_HMAC_BLOCK_SIZE - p 54 memcpy((u8 *)sctx->block + par 55 md5_sparc64_transform(sctx->ha 56 } 57 if (len - done >= MD5_HMAC_BLOCK_SIZE) 58 const unsigned int rounds = (l 59 60 md5_sparc64_transform(sctx->ha 61 done += rounds * MD5_HMAC_BLOC 62 } 63 64 memcpy(sctx->block, data + done, len - 65 } 66 67 static int md5_sparc64_update(struct shash_des 68 unsigned int len 69 { 70 struct md5_state *sctx = shash_desc_ct 71 unsigned int partial = sctx->byte_coun 72 73 /* Handle the fast case right here */ 74 if (partial + len < MD5_HMAC_BLOCK_SIZ 75 sctx->byte_count += len; 76 memcpy((u8 *)sctx->block + par 77 } else 78 __md5_sparc64_update(sctx, dat 79 80 return 0; 81 } 82 83 /* Add padding and return the message digest. 84 static int md5_sparc64_final(struct shash_desc 85 { 86 struct md5_state *sctx = shash_desc_ct 87 unsigned int i, index, padlen; 88 u32 *dst = (u32 *)out; 89 __le64 bits; 90 static const u8 padding[MD5_HMAC_BLOCK 91 92 bits = cpu_to_le64(sctx->byte_count << 93 94 /* Pad out to 56 mod 64 and append len 95 index = sctx->byte_count % MD5_HMAC_BL 96 padlen = (index < 56) ? (56 - index) : 97 98 /* We need to fill a whole block for _ 99 if (padlen <= 56) { 100 sctx->byte_count += padlen; 101 memcpy((u8 *)sctx->block + ind 102 } else { 103 __md5_sparc64_update(sctx, pad 104 } 105 __md5_sparc64_update(sctx, (const u8 * 106 107 /* Store state in digest */ 108 for (i = 0; i < MD5_HASH_WORDS; i++) 109 dst[i] = sctx->hash[i]; 110 111 /* Wipe context */ 112 memset(sctx, 0, sizeof(*sctx)); 113 114 return 0; 115 } 116 117 static int md5_sparc64_export(struct shash_des 118 { 119 struct md5_state *sctx = shash_desc_ct 120 121 memcpy(out, sctx, sizeof(*sctx)); 122 123 return 0; 124 } 125 126 static int md5_sparc64_import(struct shash_des 127 { 128 struct md5_state *sctx = shash_desc_ct 129 130 memcpy(sctx, in, sizeof(*sctx)); 131 132 return 0; 133 } 134 135 static struct shash_alg alg = { 136 .digestsize = MD5_DIGEST_SIZ 137 .init = md5_sparc64_in 138 .update = md5_sparc64_up 139 .final = md5_sparc64_fi 140 .export = md5_sparc64_ex 141 .import = md5_sparc64_im 142 .descsize = sizeof(struct 143 .statesize = sizeof(struct 144 .base = { 145 .cra_name = "md5", 146 .cra_driver_name= "md5-s 147 .cra_priority = SPARC_ 148 .cra_blocksize = MD5_HM 149 .cra_module = THIS_M 150 } 151 }; 152 153 static bool __init sparc64_has_md5_opcode(void 154 { 155 unsigned long cfr; 156 157 if (!(sparc64_elf_hwcap & HWCAP_SPARC_ 158 return false; 159 160 __asm__ __volatile__("rd %%asr26, %0" 161 if (!(cfr & CFR_MD5)) 162 return false; 163 164 return true; 165 } 166 167 static int __init md5_sparc64_mod_init(void) 168 { 169 if (sparc64_has_md5_opcode()) { 170 pr_info("Using sparc64 md5 opc 171 return crypto_register_shash(& 172 } 173 pr_info("sparc64 md5 opcode not availa 174 return -ENODEV; 175 } 176 177 static void __exit md5_sparc64_mod_fini(void) 178 { 179 crypto_unregister_shash(&alg); 180 } 181 182 module_init(md5_sparc64_mod_init); 183 module_exit(md5_sparc64_mod_fini); 184 185 MODULE_LICENSE("GPL"); 186 MODULE_DESCRIPTION("MD5 Message Digest Algorit 187 188 MODULE_ALIAS_CRYPTO("md5"); 189 190 #include "crop_devid.c" 191
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.