diff options
Diffstat (limited to 'linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md4.c')
-rwxr-xr-x | linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md4.c | 327 |
1 files changed, 327 insertions, 0 deletions
diff --git a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md4.c b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md4.c new file mode 100755 index 0000000..8c4504e --- /dev/null +++ b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/md4.c | |||
@@ -0,0 +1,327 @@ | |||
1 | /* md4.c - MD4 Message-Digest Algorithm | ||
2 | * Copyright (C) 2002, 2003 Free Software Foundation, Inc. | ||
3 | * | ||
4 | * This file is part of Libgcrypt. | ||
5 | * | ||
6 | * Libgcrypt is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU Lesser General Public License as | ||
8 | * published by the Free Software Foundation; either version 2.1 of | ||
9 | * the License, or (at your option) any later version. | ||
10 | * | ||
11 | * Libgcrypt is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU Lesser General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU Lesser General Public | ||
17 | * License along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||
19 | * | ||
20 | * Based on md5.c in libgcrypt, but rewritten to compute md4 checksums | ||
21 | * using a public domain md4 implementation with the following comments: | ||
22 | * | ||
23 | * Modified by Wei Dai from Andrew M. Kuchling's md4.c | ||
24 | * The original code and all modifications are in the public domain. | ||
25 | * | ||
26 | * This is the original introductory comment: | ||
27 | * | ||
28 | * md4.c : MD4 hash algorithm. | ||
29 | * | ||
30 | * Part of the Python Cryptography Toolkit, version 1.1 | ||
31 | * | ||
32 | * Distribute and use freely; there are no restrictions on further | ||
33 | * dissemination and usage except those imposed by the laws of your | ||
34 | * country of residence. | ||
35 | * | ||
36 | */ | ||
37 | |||
38 | /* MD4 test suite: | ||
39 | * MD4 ("") = 31d6cfe0d16ae931b73c59d7e0c089c0 | ||
40 | * MD4 ("a") = bde52cb31de33e46245e05fbdbd6fb24 | ||
41 | * MD4 ("abc") = a448017aaf21d8525fc10ae87aa6729d | ||
42 | * MD4 ("message digest") = d9130a8164549fe818874806e1c7014b | ||
43 | * MD4 ("abcdefghijklmnopqrstuvwxyz") = d79e1c308aa5bbcdeea8ed63df412da9 | ||
44 | * MD4 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") = | ||
45 | * 043f8582f241db351ce627e153e7f0e4 | ||
46 | * MD4 ("123456789012345678901234567890123456789012345678901234567890123456 | ||
47 | * 78901234567890") = e33b4ddc9c38f2199c3e7b164fcc0536 | ||
48 | */ | ||
49 | |||
50 | #include <config.h> | ||
51 | #include <stdio.h> | ||
52 | #include <stdlib.h> | ||
53 | #include <string.h> | ||
54 | #include <assert.h> | ||
55 | #include "g10lib.h" | ||
56 | #include "memory.h" | ||
57 | #include "cipher.h" | ||
58 | |||
59 | #include "bithelp.h" | ||
60 | |||
61 | |||
62 | typedef struct { | ||
63 | u32 A,B,C,D; /* chaining variables */ | ||
64 | u32 nblocks; | ||
65 | byte buf[64]; | ||
66 | int count; | ||
67 | } MD4_CONTEXT; | ||
68 | |||
69 | |||
70 | static void | ||
71 | md4_init( void *context ) | ||
72 | { | ||
73 | MD4_CONTEXT *ctx = context; | ||
74 | |||
75 | ctx->A = 0x67452301; | ||
76 | ctx->B = 0xefcdab89; | ||
77 | ctx->C = 0x98badcfe; | ||
78 | ctx->D = 0x10325476; | ||
79 | |||
80 | ctx->nblocks = 0; | ||
81 | ctx->count = 0; | ||
82 | } | ||
83 | |||
84 | #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) | ||
85 | #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) | ||
86 | #define H(x, y, z) ((x) ^ (y) ^ (z)) | ||
87 | |||
88 | |||
89 | /**************** | ||
90 | * transform 64 bytes | ||
91 | */ | ||
92 | static void | ||
93 | transform( MD4_CONTEXT *ctx, byte *data ) | ||
94 | { | ||
95 | u32 in[16]; | ||
96 | register u32 A = ctx->A; | ||
97 | register u32 B = ctx->B; | ||
98 | register u32 C = ctx->C; | ||
99 | register u32 D = ctx->D; | ||
100 | |||
101 | #ifdef WORDS_BIGENDIAN | ||
102 | { | ||
103 | int i; | ||
104 | byte *p2, *p1; | ||
105 | for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 ) | ||
106 | { | ||
107 | p2[3] = *p1++; | ||
108 | p2[2] = *p1++; | ||
109 | p2[1] = *p1++; | ||
110 | p2[0] = *p1++; | ||
111 | } | ||
112 | } | ||
113 | #else | ||
114 | memcpy (in, data, 64); | ||
115 | #endif | ||
116 | |||
117 | /* Round 1. */ | ||
118 | #define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s); | ||
119 | function(A,B,C,D, 0, 3); | ||
120 | function(D,A,B,C, 1, 7); | ||
121 | function(C,D,A,B, 2,11); | ||
122 | function(B,C,D,A, 3,19); | ||
123 | function(A,B,C,D, 4, 3); | ||
124 | function(D,A,B,C, 5, 7); | ||
125 | function(C,D,A,B, 6,11); | ||
126 | function(B,C,D,A, 7,19); | ||
127 | function(A,B,C,D, 8, 3); | ||
128 | function(D,A,B,C, 9, 7); | ||
129 | function(C,D,A,B,10,11); | ||
130 | function(B,C,D,A,11,19); | ||
131 | function(A,B,C,D,12, 3); | ||
132 | function(D,A,B,C,13, 7); | ||
133 | function(C,D,A,B,14,11); | ||
134 | function(B,C,D,A,15,19); | ||
135 | |||
136 | #undef function | ||
137 | |||
138 | /* Round 2. */ | ||
139 | #define function(a,b,c,d,k,s) a=rol(a+G(b,c,d)+in[k]+0x5a827999,s); | ||
140 | |||
141 | function(A,B,C,D, 0, 3); | ||
142 | function(D,A,B,C, 4, 5); | ||
143 | function(C,D,A,B, 8, 9); | ||
144 | function(B,C,D,A,12,13); | ||
145 | function(A,B,C,D, 1, 3); | ||
146 | function(D,A,B,C, 5, 5); | ||
147 | function(C,D,A,B, 9, 9); | ||
148 | function(B,C,D,A,13,13); | ||
149 | function(A,B,C,D, 2, 3); | ||
150 | function(D,A,B,C, 6, 5); | ||
151 | function(C,D,A,B,10, 9); | ||
152 | function(B,C,D,A,14,13); | ||
153 | function(A,B,C,D, 3, 3); | ||
154 | function(D,A,B,C, 7, 5); | ||
155 | function(C,D,A,B,11, 9); | ||
156 | function(B,C,D,A,15,13); | ||
157 | |||
158 | #undef function | ||
159 | |||
160 | /* Round 3. */ | ||
161 | #define function(a,b,c,d,k,s) a=rol(a+H(b,c,d)+in[k]+0x6ed9eba1,s); | ||
162 | |||
163 | function(A,B,C,D, 0, 3); | ||
164 | function(D,A,B,C, 8, 9); | ||
165 | function(C,D,A,B, 4,11); | ||
166 | function(B,C,D,A,12,15); | ||
167 | function(A,B,C,D, 2, 3); | ||
168 | function(D,A,B,C,10, 9); | ||
169 | function(C,D,A,B, 6,11); | ||
170 | function(B,C,D,A,14,15); | ||
171 | function(A,B,C,D, 1, 3); | ||
172 | function(D,A,B,C, 9, 9); | ||
173 | function(C,D,A,B, 5,11); | ||
174 | function(B,C,D,A,13,15); | ||
175 | function(A,B,C,D, 3, 3); | ||
176 | function(D,A,B,C,11, 9); | ||
177 | function(C,D,A,B, 7,11); | ||
178 | function(B,C,D,A,15,15); | ||
179 | |||
180 | |||
181 | /* Put checksum in context given as argument. */ | ||
182 | ctx->A += A; | ||
183 | ctx->B += B; | ||
184 | ctx->C += C; | ||
185 | ctx->D += D; | ||
186 | } | ||
187 | |||
188 | |||
189 | |||
190 | /* The routine updates the message-digest context to | ||
191 | * account for the presence of each of the characters inBuf[0..inLen-1] | ||
192 | * in the message whose digest is being computed. | ||
193 | */ | ||
194 | static void | ||
195 | md4_write( void *context, byte *inbuf, size_t inlen) | ||
196 | { | ||
197 | MD4_CONTEXT *hd = context; | ||
198 | |||
199 | if( hd->count == 64 ) /* flush the buffer */ | ||
200 | { | ||
201 | transform( hd, hd->buf ); | ||
202 | _gcry_burn_stack (80+6*sizeof(void*)); | ||
203 | hd->count = 0; | ||
204 | hd->nblocks++; | ||
205 | } | ||
206 | if( !inbuf ) | ||
207 | return; | ||
208 | |||
209 | if( hd->count ) | ||
210 | { | ||
211 | for( ; inlen && hd->count < 64; inlen-- ) | ||
212 | hd->buf[hd->count++] = *inbuf++; | ||
213 | md4_write( hd, NULL, 0 ); | ||
214 | if( !inlen ) | ||
215 | return; | ||
216 | } | ||
217 | _gcry_burn_stack (80+6*sizeof(void*)); | ||
218 | |||
219 | while( inlen >= 64 ) | ||
220 | { | ||
221 | transform( hd, inbuf ); | ||
222 | hd->count = 0; | ||
223 | hd->nblocks++; | ||
224 | inlen -= 64; | ||
225 | inbuf += 64; | ||
226 | } | ||
227 | for( ; inlen && hd->count < 64; inlen-- ) | ||
228 | hd->buf[hd->count++] = *inbuf++; | ||
229 | } | ||
230 | |||
231 | |||
232 | |||
233 | /* The routine final terminates the message-digest computation and | ||
234 | * ends with the desired message digest in mdContext->digest[0...15]. | ||
235 | * The handle is prepared for a new MD4 cycle. | ||
236 | * Returns 16 bytes representing the digest. | ||
237 | */ | ||
238 | |||
239 | static void | ||
240 | md4_final( void *context ) | ||
241 | { | ||
242 | MD4_CONTEXT *hd = context; | ||
243 | u32 t, msb, lsb; | ||
244 | byte *p; | ||
245 | |||
246 | md4_write(hd, NULL, 0); /* flush */; | ||
247 | |||
248 | t = hd->nblocks; | ||
249 | /* multiply by 64 to make a byte count */ | ||
250 | lsb = t << 6; | ||
251 | msb = t >> 26; | ||
252 | /* add the count */ | ||
253 | t = lsb; | ||
254 | if( (lsb += hd->count) < t ) | ||
255 | msb++; | ||
256 | /* multiply by 8 to make a bit count */ | ||
257 | t = lsb; | ||
258 | lsb <<= 3; | ||
259 | msb <<= 3; | ||
260 | msb |= t >> 29; | ||
261 | |||
262 | if( hd->count < 56 ) /* enough room */ | ||
263 | { | ||
264 | hd->buf[hd->count++] = 0x80; /* pad */ | ||
265 | while( hd->count < 56 ) | ||
266 | hd->buf[hd->count++] = 0; /* pad */ | ||
267 | } | ||
268 | else /* need one extra block */ | ||
269 | { | ||
270 | hd->buf[hd->count++] = 0x80; /* pad character */ | ||
271 | while( hd->count < 64 ) | ||
272 | hd->buf[hd->count++] = 0; | ||
273 | md4_write(hd, NULL, 0); /* flush */; | ||
274 | memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ | ||
275 | } | ||
276 | /* append the 64 bit count */ | ||
277 | hd->buf[56] = lsb ; | ||
278 | hd->buf[57] = lsb >> 8; | ||
279 | hd->buf[58] = lsb >> 16; | ||
280 | hd->buf[59] = lsb >> 24; | ||
281 | hd->buf[60] = msb ; | ||
282 | hd->buf[61] = msb >> 8; | ||
283 | hd->buf[62] = msb >> 16; | ||
284 | hd->buf[63] = msb >> 24; | ||
285 | transform( hd, hd->buf ); | ||
286 | _gcry_burn_stack (80+6*sizeof(void*)); | ||
287 | |||
288 | p = hd->buf; | ||
289 | #ifdef WORDS_BIGENDIAN | ||
290 | #define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \ | ||
291 | *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0) | ||
292 | #else /* little endian */ | ||
293 | #define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0) | ||
294 | #endif | ||
295 | X(A); | ||
296 | X(B); | ||
297 | X(C); | ||
298 | X(D); | ||
299 | #undef X | ||
300 | |||
301 | } | ||
302 | |||
303 | static byte * | ||
304 | md4_read (void *context) | ||
305 | { | ||
306 | MD4_CONTEXT *hd = context; | ||
307 | return hd->buf; | ||
308 | } | ||
309 | |||
310 | static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */ | ||
311 | { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, | ||
312 | 0x86, 0xf7, 0x0d, 0x02, 0x04, 0x05, 0x00, 0x04, 0x10 }; | ||
313 | |||
314 | static gcry_md_oid_spec_t oid_spec_md4[] = | ||
315 | { | ||
316 | /* iso.member-body.us.rsadsi.digestAlgorithm.md4 */ | ||
317 | { "1.2.840.113549.2.4" }, | ||
318 | { NULL }, | ||
319 | }; | ||
320 | |||
321 | gcry_md_spec_t _gcry_digest_spec_md4 = | ||
322 | { | ||
323 | "MD4", asn, DIM (asn), oid_spec_md4,16, | ||
324 | md4_init, md4_write, md4_final, md4_read, | ||
325 | sizeof (MD4_CONTEXT) | ||
326 | }; | ||
327 | |||