Mercurial > dropbear
comparison md5.c @ 0:d7da3b1e1540 libtomcrypt
put back the 0.95 makefile which was inadvertently merged over
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 31 May 2004 18:21:40 +0000 |
parents | |
children | 6362d3854bb4 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:d7da3b1e1540 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.org | |
10 */ | |
11 | |
12 /* MD5 hash function by Tom St Denis */ | |
13 | |
14 #include "mycrypt.h" | |
15 | |
16 #ifdef MD5 | |
17 | |
18 const struct _hash_descriptor md5_desc = | |
19 { | |
20 "md5", | |
21 3, | |
22 16, | |
23 64, | |
24 &md5_init, | |
25 &md5_process, | |
26 &md5_done, | |
27 &md5_test | |
28 }; | |
29 | |
30 #define F(x,y,z) (z ^ (x & (y ^ z))) | |
31 #define G(x,y,z) (y ^ (z & (y ^ x))) | |
32 #define H(x,y,z) (x^y^z) | |
33 #define I(x,y,z) (y^(x|(~z))) | |
34 | |
35 #define FF(a,b,c,d,M,s,t) \ | |
36 a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b; | |
37 | |
38 #define GG(a,b,c,d,M,s,t) \ | |
39 a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b; | |
40 | |
41 #define HH(a,b,c,d,M,s,t) \ | |
42 a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b; | |
43 | |
44 #define II(a,b,c,d,M,s,t) \ | |
45 a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b; | |
46 | |
47 #ifdef CLEAN_STACK | |
48 static void _md5_compress(hash_state *md, unsigned char *buf) | |
49 #else | |
50 static void md5_compress(hash_state *md, unsigned char *buf) | |
51 #endif | |
52 { | |
53 ulong32 i, W[16], a, b, c, d; | |
54 | |
55 /* copy the state into 512-bits into W[0..15] */ | |
56 for (i = 0; i < 16; i++) { | |
57 LOAD32L(W[i], buf + (4*i)); | |
58 } | |
59 | |
60 /* copy state */ | |
61 a = md->md5.state[0]; | |
62 b = md->md5.state[1]; | |
63 c = md->md5.state[2]; | |
64 d = md->md5.state[3]; | |
65 | |
66 FF(a,b,c,d,W[0],7,0xd76aa478UL) | |
67 FF(d,a,b,c,W[1],12,0xe8c7b756UL) | |
68 FF(c,d,a,b,W[2],17,0x242070dbUL) | |
69 FF(b,c,d,a,W[3],22,0xc1bdceeeUL) | |
70 FF(a,b,c,d,W[4],7,0xf57c0fafUL) | |
71 FF(d,a,b,c,W[5],12,0x4787c62aUL) | |
72 FF(c,d,a,b,W[6],17,0xa8304613UL) | |
73 FF(b,c,d,a,W[7],22,0xfd469501UL) | |
74 FF(a,b,c,d,W[8],7,0x698098d8UL) | |
75 FF(d,a,b,c,W[9],12,0x8b44f7afUL) | |
76 FF(c,d,a,b,W[10],17,0xffff5bb1UL) | |
77 FF(b,c,d,a,W[11],22,0x895cd7beUL) | |
78 FF(a,b,c,d,W[12],7,0x6b901122UL) | |
79 FF(d,a,b,c,W[13],12,0xfd987193UL) | |
80 FF(c,d,a,b,W[14],17,0xa679438eUL) | |
81 FF(b,c,d,a,W[15],22,0x49b40821UL) | |
82 GG(a,b,c,d,W[1],5,0xf61e2562UL) | |
83 GG(d,a,b,c,W[6],9,0xc040b340UL) | |
84 GG(c,d,a,b,W[11],14,0x265e5a51UL) | |
85 GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) | |
86 GG(a,b,c,d,W[5],5,0xd62f105dUL) | |
87 GG(d,a,b,c,W[10],9,0x02441453UL) | |
88 GG(c,d,a,b,W[15],14,0xd8a1e681UL) | |
89 GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) | |
90 GG(a,b,c,d,W[9],5,0x21e1cde6UL) | |
91 GG(d,a,b,c,W[14],9,0xc33707d6UL) | |
92 GG(c,d,a,b,W[3],14,0xf4d50d87UL) | |
93 GG(b,c,d,a,W[8],20,0x455a14edUL) | |
94 GG(a,b,c,d,W[13],5,0xa9e3e905UL) | |
95 GG(d,a,b,c,W[2],9,0xfcefa3f8UL) | |
96 GG(c,d,a,b,W[7],14,0x676f02d9UL) | |
97 GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) | |
98 HH(a,b,c,d,W[5],4,0xfffa3942UL) | |
99 HH(d,a,b,c,W[8],11,0x8771f681UL) | |
100 HH(c,d,a,b,W[11],16,0x6d9d6122UL) | |
101 HH(b,c,d,a,W[14],23,0xfde5380cUL) | |
102 HH(a,b,c,d,W[1],4,0xa4beea44UL) | |
103 HH(d,a,b,c,W[4],11,0x4bdecfa9UL) | |
104 HH(c,d,a,b,W[7],16,0xf6bb4b60UL) | |
105 HH(b,c,d,a,W[10],23,0xbebfbc70UL) | |
106 HH(a,b,c,d,W[13],4,0x289b7ec6UL) | |
107 HH(d,a,b,c,W[0],11,0xeaa127faUL) | |
108 HH(c,d,a,b,W[3],16,0xd4ef3085UL) | |
109 HH(b,c,d,a,W[6],23,0x04881d05UL) | |
110 HH(a,b,c,d,W[9],4,0xd9d4d039UL) | |
111 HH(d,a,b,c,W[12],11,0xe6db99e5UL) | |
112 HH(c,d,a,b,W[15],16,0x1fa27cf8UL) | |
113 HH(b,c,d,a,W[2],23,0xc4ac5665UL) | |
114 II(a,b,c,d,W[0],6,0xf4292244UL) | |
115 II(d,a,b,c,W[7],10,0x432aff97UL) | |
116 II(c,d,a,b,W[14],15,0xab9423a7UL) | |
117 II(b,c,d,a,W[5],21,0xfc93a039UL) | |
118 II(a,b,c,d,W[12],6,0x655b59c3UL) | |
119 II(d,a,b,c,W[3],10,0x8f0ccc92UL) | |
120 II(c,d,a,b,W[10],15,0xffeff47dUL) | |
121 II(b,c,d,a,W[1],21,0x85845dd1UL) | |
122 II(a,b,c,d,W[8],6,0x6fa87e4fUL) | |
123 II(d,a,b,c,W[15],10,0xfe2ce6e0UL) | |
124 II(c,d,a,b,W[6],15,0xa3014314UL) | |
125 II(b,c,d,a,W[13],21,0x4e0811a1UL) | |
126 II(a,b,c,d,W[4],6,0xf7537e82UL) | |
127 II(d,a,b,c,W[11],10,0xbd3af235UL) | |
128 II(c,d,a,b,W[2],15,0x2ad7d2bbUL) | |
129 II(b,c,d,a,W[9],21,0xeb86d391UL) | |
130 | |
131 md->md5.state[0] = md->md5.state[0] + a; | |
132 md->md5.state[1] = md->md5.state[1] + b; | |
133 md->md5.state[2] = md->md5.state[2] + c; | |
134 md->md5.state[3] = md->md5.state[3] + d; | |
135 } | |
136 | |
137 #ifdef CLEAN_STACK | |
138 static void md5_compress(hash_state *md, unsigned char *buf) | |
139 { | |
140 _md5_compress(md, buf); | |
141 burn_stack(sizeof(ulong32) * 21); | |
142 } | |
143 #endif | |
144 | |
145 void md5_init(hash_state * md) | |
146 { | |
147 _ARGCHK(md != NULL); | |
148 md->md5.state[0] = 0x67452301UL; | |
149 md->md5.state[1] = 0xefcdab89UL; | |
150 md->md5.state[2] = 0x98badcfeUL; | |
151 md->md5.state[3] = 0x10325476UL; | |
152 md->md5.curlen = 0; | |
153 md->md5.length = 0; | |
154 } | |
155 | |
156 HASH_PROCESS(md5_process, md5_compress, md5, 64) | |
157 | |
158 int md5_done(hash_state * md, unsigned char *hash) | |
159 { | |
160 int i; | |
161 | |
162 _ARGCHK(md != NULL); | |
163 _ARGCHK(hash != NULL); | |
164 | |
165 if (md->md5.curlen >= sizeof(md->md5.buf)) { | |
166 return CRYPT_INVALID_ARG; | |
167 } | |
168 | |
169 | |
170 /* increase the length of the message */ | |
171 md->md5.length += md->md5.curlen * 8; | |
172 | |
173 /* append the '1' bit */ | |
174 md->md5.buf[md->md5.curlen++] = (unsigned char)0x80; | |
175 | |
176 /* if the length is currently above 56 bytes we append zeros | |
177 * then compress. Then we can fall back to padding zeros and length | |
178 * encoding like normal. | |
179 */ | |
180 if (md->md5.curlen > 56) { | |
181 while (md->md5.curlen < 64) { | |
182 md->md5.buf[md->md5.curlen++] = (unsigned char)0; | |
183 } | |
184 md5_compress(md, md->md5.buf); | |
185 md->md5.curlen = 0; | |
186 } | |
187 | |
188 /* pad upto 56 bytes of zeroes */ | |
189 while (md->md5.curlen < 56) { | |
190 md->md5.buf[md->md5.curlen++] = (unsigned char)0; | |
191 } | |
192 | |
193 /* store length */ | |
194 STORE64L(md->md5.length, md->md5.buf+56); | |
195 md5_compress(md, md->md5.buf); | |
196 | |
197 /* copy output */ | |
198 for (i = 0; i < 4; i++) { | |
199 STORE32L(md->md5.state[i], hash+(4*i)); | |
200 } | |
201 #ifdef CLEAN_STACK | |
202 zeromem(md, sizeof(hash_state)); | |
203 #endif | |
204 return CRYPT_OK; | |
205 } | |
206 | |
207 int md5_test(void) | |
208 { | |
209 #ifndef LTC_TEST | |
210 return CRYPT_NOP; | |
211 #else | |
212 static const struct { | |
213 char *msg; | |
214 unsigned char hash[16]; | |
215 } tests[] = { | |
216 { "", | |
217 { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, | |
218 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, | |
219 { "a", | |
220 {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, | |
221 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, | |
222 { "abc", | |
223 { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, | |
224 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, | |
225 { "message digest", | |
226 { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, | |
227 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, | |
228 { "abcdefghijklmnopqrstuvwxyz", | |
229 { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, | |
230 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, | |
231 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", | |
232 { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, | |
233 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, | |
234 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", | |
235 { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, | |
236 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, | |
237 { NULL, { 0 } } | |
238 }; | |
239 | |
240 int i; | |
241 unsigned char tmp[16]; | |
242 hash_state md; | |
243 | |
244 for (i = 0; tests[i].msg != NULL; i++) { | |
245 md5_init(&md); | |
246 md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); | |
247 md5_done(&md, tmp); | |
248 if (memcmp(tmp, tests[i].hash, 16) != 0) { | |
249 return CRYPT_FAIL_TESTVECTOR; | |
250 } | |
251 } | |
252 return CRYPT_OK; | |
253 #endif | |
254 } | |
255 | |
256 #endif | |
257 | |
258 |