Blame view
crypto/md4.c
6.16 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
/* * Cryptographic API. * * MD4 Message Digest Algorithm (RFC1320). * * Implementation derived from Andrew Tridgell and Steve French's * CIFS MD4 implementation, and the cryptoapi implementation * originally based on the public domain implementation written * by Colin Plumb in 1993. * * Copyright (c) Andrew Tridgell 1997-1998. * Modified by Steve French (sfrench@us.ibm.com) 2002 * Copyright (c) Cryptoapi developers. * Copyright (c) 2002 David S. Miller (davem@redhat.com) * 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. * */ |
808a1763c crypto: md4 - Swi... |
23 |
#include <crypto/internal/hash.h> |
1da177e4c Linux-2.6.12-rc2 |
24 |
#include <linux/init.h> |
1da177e4c Linux-2.6.12-rc2 |
25 |
#include <linux/kernel.h> |
4bb33cc89 crypto: add modul... |
26 |
#include <linux/module.h> |
1da177e4c Linux-2.6.12-rc2 |
27 |
#include <linux/string.h> |
06ace7a9b [CRYPTO] Use stan... |
28 |
#include <linux/types.h> |
1da177e4c Linux-2.6.12-rc2 |
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#include <asm/byteorder.h> #define MD4_DIGEST_SIZE 16 #define MD4_HMAC_BLOCK_SIZE 64 #define MD4_BLOCK_WORDS 16 #define MD4_HASH_WORDS 4 struct md4_ctx { u32 hash[MD4_HASH_WORDS]; u32 block[MD4_BLOCK_WORDS]; u64 byte_count; }; static inline u32 lshift(u32 x, unsigned int s) { x &= 0xFFFFFFFF; return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); } static inline u32 F(u32 x, u32 y, u32 z) { return (x & y) | ((~x) & z); } static inline u32 G(u32 x, u32 y, u32 z) { return (x & y) | (x & z) | (y & z); } static inline u32 H(u32 x, u32 y, u32 z) { return x ^ y ^ z; } |
808a1763c crypto: md4 - Swi... |
62 |
|
1da177e4c Linux-2.6.12-rc2 |
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 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s)) #define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (u32)0x5A827999,s)) #define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (u32)0x6ED9EBA1,s)) /* 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++; } } static void md4_transform(u32 *hash, u32 const *in) { u32 a, b, c, d; a = hash[0]; b = hash[1]; c = hash[2]; d = hash[3]; ROUND1(a, b, c, d, in[0], 3); ROUND1(d, a, b, c, in[1], 7); ROUND1(c, d, a, b, in[2], 11); ROUND1(b, c, d, a, in[3], 19); ROUND1(a, b, c, d, in[4], 3); ROUND1(d, a, b, c, in[5], 7); ROUND1(c, d, a, b, in[6], 11); ROUND1(b, c, d, a, in[7], 19); ROUND1(a, b, c, d, in[8], 3); ROUND1(d, a, b, c, in[9], 7); ROUND1(c, d, a, b, in[10], 11); ROUND1(b, c, d, a, in[11], 19); ROUND1(a, b, c, d, in[12], 3); ROUND1(d, a, b, c, in[13], 7); ROUND1(c, d, a, b, in[14], 11); ROUND1(b, c, d, a, in[15], 19); ROUND2(a, b, c, d,in[ 0], 3); ROUND2(d, a, b, c, in[4], 5); ROUND2(c, d, a, b, in[8], 9); ROUND2(b, c, d, a, in[12], 13); ROUND2(a, b, c, d, in[1], 3); ROUND2(d, a, b, c, in[5], 5); ROUND2(c, d, a, b, in[9], 9); ROUND2(b, c, d, a, in[13], 13); ROUND2(a, b, c, d, in[2], 3); ROUND2(d, a, b, c, in[6], 5); ROUND2(c, d, a, b, in[10], 9); ROUND2(b, c, d, a, in[14], 13); ROUND2(a, b, c, d, in[3], 3); ROUND2(d, a, b, c, in[7], 5); ROUND2(c, d, a, b, in[11], 9); ROUND2(b, c, d, a, in[15], 13); ROUND3(a, b, c, d,in[ 0], 3); ROUND3(d, a, b, c, in[8], 9); ROUND3(c, d, a, b, in[4], 11); ROUND3(b, c, d, a, in[12], 15); ROUND3(a, b, c, d, in[2], 3); ROUND3(d, a, b, c, in[10], 9); ROUND3(c, d, a, b, in[6], 11); ROUND3(b, c, d, a, in[14], 15); ROUND3(a, b, c, d, in[1], 3); ROUND3(d, a, b, c, in[9], 9); ROUND3(c, d, a, b, in[5], 11); ROUND3(b, c, d, a, in[13], 15); ROUND3(a, b, c, d, in[3], 3); ROUND3(d, a, b, c, in[11], 9); ROUND3(c, d, a, b, in[7], 11); ROUND3(b, c, d, a, in[15], 15); hash[0] += a; hash[1] += b; hash[2] += c; hash[3] += d; } static inline void md4_transform_helper(struct md4_ctx *ctx) { |
31a61bfc6 crypto: md4 - Use... |
152 |
le32_to_cpu_array(ctx->block, ARRAY_SIZE(ctx->block)); |
1da177e4c Linux-2.6.12-rc2 |
153 154 |
md4_transform(ctx->hash, ctx->block); } |
808a1763c crypto: md4 - Swi... |
155 |
static int md4_init(struct shash_desc *desc) |
1da177e4c Linux-2.6.12-rc2 |
156 |
{ |
808a1763c crypto: md4 - Swi... |
157 |
struct md4_ctx *mctx = shash_desc_ctx(desc); |
1da177e4c Linux-2.6.12-rc2 |
158 159 160 161 162 163 |
mctx->hash[0] = 0x67452301; mctx->hash[1] = 0xefcdab89; mctx->hash[2] = 0x98badcfe; mctx->hash[3] = 0x10325476; mctx->byte_count = 0; |
808a1763c crypto: md4 - Swi... |
164 165 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
166 |
} |
808a1763c crypto: md4 - Swi... |
167 |
static int md4_update(struct shash_desc *desc, const u8 *data, unsigned int len) |
1da177e4c Linux-2.6.12-rc2 |
168 |
{ |
808a1763c crypto: md4 - Swi... |
169 |
struct md4_ctx *mctx = shash_desc_ctx(desc); |
1da177e4c Linux-2.6.12-rc2 |
170 171 172 173 174 175 176 |
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); |
808a1763c crypto: md4 - Swi... |
177 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
} memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), data, avail); md4_transform_helper(mctx); data += avail; len -= avail; while (len >= sizeof(mctx->block)) { memcpy(mctx->block, data, sizeof(mctx->block)); md4_transform_helper(mctx); data += sizeof(mctx->block); len -= sizeof(mctx->block); } memcpy(mctx->block, data, len); |
808a1763c crypto: md4 - Swi... |
195 196 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
197 |
} |
808a1763c crypto: md4 - Swi... |
198 |
static int md4_final(struct shash_desc *desc, u8 *out) |
1da177e4c Linux-2.6.12-rc2 |
199 |
{ |
808a1763c crypto: md4 - Swi... |
200 |
struct md4_ctx *mctx = shash_desc_ctx(desc); |
1da177e4c Linux-2.6.12-rc2 |
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
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)); md4_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)); md4_transform(mctx->hash, mctx->block); |
31a61bfc6 crypto: md4 - Use... |
219 |
cpu_to_le32_array(mctx->hash, ARRAY_SIZE(mctx->hash)); |
1da177e4c Linux-2.6.12-rc2 |
220 221 |
memcpy(out, mctx->hash, sizeof(mctx->hash)); memset(mctx, 0, sizeof(*mctx)); |
808a1763c crypto: md4 - Swi... |
222 223 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
224 |
} |
808a1763c crypto: md4 - Swi... |
225 226 227 228 229 230 231 232 233 234 235 236 |
static struct shash_alg alg = { .digestsize = MD4_DIGEST_SIZE, .init = md4_init, .update = md4_update, .final = md4_final, .descsize = sizeof(struct md4_ctx), .base = { .cra_name = "md4", .cra_flags = CRYPTO_ALG_TYPE_SHASH, .cra_blocksize = MD4_HMAC_BLOCK_SIZE, .cra_module = THIS_MODULE, } |
1da177e4c Linux-2.6.12-rc2 |
237 |
}; |
3af5b90bd [CRYPTO] all: Cle... |
238 |
static int __init md4_mod_init(void) |
1da177e4c Linux-2.6.12-rc2 |
239 |
{ |
808a1763c crypto: md4 - Swi... |
240 |
return crypto_register_shash(&alg); |
1da177e4c Linux-2.6.12-rc2 |
241 |
} |
3af5b90bd [CRYPTO] all: Cle... |
242 |
static void __exit md4_mod_fini(void) |
1da177e4c Linux-2.6.12-rc2 |
243 |
{ |
808a1763c crypto: md4 - Swi... |
244 |
crypto_unregister_shash(&alg); |
1da177e4c Linux-2.6.12-rc2 |
245 |
} |
3af5b90bd [CRYPTO] all: Cle... |
246 247 |
module_init(md4_mod_init); module_exit(md4_mod_fini); |
1da177e4c Linux-2.6.12-rc2 |
248 249 250 |
MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MD4 Message Digest Algorithm"); |