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