blob: 4e9749415dc1cdff6c18914458ac56baf6c51440 [file] [log] [blame]
vincentc1a03d42005-09-28 15:47:44 +00001/* $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.3 2005/09/28 15:47:44 vincent Exp $ */
paul718e3742002-12-13 20:15:29 +00004
vincentc1a03d42005-09-28 15:47:44 +00005/*
6 * Copyright (C) 2004 6WIND
7 * <Vincent.Jardin@6WIND.com>
8 * All rights reserved.
9 *
10 * This MD5 code is Big endian and Little Endian compatible.
11 */
paul718e3742002-12-13 20:15:29 +000012
vincentc1a03d42005-09-28 15:47:44 +000013/*
14 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
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.
28 *
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
39 * SUCH DAMAGE.
40 */
paul718e3742002-12-13 20:15:29 +000041
vincentc1a03d42005-09-28 15:47:44 +000042#include <sys/param.h>
paul718e3742002-12-13 20:15:29 +000043#include <sys/types.h>
vincentc1a03d42005-09-28 15:47:44 +000044#include <sys/cdefs.h>
45#include <sys/time.h>
46#include <string.h>
47#include "md5.h"
paul718e3742002-12-13 20:15:29 +000048
vincentc1a03d42005-09-28 15:47:44 +000049#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
paul718e3742002-12-13 20:15:29 +000050
vincentc1a03d42005-09-28 15:47:44 +000051#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
52#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
53#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
54#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
paul718e3742002-12-13 20:15:29 +000055
vincentc1a03d42005-09-28 15:47:44 +000056#define ROUND1(a, b, c, d, k, s, i) { \
57 (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
58 (a) = SHIFT((a), (s)); \
59 (a) = (b) + (a); \
paul718e3742002-12-13 20:15:29 +000060}
61
vincentc1a03d42005-09-28 15:47:44 +000062#define ROUND2(a, b, c, d, k, s, i) { \
63 (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
64 (a) = SHIFT((a), (s)); \
65 (a) = (b) + (a); \
paul718e3742002-12-13 20:15:29 +000066}
67
vincentc1a03d42005-09-28 15:47:44 +000068#define ROUND3(a, b, c, d, k, s, i) { \
69 (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
70 (a) = SHIFT((a), (s)); \
71 (a) = (b) + (a); \
paul718e3742002-12-13 20:15:29 +000072}
73
vincentc1a03d42005-09-28 15:47:44 +000074#define ROUND4(a, b, c, d, k, s, i) { \
75 (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
76 (a) = SHIFT((a), (s)); \
77 (a) = (b) + (a); \
78}
79
80#define Sa 7
81#define Sb 12
82#define Sc 17
83#define Sd 22
84
85#define Se 5
86#define Sf 9
87#define Sg 14
88#define Sh 20
89
90#define Si 4
91#define Sj 11
92#define Sk 16
93#define Sl 23
94
95#define Sm 6
96#define Sn 10
97#define So 15
98#define Sp 21
99
100#define MD5_A0 0x67452301
101#define MD5_B0 0xefcdab89
102#define MD5_C0 0x98badcfe
103#define MD5_D0 0x10325476
104
105/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
106static const u_int32_t T[65] = {
107 0,
108 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
109 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
110 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
111 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
112
113 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
114 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
115 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
116 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
117
118 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
119 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
120 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
121 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
122
123 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
124 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
125 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
126 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
127};
128
129static const u_int8_t md5_paddat[MD5_BUFLEN] = {
130 0x80, 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,
134 0, 0, 0, 0, 0, 0, 0, 0,
135 0, 0, 0, 0, 0, 0, 0, 0,
136 0, 0, 0, 0, 0, 0, 0, 0,
137 0, 0, 0, 0, 0, 0, 0, 0,
138};
139
140static void md5_calc __P((u_int8_t *, md5_ctxt *));
141
142void md5_init(ctxt)
143 md5_ctxt *ctxt;
paul718e3742002-12-13 20:15:29 +0000144{
vincentc1a03d42005-09-28 15:47:44 +0000145 ctxt->md5_n = 0;
146 ctxt->md5_i = 0;
147 ctxt->md5_sta = MD5_A0;
148 ctxt->md5_stb = MD5_B0;
149 ctxt->md5_stc = MD5_C0;
150 ctxt->md5_std = MD5_D0;
151 bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
152}
paul718e3742002-12-13 20:15:29 +0000153
vincentc1a03d42005-09-28 15:47:44 +0000154void md5_loop(ctxt, input, len)
155 md5_ctxt *ctxt;
156 u_int8_t *input;
157 u_int len; /* number of bytes */
158{
159 u_int gap, i;
paul718e3742002-12-13 20:15:29 +0000160
vincentc1a03d42005-09-28 15:47:44 +0000161 ctxt->md5_n += len * 8; /* byte to bit */
162 gap = MD5_BUFLEN - ctxt->md5_i;
paul718e3742002-12-13 20:15:29 +0000163
vincentc1a03d42005-09-28 15:47:44 +0000164 if (len >= gap) {
165 bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
166 gap);
167 md5_calc(ctxt->md5_buf, ctxt);
paul718e3742002-12-13 20:15:29 +0000168
vincentc1a03d42005-09-28 15:47:44 +0000169 for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
170 md5_calc((u_int8_t *)(input + i), ctxt);
171 }
172
173 ctxt->md5_i = len - i;
174 bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
175 } else {
176 bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
177 len);
178 ctxt->md5_i += len;
paul718e3742002-12-13 20:15:29 +0000179 }
paul718e3742002-12-13 20:15:29 +0000180}
181
vincentc1a03d42005-09-28 15:47:44 +0000182void md5_pad(ctxt)
183 md5_ctxt *ctxt;
paul718e3742002-12-13 20:15:29 +0000184{
vincentc1a03d42005-09-28 15:47:44 +0000185 u_int gap;
paul718e3742002-12-13 20:15:29 +0000186
vincentc1a03d42005-09-28 15:47:44 +0000187 /* Don't count up padding. Keep md5_n. */
188 gap = MD5_BUFLEN - ctxt->md5_i;
189 if (gap > 8) {
190 bcopy((void *)md5_paddat,
191 (void *)(ctxt->md5_buf + ctxt->md5_i),
192 gap - sizeof(ctxt->md5_n));
193 } else {
194 /* including gap == 8 */
195 bcopy((void *)md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
196 gap);
197 md5_calc(ctxt->md5_buf, ctxt);
198 bcopy((void *)(md5_paddat + gap),
199 (void *)ctxt->md5_buf,
200 MD5_BUFLEN - sizeof(ctxt->md5_n));
paul718e3742002-12-13 20:15:29 +0000201 }
202
vincentc1a03d42005-09-28 15:47:44 +0000203 /* 8 byte word */
204#if BYTE_ORDER == LITTLE_ENDIAN
205 bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
paul718e3742002-12-13 20:15:29 +0000206#endif
vincentc1a03d42005-09-28 15:47:44 +0000207#if BYTE_ORDER == BIG_ENDIAN
208 ctxt->md5_buf[56] = ctxt->md5_n8[7];
209 ctxt->md5_buf[57] = ctxt->md5_n8[6];
210 ctxt->md5_buf[58] = ctxt->md5_n8[5];
211 ctxt->md5_buf[59] = ctxt->md5_n8[4];
212 ctxt->md5_buf[60] = ctxt->md5_n8[3];
213 ctxt->md5_buf[61] = ctxt->md5_n8[2];
214 ctxt->md5_buf[62] = ctxt->md5_n8[1];
215 ctxt->md5_buf[63] = ctxt->md5_n8[0];
216#endif
217
218 md5_calc(ctxt->md5_buf, ctxt);
219}
220
221void md5_result(digest, ctxt)
222 u_int8_t *digest;
223 md5_ctxt *ctxt;
224{
225 /* 4 byte words */
226#if BYTE_ORDER == LITTLE_ENDIAN
227 bcopy(&ctxt->md5_st8[0], digest, 16);
228#endif
229#if BYTE_ORDER == BIG_ENDIAN
230 digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
231 digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
232 digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
233 digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
234 digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
235 digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
236 digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
237 digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
238#endif
239}
240
241#if BYTE_ORDER == BIG_ENDIAN
242u_int32_t X[16];
243#endif
244
245static void md5_calc(b64, ctxt)
246 u_int8_t *b64;
247 md5_ctxt *ctxt;
248{
249 u_int32_t A = ctxt->md5_sta;
250 u_int32_t B = ctxt->md5_stb;
251 u_int32_t C = ctxt->md5_stc;
252 u_int32_t D = ctxt->md5_std;
253#if BYTE_ORDER == LITTLE_ENDIAN
254 u_int32_t *X = (u_int32_t *)b64;
255#endif
256#if BYTE_ORDER == BIG_ENDIAN
257 /* 4 byte words */
258 /* what a brute force but fast! */
259 u_int8_t *y = (u_int8_t *)X;
260 y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
261 y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
262 y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
263 y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
264 y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
265 y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
266 y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
267 y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
268 y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
269 y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
270 y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
271 y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
272 y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
273 y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
274 y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
275 y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
276#endif
277
278 ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
279 ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
280 ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
281 ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
282 ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
283 ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
284 ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
285 ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
286
287 ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
288 ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
289 ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
290 ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
291 ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
292 ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
293 ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
294 ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
295
296 ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
297 ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
298 ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
299 ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
300 ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
301 ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
302 ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
303 ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
304
305 ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
306 ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
307 ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
308 ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
309 ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
310 ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
311 ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
312 ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
313
314 ctxt->md5_sta += A;
315 ctxt->md5_stb += B;
316 ctxt->md5_stc += C;
317 ctxt->md5_std += D;
318}