1 #include "first.h"
2
3 #include "sys-crypto-md.h"
4 #ifndef USE_LIB_CRYPTO_MD5
5
6 #define HAVE_MEMCPY
7 #define HAVE_MEMSET
8
9 /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
10 */
11
12 /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
13 rights reserved.
14
15 License to copy and use this software is granted provided that it
16 is identified as the "RSA Data Security, Inc. MD5 Message-Digest
17 Algorithm" in all material mentioning or referencing this software
18 or this function.
19
20 License is also granted to make and use derivative works provided
21 that such works are identified as "derived from the RSA Data
22 Security, Inc. MD5 Message-Digest Algorithm" in all material
23 mentioning or referencing the derived work.
24
25 RSA Data Security, Inc. makes no representations concerning either
26 the merchantability of this software or the suitability of this
27 software for any particular purpose. It is provided "as is"
28 without express or implied warranty of any kind.
29
30 These notices must be retained in any copies of any part of this
31 documentation and/or software.
32 */
33
34
35 #include "algo_md5.h"
36 #define li_MD5_CTX MD5_CTX
37 #define li_MD5_Init MD5_Init
38 #define li_MD5_Update MD5_Update
39 #define li_MD5_Final MD5_Final
40
41 #define UINT4 uint32_t
42 #define UINT2 uint16_t
43 #define POINTER unsigned char *
44
45 #include <string.h>
46
47 /* Constants for MD5Transform routine.
48 */
49
50 #define S11 7
51 #define S12 12
52 #define S13 17
53 #define S14 22
54 #define S21 5
55 #define S22 9
56 #define S23 14
57 #define S24 20
58 #define S31 4
59 #define S32 11
60 #define S33 16
61 #define S34 23
62 #define S41 6
63 #define S42 10
64 #define S43 15
65 #define S44 21
66
67 static void li_MD5Transform (UINT4 [4], const unsigned char [64]);
68 static void Encode (unsigned char *, UINT4 *, unsigned int);
69 static void Decode (UINT4 *, const unsigned char *, unsigned int);
70
71 #ifdef HAVE_MEMCPY
72 #define MD5_memcpy(output, input, len) memcpy((output), (input), (len))
73 #else
74 static void MD5_memcpy (POINTER, POINTER, unsigned int);
75 #endif
76 #ifdef HAVE_MEMSET
77 #define MD5_memset(output, value, len) memset((output), (value), (len))
78 #else
79 static void MD5_memset (POINTER, int, unsigned int);
80 #endif
81
82 static unsigned char PADDING[64] = {
83 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
86 };
87
88 /* F, G, H and I are basic MD5 functions.
89 */
90 #define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
91 #define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
92 #define H(x, y, z) ((x) ^ (y) ^ (z))
93 #define I(x, y, z) ((y) ^ ((x) | (~z)))
94
95 /* ROTATE_LEFT rotates x left n bits.
96 */
97 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
98
99 /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
100 Rotation is separate from addition to prevent recomputation.
101 */
102 #define FF(a, b, c, d, x, s, ac) { \
103 (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
104 (a) = ROTATE_LEFT ((a), (s)); \
105 (a) += (b); \
106 }
107 #define GG(a, b, c, d, x, s, ac) { \
108 (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
109 (a) = ROTATE_LEFT ((a), (s)); \
110 (a) += (b); \
111 }
112 #define HH(a, b, c, d, x, s, ac) { \
113 (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
114 (a) = ROTATE_LEFT ((a), (s)); \
115 (a) += (b); \
116 }
117 #define II(a, b, c, d, x, s, ac) { \
118 (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
119 (a) = ROTATE_LEFT ((a), (s)); \
120 (a) += (b); \
121 }
122
123 /* MD5 initialization. Begins an MD5 operation, writing a new context.
124 */
li_MD5_Init(li_MD5_CTX * context)125 void li_MD5_Init (li_MD5_CTX *context)
126 {
127 context->count[0] = context->count[1] = 0;
128 /* Load magic initialization constants.
129 */
130 context->state[0] = 0x67452301;
131 context->state[1] = 0xefcdab89;
132 context->state[2] = 0x98badcfe;
133 context->state[3] = 0x10325476;
134 }
135
136 /* MD5 block update operation. Continues an MD5 message-digest
137 operation, processing another message block, and updating the
138 context.
139 */
li_MD5_Update(li_MD5_CTX * context,const void * _input,unsigned int inputLen)140 void li_MD5_Update (li_MD5_CTX *context, const void *_input, unsigned int inputLen)
141 {
142 unsigned int i, ndx, partLen;
143 const unsigned char *input = (const unsigned char*) _input;
144
145 /* Compute number of bytes mod 64 */
146 ndx = (unsigned int)((context->count[0] >> 3) & 0x3F);
147
148 /* Update number of bits */
149 if ((context->count[0] += ((UINT4)inputLen << 3))
150
151 < ((UINT4)inputLen << 3))
152 context->count[1]++;
153 context->count[1] += ((UINT4)inputLen >> 29);
154
155 partLen = 64 - ndx;
156
157 /* Transform as many times as possible.
158 */
159 if (inputLen >= partLen) {
160 MD5_memcpy
161 ((POINTER)&context->buffer[ndx], (POINTER)input, partLen);
162 li_MD5Transform (context->state, context->buffer);
163
164 for (i = partLen; i + 63 < inputLen; i += 64)
165 li_MD5Transform (context->state, &input[i]);
166
167 ndx = 0;
168 }
169 else
170 i = 0;
171
172 /* Buffer remaining input */
173 MD5_memcpy
174 ((POINTER)&context->buffer[ndx], (POINTER)&input[i],
175 inputLen-i);
176 }
177
178 /* MD5 finalization. Ends an MD5 message-digest operation, writing the
179 the message digest and zeroizing the context.
180 */
li_MD5_Final(unsigned char digest[16],li_MD5_CTX * context)181 void li_MD5_Final (unsigned char digest[16], li_MD5_CTX *context)
182 {
183 unsigned char bits[8];
184 unsigned int ndx, padLen;
185
186 /* Save number of bits */
187 Encode (bits, context->count, 8);
188
189 /* Pad out to 56 mod 64.
190 */
191 ndx = (unsigned int)((context->count[0] >> 3) & 0x3f);
192 padLen = (ndx < 56) ? (56 - ndx) : (120 - ndx);
193 li_MD5_Update (context, PADDING, padLen);
194
195 /* Append length (before padding) */
196 li_MD5_Update (context, bits, 8);
197
198 /* Store state in digest */
199 Encode (digest, context->state, 16);
200
201 /* Zeroize sensitive information.
202 */
203 MD5_memset ((POINTER)context, 0, sizeof (*context));
204 }
205
206 /* MD5 basic transformation. Transforms state based on block.
207 */
li_MD5Transform(UINT4 state[4],const unsigned char block[64])208 static void li_MD5Transform (UINT4 state[4], const unsigned char block[64])
209 {
210 UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
211
212 Decode (x, block, 64);
213
214 /* Round 1 */
215 FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
216 FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
217 FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
218 FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
219 FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
220 FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
221 FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
222 FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
223 FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
224 FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
225 FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
226 FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
227 FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
228 FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
229 FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
230 FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
231
232 /* Round 2 */
233 GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
234 GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
235 GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
236 GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
237 GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
238 GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
239 GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
240 GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
241 GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
242 GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
243 GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
244
245 GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
246 GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
247 GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
248 GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
249 GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
250
251 /* Round 3 */
252 HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
253 HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
254 HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
255 HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
256 HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
257 HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
258 HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
259 HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
260 HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
261 HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
262 HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
263 HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
264 HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
265 HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
266 HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
267 HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
268
269 /* Round 4 */
270 II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
271 II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
272 II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
273 II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
274 II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
275 II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
276 II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
277 II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
278 II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
279 II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
280 II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
281 II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
282 II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
283 II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
284 II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
285 II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
286
287 state[0] += a;
288 state[1] += b;
289 state[2] += c;
290 state[3] += d;
291
292 /* Zeroize sensitive information.
293
294 */
295 MD5_memset ((POINTER)x, 0, sizeof (x));
296 }
297
298 /* Encodes input (UINT4) into output (unsigned char). Assumes len is
299 a multiple of 4.
300 */
Encode(unsigned char * output,UINT4 * input,unsigned int len)301 static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
302 {
303 unsigned int i, j;
304
305 for (i = 0, j = 0; j < len; i++, j += 4) {
306 output[j] = (unsigned char)(input[i] & 0xff);
307 output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
308 output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
309 output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
310 }
311 }
312
313 /* Decodes input (unsigned char) into output (UINT4). Assumes len is
314 a multiple of 4.
315 */
Decode(UINT4 * output,const unsigned char * input,unsigned int len)316 static void Decode (UINT4 *output, const unsigned char *input, unsigned int len)
317 {
318 unsigned int i, j;
319
320 for (i = 0, j = 0; j < len; i++, j += 4)
321 output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
322 (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
323 }
324
325 /* Note: Replace "for loop" with standard memcpy if possible.
326 */
327 #ifndef HAVE_MEMCPY
MD5_memcpy(POINTER output,POINTER input,unsigned int len)328 static void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
329 {
330 unsigned int i;
331
332 for (i = 0; i < len; i++)
333
334 output[i] = input[i];
335 }
336 #endif
337 /* Note: Replace "for loop" with standard memset if possible.
338 */
339 #ifndef HAVE_MEMSET
MD5_memset(POINTER output,int value,unsigned int len)340 static void MD5_memset (POINTER output, int value, unsigned int len)
341 {
342 unsigned int i;
343
344 for (i = 0; i < len; i++)
345 ((char *)output)[i] = (char)value;
346 }
347 #endif
348
349 #endif
350