Blame view
crypto/md5.c
7.72 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/* * 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 <jmorris@intercode.com.au> * * 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 Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * */ |
14b75ba70 crypto: md5 - Swi... |
18 |
#include <crypto/internal/hash.h> |
7d6f75eb2 crypto: md5 - Add... |
19 |
#include <crypto/md5.h> |
1da177e4c Linux-2.6.12-rc2 |
20 21 22 |
#include <linux/init.h> #include <linux/module.h> #include <linux/string.h> |
06ace7a9b [CRYPTO] Use stan... |
23 |
#include <linux/types.h> |
1da177e4c Linux-2.6.12-rc2 |
24 |
#include <asm/byteorder.h> |
3c7eb3cc8 md5: remove from ... |
25 26 |
#define MD5_DIGEST_WORDS 4 #define MD5_MESSAGE_BYTES 64 |
0c4c78de0 crypto: hash - ad... |
27 28 29 30 31 |
const u8 md5_zero_message_hash[MD5_DIGEST_SIZE] = { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e, }; EXPORT_SYMBOL_GPL(md5_zero_message_hash); |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
/* XXX: this stuff can be optimized */ static inline void le32_to_cpu_array(u32 *buf, unsigned int words) { while (words--) { __le32_to_cpus(buf); buf++; } } static inline void cpu_to_le32_array(u32 *buf, unsigned int words) { while (words--) { __cpu_to_le32s(buf); buf++; } } |
3c7eb3cc8 md5: remove from ... |
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
#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 += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x) static void md5_transform(__u32 *hash, __u32 const *in) { u32 a, b, c, d; a = hash[0]; b = hash[1]; c = hash[2]; d = 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] += a; hash[1] += b; hash[2] += c; hash[3] += d; } |
7d6f75eb2 crypto: md5 - Add... |
138 |
static inline void md5_transform_helper(struct md5_state *ctx) |
1da177e4c Linux-2.6.12-rc2 |
139 140 141 142 |
{ le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(u32)); md5_transform(ctx->hash, ctx->block); } |
14b75ba70 crypto: md5 - Swi... |
143 |
static int md5_init(struct shash_desc *desc) |
1da177e4c Linux-2.6.12-rc2 |
144 |
{ |
7d6f75eb2 crypto: md5 - Add... |
145 |
struct md5_state *mctx = shash_desc_ctx(desc); |
1da177e4c Linux-2.6.12-rc2 |
146 |
|
6a185016f crypto: md5 - use... |
147 148 149 150 |
mctx->hash[0] = MD5_H0; mctx->hash[1] = MD5_H1; mctx->hash[2] = MD5_H2; mctx->hash[3] = MD5_H3; |
1da177e4c Linux-2.6.12-rc2 |
151 |
mctx->byte_count = 0; |
14b75ba70 crypto: md5 - Swi... |
152 153 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
154 |
} |
14b75ba70 crypto: md5 - Swi... |
155 |
static int md5_update(struct shash_desc *desc, const u8 *data, unsigned int len) |
1da177e4c Linux-2.6.12-rc2 |
156 |
{ |
7d6f75eb2 crypto: md5 - Add... |
157 |
struct md5_state *mctx = shash_desc_ctx(desc); |
1da177e4c Linux-2.6.12-rc2 |
158 159 160 161 162 163 164 |
const u32 avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); mctx->byte_count += len; if (avail > len) { memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, len); |
14b75ba70 crypto: md5 - Swi... |
165 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
} memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, avail); md5_transform_helper(mctx); data += avail; len -= avail; while (len >= sizeof(mctx->block)) { memcpy(mctx->block, data, sizeof(mctx->block)); md5_transform_helper(mctx); data += sizeof(mctx->block); len -= sizeof(mctx->block); } memcpy(mctx->block, data, len); |
14b75ba70 crypto: md5 - Swi... |
183 184 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
185 |
} |
14b75ba70 crypto: md5 - Swi... |
186 |
static int md5_final(struct shash_desc *desc, u8 *out) |
1da177e4c Linux-2.6.12-rc2 |
187 |
{ |
7d6f75eb2 crypto: md5 - Add... |
188 |
struct md5_state *mctx = shash_desc_ctx(desc); |
1da177e4c Linux-2.6.12-rc2 |
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
const unsigned int offset = mctx->byte_count & 0x3f; char *p = (char *)mctx->block + offset; int padding = 56 - (offset + 1); *p++ = 0x80; if (padding < 0) { memset(p, 0x00, padding + sizeof (u64)); md5_transform_helper(mctx); p = (char *)mctx->block; padding = 56; } memset(p, 0, padding); mctx->block[14] = mctx->byte_count << 3; mctx->block[15] = mctx->byte_count >> 29; le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - sizeof(u64)) / sizeof(u32)); md5_transform(mctx->hash, mctx->block); cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32)); memcpy(out, mctx->hash, sizeof(mctx->hash)); memset(mctx, 0, sizeof(*mctx)); |
14b75ba70 crypto: md5 - Swi... |
210 211 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
212 |
} |
7d6f75eb2 crypto: md5 - Add... |
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
static int md5_export(struct shash_desc *desc, void *out) { struct md5_state *ctx = shash_desc_ctx(desc); memcpy(out, ctx, sizeof(*ctx)); return 0; } static int md5_import(struct shash_desc *desc, const void *in) { struct md5_state *ctx = shash_desc_ctx(desc); memcpy(ctx, in, sizeof(*ctx)); return 0; } |
14b75ba70 crypto: md5 - Swi... |
228 229 230 231 232 |
static struct shash_alg alg = { .digestsize = MD5_DIGEST_SIZE, .init = md5_init, .update = md5_update, .final = md5_final, |
7d6f75eb2 crypto: md5 - Add... |
233 234 235 |
.export = md5_export, .import = md5_import, .descsize = sizeof(struct md5_state), |
eebb111f5 crypto: md5 - Set... |
236 |
.statesize = sizeof(struct md5_state), |
14b75ba70 crypto: md5 - Swi... |
237 238 239 240 241 242 |
.base = { .cra_name = "md5", .cra_flags = CRYPTO_ALG_TYPE_SHASH, .cra_blocksize = MD5_HMAC_BLOCK_SIZE, .cra_module = THIS_MODULE, } |
1da177e4c Linux-2.6.12-rc2 |
243 |
}; |
3af5b90bd [CRYPTO] all: Cle... |
244 |
static int __init md5_mod_init(void) |
1da177e4c Linux-2.6.12-rc2 |
245 |
{ |
14b75ba70 crypto: md5 - Swi... |
246 |
return crypto_register_shash(&alg); |
1da177e4c Linux-2.6.12-rc2 |
247 |
} |
3af5b90bd [CRYPTO] all: Cle... |
248 |
static void __exit md5_mod_fini(void) |
1da177e4c Linux-2.6.12-rc2 |
249 |
{ |
14b75ba70 crypto: md5 - Swi... |
250 |
crypto_unregister_shash(&alg); |
1da177e4c Linux-2.6.12-rc2 |
251 |
} |
3af5b90bd [CRYPTO] all: Cle... |
252 253 |
module_init(md5_mod_init); module_exit(md5_mod_fini); |
1da177e4c Linux-2.6.12-rc2 |
254 255 256 |
MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MD5 Message Digest Algorithm"); |
5d26a105b crypto: prefix mo... |
257 |
MODULE_ALIAS_CRYPTO("md5"); |