1 /* $USAGI: md5.c,v 1.2 2000/11/02 11:59:24 yoshfuji Exp $ */
2 /* $KAME: md5.c,v 1.2 2000/05/27 07:07:48 jinmei Exp $ */
3 /* $Id: md5.c,v 1.6 2006/01/17 23:39:04 vincent Exp $ */
6 * Copyright (C) 2004 6WIND
7 * <Vincent.Jardin@6WIND.com>
10 * This MD5 code is Big endian and Little Endian compatible.
14 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
15 * All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. Neither the name of the project nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
29 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
45 #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
47 #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
48 #define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
49 #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
50 #define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
52 #define ROUND1(a, b, c, d, k, s, i) { \
53 (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
54 (a) = SHIFT((a), (s)); \
58 #define ROUND2(a, b, c, d, k, s, i) { \
59 (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
60 (a) = SHIFT((a), (s)); \
64 #define ROUND3(a, b, c, d, k, s, i) { \
65 (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
66 (a) = SHIFT((a), (s)); \
70 #define ROUND4(a, b, c, d, k, s, i) { \
71 (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
72 (a) = SHIFT((a), (s)); \
96 #define MD5_A0 0x67452301
97 #define MD5_B0 0xefcdab89
98 #define MD5_C0 0x98badcfe
99 #define MD5_D0 0x10325476
101 /* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
102 static const uint32_t T[65] = {
104 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
105 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
106 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
107 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
109 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
110 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
111 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
112 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
114 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
115 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
116 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
117 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
119 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
120 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
121 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
122 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
125 static const uint8_t md5_paddat[MD5_BUFLEN] = {
126 0x80, 0, 0, 0, 0, 0, 0, 0,
127 0, 0, 0, 0, 0, 0, 0, 0,
128 0, 0, 0, 0, 0, 0, 0, 0,
129 0, 0, 0, 0, 0, 0, 0, 0,
130 0, 0, 0, 0, 0, 0, 0, 0,
131 0, 0, 0, 0, 0, 0, 0, 0,
132 0, 0, 0, 0, 0, 0, 0, 0,
133 0, 0, 0, 0, 0, 0, 0, 0,
136 static void md5_calc (const uint8_t *, md5_ctxt *);
138 void md5_init(md5_ctxt *ctxt)
142 ctxt->md5_sta = MD5_A0;
143 ctxt->md5_stb = MD5_B0;
144 ctxt->md5_stc = MD5_C0;
145 ctxt->md5_std = MD5_D0;
146 memset (ctxt->md5_buf, 0, sizeof(ctxt->md5_buf));
149 void md5_loop(md5_ctxt *ctxt, const void *vinput, uint len)
152 const uint8_t *input = vinput;
154 ctxt->md5_n += len * 8; /* byte to bit */
155 gap = MD5_BUFLEN - ctxt->md5_i;
158 memcpy (ctxt->md5_buf + ctxt->md5_i, input, gap);
159 md5_calc(ctxt->md5_buf, ctxt);
161 for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
162 md5_calc((input + i), ctxt);
165 ctxt->md5_i = len - i;
166 memcpy (ctxt->md5_buf, (input + i), ctxt->md5_i);
168 memcpy (ctxt->md5_buf + ctxt->md5_i, input, len);
173 void md5_pad(md5_ctxt *ctxt)
177 /* Don't count up padding. Keep md5_n. */
178 gap = MD5_BUFLEN - ctxt->md5_i;
180 memcpy (ctxt->md5_buf + ctxt->md5_i, md5_paddat,
181 gap - sizeof(ctxt->md5_n));
183 /* including gap == 8 */
184 memcpy (ctxt->md5_buf + ctxt->md5_i, md5_paddat, gap);
185 md5_calc (ctxt->md5_buf, ctxt);
186 memcpy (ctxt->md5_buf, md5_paddat + gap,
187 MD5_BUFLEN - sizeof(ctxt->md5_n));
191 if (BYTE_ORDER == LITTLE_ENDIAN)
192 memcpy (&ctxt->md5_buf[56], &ctxt->md5_n8[0], 8);
195 ctxt->md5_buf[56] = ctxt->md5_n8[7];
196 ctxt->md5_buf[57] = ctxt->md5_n8[6];
197 ctxt->md5_buf[58] = ctxt->md5_n8[5];
198 ctxt->md5_buf[59] = ctxt->md5_n8[4];
199 ctxt->md5_buf[60] = ctxt->md5_n8[3];
200 ctxt->md5_buf[61] = ctxt->md5_n8[2];
201 ctxt->md5_buf[62] = ctxt->md5_n8[1];
202 ctxt->md5_buf[63] = ctxt->md5_n8[0];
204 md5_calc(ctxt->md5_buf, ctxt);
207 void md5_result(uint8_t *digest, md5_ctxt *ctxt)
210 if (BYTE_ORDER == LITTLE_ENDIAN)
211 memcpy (digest, &ctxt->md5_st8[0], 16);
212 else if (BYTE_ORDER == BIG_ENDIAN)
214 digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
215 digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
216 digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
217 digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
218 digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
219 digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
220 digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
221 digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
225 static void md5_calc(const uint8_t *b64, md5_ctxt * ctxt)
227 uint32_t A = ctxt->md5_sta;
228 uint32_t B = ctxt->md5_stb;
229 uint32_t C = ctxt->md5_stc;
230 uint32_t D = ctxt->md5_std;
231 #if (BYTE_ORDER == LITTLE_ENDIAN)
232 const uint32_t *X = (const uint32_t *)b64;
233 #elif (BYTE_ORDER == BIG_ENDIAN)
236 if (BYTE_ORDER == BIG_ENDIAN)
239 /* what a brute force but fast! */
240 uint8_t *y = (uint8_t *)X;
241 y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
242 y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
243 y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
244 y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
245 y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
246 y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
247 y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
248 y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
249 y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
250 y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
251 y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
252 y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
253 y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
254 y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
255 y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
256 y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
260 ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
261 ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
262 ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
263 ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
264 ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
265 ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
266 ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
267 ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
269 ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
270 ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
271 ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
272 ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
273 ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
274 ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
275 ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
276 ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
278 ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
279 ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
280 ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
281 ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
282 ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
283 ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
284 ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
285 ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
287 ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
288 ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
289 ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
290 ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
291 ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
292 ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
293 ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
294 ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
304 hmac_md5(text, text_len, key, key_len, digest)
305 unsigned char* text; /* pointer to data stream */
306 int text_len; /* length of data stream */
307 unsigned char* key; /* pointer to authentication key */
308 int key_len; /* length of authentication key */
309 uint8_t * digest; /* caller digest to be filled in */
313 unsigned char k_ipad[65]; /* inner padding -
316 unsigned char k_opad[65]; /* outer padding -
319 unsigned char tk[16];
321 /* if key is longer than 64 bytes reset it to key=MD5(key) */
327 MD5Update(&tctx, key, key_len);
335 * the HMAC_MD5 transform looks like:
337 * MD5(K XOR opad, MD5(K XOR ipad, text))
339 * where K is an n byte key
340 * ipad is the byte 0x36 repeated 64 times
341 * opad is the byte 0x5c repeated 64 times
342 * and text is the data being protected
345 /* start out by storing key in pads */
346 bzero( k_ipad, sizeof k_ipad);
347 bzero( k_opad, sizeof k_opad);
348 bcopy( key, k_ipad, key_len);
349 bcopy( key, k_opad, key_len);
351 /* XOR key with ipad and opad values */
352 for (i=0; i<64; i++) {
359 MD5Init(&context); /* init context for 1st
361 MD5Update(&context, k_ipad, 64); /* start with inner pad */
362 MD5Update(&context, text, text_len); /* then text of datagram */
363 MD5Final(digest, &context); /* finish up 1st pass */
367 MD5Init(&context); /* init context for 2nd
369 MD5Update(&context, k_opad, 64); /* start with outer pad */
370 MD5Update(&context, digest, 16); /* then results of 1st
372 MD5Final(digest, &context); /* finish up 2nd pass */