Diffstat (limited to 'pwmanager/libcrypt/cipher/md5.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | pwmanager/libcrypt/cipher/md5.c | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/pwmanager/libcrypt/cipher/md5.c b/pwmanager/libcrypt/cipher/md5.c new file mode 100644 index 0000000..ec10b4d --- a/dev/null +++ b/pwmanager/libcrypt/cipher/md5.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* md5.c - MD5 Message-Digest Algorithm | ||
2 | * Copyright (C) 1995,1996,1998,1999,2001,2002, | ||
3 | * 2003 Free Software Foundation, Inc. | ||
4 | * | ||
5 | * This file is part of Libgcrypt. | ||
6 | * | ||
7 | * Libgcrypt is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU Lesser General Public License as | ||
9 | * published by the Free Software Foundation; either version 2.1 of | ||
10 | * the License, or (at your option) any later version. | ||
11 | * | ||
12 | * Libgcrypt is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU Lesser General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU Lesser General Public | ||
18 | * License along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||
20 | * | ||
21 | * According to the definition of MD5 in RFC 1321 from April 1992. | ||
22 | * NOTE: This is *not* the same file as the one from glibc. | ||
23 | * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. | ||
24 | * heavily modified for GnuPG by Werner Koch <wk@gnupg.org> | ||
25 | */ | ||
26 | |||
27 | /* Test values: | ||
28 | * "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E | ||
29 | * "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61 | ||
30 | * "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72 | ||
31 | * "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0 | ||
32 | */ | ||
33 | |||
34 | #include <config.h> | ||
35 | #include <stdio.h> | ||
36 | #include <stdlib.h> | ||
37 | #include <string.h> | ||
38 | #include <assert.h> | ||
39 | #include "g10lib.h" | ||
40 | #include "memory.h" | ||
41 | #include "cipher.h" | ||
42 | |||
43 | #include "bithelp.h" | ||
44 | |||
45 | |||
46 | typedef struct { | ||
47 | u32 A,B,C,D; /* chaining variables */ | ||
48 | u32 nblocks; | ||
49 | byte buf[64]; | ||
50 | int count; | ||
51 | } MD5_CONTEXT; | ||
52 | |||
53 | |||
54 | static void | ||
55 | md5_init( void *context ) | ||
56 | { | ||
57 | MD5_CONTEXT *ctx = context; | ||
58 | |||
59 | ctx->A = 0x67452301; | ||
60 | ctx->B = 0xefcdab89; | ||
61 | ctx->C = 0x98badcfe; | ||
62 | ctx->D = 0x10325476; | ||
63 | |||
64 | ctx->nblocks = 0; | ||
65 | ctx->count = 0; | ||
66 | } | ||
67 | |||
68 | |||
69 | /* These are the four functions used in the four steps of the MD5 algorithm | ||
70 | and defined in the RFC 1321. The first function is a little bit optimized | ||
71 | (as found in Colin Plumbs public domain implementation). */ | ||
72 | /* #define FF(b, c, d) ((b & c) | (~b & d)) */ | ||
73 | #define FF(b, c, d) (d ^ (b & (c ^ d))) | ||
74 | #define FG(b, c, d) FF (d, b, c) | ||
75 | #define FH(b, c, d) (b ^ c ^ d) | ||
76 | #define FI(b, c, d) (c ^ (b | ~d)) | ||
77 | |||
78 | |||
79 | /**************** | ||
80 | * transform n*64 bytes | ||
81 | */ | ||
82 | static void | ||
83 | transform( MD5_CONTEXT *ctx, byte *data ) | ||
84 | { | ||
85 | u32 correct_words[16]; | ||
86 | register u32 A = ctx->A; | ||
87 | register u32 B = ctx->B; | ||
88 | register u32 C = ctx->C; | ||
89 | register u32 D = ctx->D; | ||
90 | u32 *cwp = correct_words; | ||
91 | |||
92 | #ifdef WORDS_BIGENDIAN | ||
93 | { | ||
94 | int i; | ||
95 | byte *p2, *p1; | ||
96 | for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 ) | ||
97 | { | ||
98 | p2[3] = *p1++; | ||
99 | p2[2] = *p1++; | ||
100 | p2[1] = *p1++; | ||
101 | p2[0] = *p1++; | ||
102 | } | ||
103 | } | ||
104 | #else | ||
105 | memcpy( correct_words, data, 64 ); | ||
106 | #endif | ||
107 | |||
108 | |||
109 | #define OP(a, b, c, d, s, T) \ | ||
110 | do \ | ||
111 | { \ | ||
112 | a += FF (b, c, d) + (*cwp++) + T; \ | ||
113 | a = rol(a, s); \ | ||
114 | a += b; \ | ||
115 | } \ | ||
116 | while (0) | ||
117 | |||
118 | /* Before we start, one word about the strange constants. | ||
119 | They are defined in RFC 1321 as | ||
120 | |||
121 | T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 | ||
122 | */ | ||
123 | |||
124 | /* Round 1. */ | ||
125 | OP (A, B, C, D, 7, 0xd76aa478); | ||
126 | OP (D, A, B, C, 12, 0xe8c7b756); | ||
127 | OP (C, D, A, B, 17, 0x242070db); | ||
128 | OP (B, C, D, A, 22, 0xc1bdceee); | ||
129 | OP (A, B, C, D, 7, 0xf57c0faf); | ||
130 | OP (D, A, B, C, 12, 0x4787c62a); | ||
131 | OP (C, D, A, B, 17, 0xa8304613); | ||
132 | OP (B, C, D, A, 22, 0xfd469501); | ||
133 | OP (A, B, C, D, 7, 0x698098d8); | ||
134 | OP (D, A, B, C, 12, 0x8b44f7af); | ||
135 | OP (C, D, A, B, 17, 0xffff5bb1); | ||
136 | OP (B, C, D, A, 22, 0x895cd7be); | ||
137 | OP (A, B, C, D, 7, 0x6b901122); | ||
138 | OP (D, A, B, C, 12, 0xfd987193); | ||
139 | OP (C, D, A, B, 17, 0xa679438e); | ||
140 | OP (B, C, D, A, 22, 0x49b40821); | ||
141 | |||
142 | #undef OP | ||
143 | #define OP(f, a, b, c, d, k, s, T) \ | ||
144 | do \ | ||
145 | { \ | ||
146 | a += f (b, c, d) + correct_words[k] + T; \ | ||
147 | a = rol(a, s); \ | ||
148 | a += b; \ | ||
149 | } \ | ||
150 | while (0) | ||
151 | |||
152 | /* Round 2. */ | ||
153 | OP (FG, A, B, C, D, 1, 5, 0xf61e2562); | ||
154 | OP (FG, D, A, B, C, 6, 9, 0xc040b340); | ||
155 | OP (FG, C, D, A, B, 11, 14, 0x265e5a51); | ||
156 | OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); | ||
157 | OP (FG, A, B, C, D, 5, 5, 0xd62f105d); | ||
158 | OP (FG, D, A, B, C, 10, 9, 0x02441453); | ||
159 | OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); | ||
160 | OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); | ||
161 | OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); | ||
162 | OP (FG, D, A, B, C, 14, 9, 0xc33707d6); | ||
163 | OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); | ||
164 | OP (FG, B, C, D, A, 8, 20, 0x455a14ed); | ||
165 | OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); | ||
166 | OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); | ||
167 | OP (FG, C, D, A, B, 7, 14, 0x676f02d9); | ||
168 | OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); | ||
169 | |||
170 | /* Round 3. */ | ||
171 | OP (FH, A, B, C, D, 5, 4, 0xfffa3942); | ||
172 | OP (FH, D, A, B, C, 8, 11, 0x8771f681); | ||
173 | OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); | ||
174 | OP (FH, B, C, D, A, 14, 23, 0xfde5380c); | ||
175 | OP (FH, A, B, C, D, 1, 4, 0xa4beea44); | ||
176 | OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); | ||
177 | OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); | ||
178 | OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); | ||
179 | OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); | ||
180 | OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); | ||
181 | OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); | ||
182 | OP (FH, B, C, D, A, 6, 23, 0x04881d05); | ||
183 | OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); | ||
184 | OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); | ||
185 | OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); | ||
186 | OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); | ||
187 | |||
188 | /* Round 4. */ | ||
189 | OP (FI, A, B, C, D, 0, 6, 0xf4292244); | ||
190 | OP (FI, D, A, B, C, 7, 10, 0x432aff97); | ||
191 | OP (FI, C, D, A, B, 14, 15, 0xab9423a7); | ||
192 | OP (FI, B, C, D, A, 5, 21, 0xfc93a039); | ||
193 | OP (FI, A, B, C, D, 12, 6, 0x655b59c3); | ||
194 | OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); | ||
195 | OP (FI, C, D, A, B, 10, 15, 0xffeff47d); | ||
196 | OP (FI, B, C, D, A, 1, 21, 0x85845dd1); | ||
197 | OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); | ||
198 | OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); | ||
199 | OP (FI, C, D, A, B, 6, 15, 0xa3014314); | ||
200 | OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); | ||
201 | OP (FI, A, B, C, D, 4, 6, 0xf7537e82); | ||
202 | OP (FI, D, A, B, C, 11, 10, 0xbd3af235); | ||
203 | OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); | ||
204 | OP (FI, B, C, D, A, 9, 21, 0xeb86d391); | ||
205 | |||
206 | /* Put checksum in context given as argument. */ | ||
207 | ctx->A += A; | ||
208 | ctx->B += B; | ||
209 | ctx->C += C; | ||
210 | ctx->D += D; | ||
211 | } | ||
212 | |||
213 | |||
214 | |||
215 | /* The routine updates the message-digest context to | ||
216 | * account for the presence of each of the characters inBuf[0..inLen-1] | ||
217 | * in the message whose digest is being computed. | ||
218 | */ | ||
219 | static void | ||
220 | md5_write( void *context, byte *inbuf, size_t inlen) | ||
221 | { | ||
222 | MD5_CONTEXT *hd = context; | ||
223 | |||
224 | if( hd->count == 64 ) /* flush the buffer */ | ||
225 | { | ||
226 | transform( hd, hd->buf ); | ||
227 | _gcry_burn_stack (80+6*sizeof(void*)); | ||
228 | hd->count = 0; | ||
229 | hd->nblocks++; | ||
230 | } | ||
231 | if( !inbuf ) | ||
232 | return; | ||
233 | |||
234 | if( hd->count ) | ||
235 | { | ||
236 | for( ; inlen && hd->count < 64; inlen-- ) | ||
237 | hd->buf[hd->count++] = *inbuf++; | ||
238 | md5_write( hd, NULL, 0 ); | ||
239 | if( !inlen ) | ||
240 | return; | ||
241 | } | ||
242 | _gcry_burn_stack (80+6*sizeof(void*)); | ||
243 | |||
244 | while( inlen >= 64 ) | ||
245 | { | ||
246 | transform( hd, inbuf ); | ||
247 | hd->count = 0; | ||
248 | hd->nblocks++; | ||
249 | inlen -= 64; | ||
250 | inbuf += 64; | ||
251 | } | ||
252 | for( ; inlen && hd->count < 64; inlen-- ) | ||
253 | hd->buf[hd->count++] = *inbuf++; | ||
254 | |||
255 | } | ||
256 | |||
257 | |||
258 | |||
259 | /* The routine final terminates the message-digest computation and | ||
260 | * ends with the desired message digest in mdContext->digest[0...15]. | ||
261 | * The handle is prepared for a new MD5 cycle. | ||
262 | * Returns 16 bytes representing the digest. | ||
263 | */ | ||
264 | |||
265 | static void | ||
266 | md5_final( void *context) | ||
267 | { | ||
268 | MD5_CONTEXT *hd = context; | ||
269 | u32 t, msb, lsb; | ||
270 | byte *p; | ||
271 | |||
272 | md5_write(hd, NULL, 0); /* flush */; | ||
273 | |||
274 | t = hd->nblocks; | ||
275 | /* multiply by 64 to make a byte count */ | ||
276 | lsb = t << 6; | ||
277 | msb = t >> 26; | ||
278 | /* add the count */ | ||
279 | t = lsb; | ||
280 | if( (lsb += hd->count) < t ) | ||
281 | msb++; | ||
282 | /* multiply by 8 to make a bit count */ | ||
283 | t = lsb; | ||
284 | lsb <<= 3; | ||
285 | msb <<= 3; | ||
286 | msb |= t >> 29; | ||
287 | |||
288 | if( hd->count < 56 ) /* enough room */ | ||
289 | { | ||
290 | hd->buf[hd->count++] = 0x80; /* pad */ | ||
291 | while( hd->count < 56 ) | ||
292 | hd->buf[hd->count++] = 0; /* pad */ | ||
293 | } | ||
294 | else /* need one extra block */ | ||
295 | { | ||
296 | hd->buf[hd->count++] = 0x80; /* pad character */ | ||
297 | while( hd->count < 64 ) | ||
298 | hd->buf[hd->count++] = 0; | ||
299 | md5_write(hd, NULL, 0); /* flush */; | ||
300 | memset(hd->buf, 0, 56 ); /* fill next block with zeroes */ | ||
301 | } | ||
302 | /* append the 64 bit count */ | ||
303 | hd->buf[56] = lsb ; | ||
304 | hd->buf[57] = lsb >> 8; | ||
305 | hd->buf[58] = lsb >> 16; | ||
306 | hd->buf[59] = lsb >> 24; | ||
307 | hd->buf[60] = msb ; | ||
308 | hd->buf[61] = msb >> 8; | ||
309 | hd->buf[62] = msb >> 16; | ||
310 | hd->buf[63] = msb >> 24; | ||
311 | transform( hd, hd->buf ); | ||
312 | _gcry_burn_stack (80+6*sizeof(void*)); | ||
313 | |||
314 | p = hd->buf; | ||
315 | #ifdef WORDS_BIGENDIAN | ||
316 | #define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \ | ||
317 | *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0) | ||
318 | #else /* little endian */ | ||
319 | #define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0) | ||
320 | #endif | ||
321 | X(A); | ||
322 | X(B); | ||
323 | X(C); | ||
324 | X(D); | ||
325 | #undef X | ||
326 | |||
327 | } | ||
328 | |||
329 | static byte * | ||
330 | md5_read( void *context ) | ||
331 | { | ||
332 | MD5_CONTEXT *hd = (MD5_CONTEXT *) context; | ||
333 | return hd->buf; | ||
334 | } | ||
335 | |||
336 | static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */ | ||
337 | { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, | ||
338 | 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; | ||
339 | |||
340 | static gcry_md_oid_spec_t oid_spec_md5[] = | ||
341 | { | ||
342 | /* iso.member-body.us.rsadsi.pkcs.pkcs-1.4 (md5WithRSAEncryption) */ | ||
343 | { "1.2.840.113549.1.1.4" }, | ||
344 | /* RSADSI digestAlgorithm MD5 */ | ||
345 | { "1.2.840.113549.2.5" }, | ||
346 | { NULL }, | ||
347 | }; | ||
348 | |||
349 | gcry_md_spec_t _gcry_digest_spec_md5 = | ||
350 | { | ||
351 | "MD5", asn, DIM (asn), oid_spec_md5, 16, | ||
352 | md5_init, md5_write, md5_final, md5_read, | ||
353 | sizeof (MD5_CONTEXT) | ||
354 | }; | ||