1 /* 1 2 * Cryptographic API. 3 * 4 * MD5 Message Digest Algorithm (RFC1321). 5 * 6 * Derived from cryptoapi implementation, orig 7 * public domain implementation written by Col 8 * 9 * Copyright (c) Cryptoapi developers. 10 * Copyright (c) 2002 James Morris <jmorris@in 11 * 12 * This program is free software; you can redi 13 * under the terms of the GNU General Public L 14 * Software Foundation; either version 2 of th 15 * any later version. 16 * 17 */ 18 #include <crypto/internal/hash.h> 19 #include <crypto/md5.h> 20 #include <linux/init.h> 21 #include <linux/module.h> 22 #include <linux/string.h> 23 #include <linux/types.h> 24 #include <asm/byteorder.h> 25 26 const u8 md5_zero_message_hash[MD5_DIGEST_SIZE 27 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0x 28 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x 29 }; 30 EXPORT_SYMBOL_GPL(md5_zero_message_hash); 31 32 #define F1(x, y, z) (z ^ (x & (y ^ z))) 33 #define F2(x, y, z) F1(z, x, y) 34 #define F3(x, y, z) (x ^ y ^ z) 35 #define F4(x, y, z) (y ^ (x | ~z)) 36 37 #define MD5STEP(f, w, x, y, z, in, s) \ 38 (w += f(x, y, z) + in, w = (w<<s | w>> 39 40 static void md5_transform(__u32 *hash, __u32 c 41 { 42 u32 a, b, c, d; 43 44 a = hash[0]; 45 b = hash[1]; 46 c = hash[2]; 47 d = hash[3]; 48 49 MD5STEP(F1, a, b, c, d, in[0] + 0xd76a 50 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7 51 MD5STEP(F1, c, d, a, b, in[2] + 0x2420 52 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bd 53 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c 54 MD5STEP(F1, d, a, b, c, in[5] + 0x4787 55 MD5STEP(F1, c, d, a, b, in[6] + 0xa830 56 MD5STEP(F1, b, c, d, a, in[7] + 0xfd46 57 MD5STEP(F1, a, b, c, d, in[8] + 0x6980 58 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44 59 MD5STEP(F1, c, d, a, b, in[10] + 0xfff 60 MD5STEP(F1, b, c, d, a, in[11] + 0x895 61 MD5STEP(F1, a, b, c, d, in[12] + 0x6b9 62 MD5STEP(F1, d, a, b, c, in[13] + 0xfd9 63 MD5STEP(F1, c, d, a, b, in[14] + 0xa67 64 MD5STEP(F1, b, c, d, a, in[15] + 0x49b 65 66 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e 67 MD5STEP(F2, d, a, b, c, in[6] + 0xc040 68 MD5STEP(F2, c, d, a, b, in[11] + 0x265 69 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6 70 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f 71 MD5STEP(F2, d, a, b, c, in[10] + 0x024 72 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a 73 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3 74 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1 75 MD5STEP(F2, d, a, b, c, in[14] + 0xc33 76 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d5 77 MD5STEP(F2, b, c, d, a, in[8] + 0x455a 78 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e 79 MD5STEP(F2, d, a, b, c, in[2] + 0xfcef 80 MD5STEP(F2, c, d, a, b, in[7] + 0x676f 81 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2 82 83 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa 84 MD5STEP(F3, d, a, b, c, in[8] + 0x8771 85 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9 86 MD5STEP(F3, b, c, d, a, in[14] + 0xfde 87 MD5STEP(F3, a, b, c, d, in[1] + 0xa4be 88 MD5STEP(F3, d, a, b, c, in[4] + 0x4bde 89 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb 90 MD5STEP(F3, b, c, d, a, in[10] + 0xbeb 91 MD5STEP(F3, a, b, c, d, in[13] + 0x289 92 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa1 93 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef 94 MD5STEP(F3, b, c, d, a, in[6] + 0x0488 95 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4 96 MD5STEP(F3, d, a, b, c, in[12] + 0xe6d 97 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa 98 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac 99 100 MD5STEP(F4, a, b, c, d, in[0] + 0xf429 101 MD5STEP(F4, d, a, b, c, in[7] + 0x432a 102 MD5STEP(F4, c, d, a, b, in[14] + 0xab9 103 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93 104 MD5STEP(F4, a, b, c, d, in[12] + 0x655 105 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0c 106 MD5STEP(F4, c, d, a, b, in[10] + 0xffe 107 MD5STEP(F4, b, c, d, a, in[1] + 0x8584 108 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa8 109 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2 110 MD5STEP(F4, c, d, a, b, in[6] + 0xa301 111 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0 112 MD5STEP(F4, a, b, c, d, in[4] + 0xf753 113 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3 114 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7 115 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86 116 117 hash[0] += a; 118 hash[1] += b; 119 hash[2] += c; 120 hash[3] += d; 121 } 122 123 static inline void md5_transform_helper(struct 124 { 125 le32_to_cpu_array(ctx->block, sizeof(c 126 md5_transform(ctx->hash, ctx->block); 127 } 128 129 static int md5_init(struct shash_desc *desc) 130 { 131 struct md5_state *mctx = shash_desc_ct 132 133 mctx->hash[0] = MD5_H0; 134 mctx->hash[1] = MD5_H1; 135 mctx->hash[2] = MD5_H2; 136 mctx->hash[3] = MD5_H3; 137 mctx->byte_count = 0; 138 139 return 0; 140 } 141 142 static int md5_update(struct shash_desc *desc, 143 { 144 struct md5_state *mctx = shash_desc_ct 145 const u32 avail = sizeof(mctx->block) 146 147 mctx->byte_count += len; 148 149 if (avail > len) { 150 memcpy((char *)mctx->block + ( 151 data, len); 152 return 0; 153 } 154 155 memcpy((char *)mctx->block + (sizeof(m 156 data, avail); 157 158 md5_transform_helper(mctx); 159 data += avail; 160 len -= avail; 161 162 while (len >= sizeof(mctx->block)) { 163 memcpy(mctx->block, data, size 164 md5_transform_helper(mctx); 165 data += sizeof(mctx->block); 166 len -= sizeof(mctx->block); 167 } 168 169 memcpy(mctx->block, data, len); 170 171 return 0; 172 } 173 174 static int md5_final(struct shash_desc *desc, 175 { 176 struct md5_state *mctx = shash_desc_ct 177 const unsigned int offset = mctx->byte 178 char *p = (char *)mctx->block + offset 179 int padding = 56 - (offset + 1); 180 181 *p++ = 0x80; 182 if (padding < 0) { 183 memset(p, 0x00, padding + size 184 md5_transform_helper(mctx); 185 p = (char *)mctx->block; 186 padding = 56; 187 } 188 189 memset(p, 0, padding); 190 mctx->block[14] = mctx->byte_count << 191 mctx->block[15] = mctx->byte_count >> 192 le32_to_cpu_array(mctx->block, (sizeof 193 sizeof(u64)) / sizeo 194 md5_transform(mctx->hash, mctx->block) 195 cpu_to_le32_array(mctx->hash, sizeof(m 196 memcpy(out, mctx->hash, sizeof(mctx->h 197 memset(mctx, 0, sizeof(*mctx)); 198 199 return 0; 200 } 201 202 static int md5_export(struct shash_desc *desc, 203 { 204 struct md5_state *ctx = shash_desc_ctx 205 206 memcpy(out, ctx, sizeof(*ctx)); 207 return 0; 208 } 209 210 static int md5_import(struct shash_desc *desc, 211 { 212 struct md5_state *ctx = shash_desc_ctx 213 214 memcpy(ctx, in, sizeof(*ctx)); 215 return 0; 216 } 217 218 static struct shash_alg alg = { 219 .digestsize = MD5_DIGEST_SIZ 220 .init = md5_init, 221 .update = md5_update, 222 .final = md5_final, 223 .export = md5_export, 224 .import = md5_import, 225 .descsize = sizeof(struct 226 .statesize = sizeof(struct 227 .base = { 228 .cra_name = "md5", 229 .cra_driver_name = "md5-g 230 .cra_blocksize = MD5_HM 231 .cra_module = THIS_M 232 } 233 }; 234 235 static int __init md5_mod_init(void) 236 { 237 return crypto_register_shash(&alg); 238 } 239 240 static void __exit md5_mod_fini(void) 241 { 242 crypto_unregister_shash(&alg); 243 } 244 245 subsys_initcall(md5_mod_init); 246 module_exit(md5_mod_fini); 247 248 MODULE_LICENSE("GPL"); 249 MODULE_DESCRIPTION("MD5 Message Digest Algorit 250 MODULE_ALIAS_CRYPTO("md5"); 251
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.