ar71xx: ag71xx: make switch register access atomic
[openwrt.git] / package / ubsec_ssb / src / md5.c
1 /* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
2 /*
3 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the project nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31 #if 0
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
34
35 #include <sys/types.h>
36 #include <sys/cdefs.h>
37 #include <sys/time.h>
38 #include <sys/systm.h>
39 #include <crypto/md5.h>
40 #endif
41
42 #define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
43
44 #define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
45 #define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
46 #define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
47 #define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
48
49 #define ROUND1(a, b, c, d, k, s, i) { \
50 (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
51 (a) = SHIFT((a), (s)); \
52 (a) = (b) + (a); \
53 }
54
55 #define ROUND2(a, b, c, d, k, s, i) { \
56 (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
57 (a) = SHIFT((a), (s)); \
58 (a) = (b) + (a); \
59 }
60
61 #define ROUND3(a, b, c, d, k, s, i) { \
62 (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
63 (a) = SHIFT((a), (s)); \
64 (a) = (b) + (a); \
65 }
66
67 #define ROUND4(a, b, c, d, k, s, i) { \
68 (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
69 (a) = SHIFT((a), (s)); \
70 (a) = (b) + (a); \
71 }
72
73 #define Sa 7
74 #define Sb 12
75 #define Sc 17
76 #define Sd 22
77
78 #define Se 5
79 #define Sf 9
80 #define Sg 14
81 #define Sh 20
82
83 #define Si 4
84 #define Sj 11
85 #define Sk 16
86 #define Sl 23
87
88 #define Sm 6
89 #define Sn 10
90 #define So 15
91 #define Sp 21
92
93 #define MD5_A0 0x67452301
94 #define MD5_B0 0xefcdab89
95 #define MD5_C0 0x98badcfe
96 #define MD5_D0 0x10325476
97
98 /* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
99 static const u_int32_t T[65] = {
100 0,
101 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
102 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
103 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
104 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
105
106 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
107 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
108 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
109 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
110
111 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
112 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
113 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
114 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
115
116 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
117 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
118 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
119 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
120 };
121
122 static const u_int8_t md5_paddat[MD5_BUFLEN] = {
123 0x80, 0, 0, 0, 0, 0, 0, 0,
124 0, 0, 0, 0, 0, 0, 0, 0,
125 0, 0, 0, 0, 0, 0, 0, 0,
126 0, 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 };
132
133 static void md5_calc(u_int8_t *, md5_ctxt *);
134
135 void md5_init(ctxt)
136 md5_ctxt *ctxt;
137 {
138 ctxt->md5_n = 0;
139 ctxt->md5_i = 0;
140 ctxt->md5_sta = MD5_A0;
141 ctxt->md5_stb = MD5_B0;
142 ctxt->md5_stc = MD5_C0;
143 ctxt->md5_std = MD5_D0;
144 bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
145 }
146
147 void md5_loop(ctxt, input, len)
148 md5_ctxt *ctxt;
149 u_int8_t *input;
150 u_int len; /* number of bytes */
151 {
152 u_int gap, i;
153
154 ctxt->md5_n += len * 8; /* byte to bit */
155 gap = MD5_BUFLEN - ctxt->md5_i;
156
157 if (len >= gap) {
158 bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
159 gap);
160 md5_calc(ctxt->md5_buf, ctxt);
161
162 for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
163 md5_calc((u_int8_t *)(input + i), ctxt);
164 }
165
166 ctxt->md5_i = len - i;
167 bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
168 } else {
169 bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
170 len);
171 ctxt->md5_i += len;
172 }
173 }
174
175 void md5_pad(ctxt)
176 md5_ctxt *ctxt;
177 {
178 u_int gap;
179
180 /* Don't count up padding. Keep md5_n. */
181 gap = MD5_BUFLEN - ctxt->md5_i;
182 if (gap > 8) {
183 bcopy(md5_paddat,
184 (void *)(ctxt->md5_buf + ctxt->md5_i),
185 gap - sizeof(ctxt->md5_n));
186 } else {
187 /* including gap == 8 */
188 bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
189 gap);
190 md5_calc(ctxt->md5_buf, ctxt);
191 bcopy((md5_paddat + gap),
192 (void *)ctxt->md5_buf,
193 MD5_BUFLEN - sizeof(ctxt->md5_n));
194 }
195
196 /* 8 byte word */
197 #if BYTE_ORDER == LITTLE_ENDIAN
198 bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
199 #endif
200 #if BYTE_ORDER == BIG_ENDIAN
201 ctxt->md5_buf[56] = ctxt->md5_n8[7];
202 ctxt->md5_buf[57] = ctxt->md5_n8[6];
203 ctxt->md5_buf[58] = ctxt->md5_n8[5];
204 ctxt->md5_buf[59] = ctxt->md5_n8[4];
205 ctxt->md5_buf[60] = ctxt->md5_n8[3];
206 ctxt->md5_buf[61] = ctxt->md5_n8[2];
207 ctxt->md5_buf[62] = ctxt->md5_n8[1];
208 ctxt->md5_buf[63] = ctxt->md5_n8[0];
209 #endif
210
211 md5_calc(ctxt->md5_buf, ctxt);
212 }
213
214 void md5_result(digest, ctxt)
215 u_int8_t *digest;
216 md5_ctxt *ctxt;
217 {
218 /* 4 byte words */
219 #if BYTE_ORDER == LITTLE_ENDIAN
220 bcopy(&ctxt->md5_st8[0], digest, 16);
221 #endif
222 #if BYTE_ORDER == BIG_ENDIAN
223 digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
224 digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
225 digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
226 digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
227 digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
228 digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
229 digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
230 digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
231 #endif
232 }
233
234 static void md5_calc(b64, ctxt)
235 u_int8_t *b64;
236 md5_ctxt *ctxt;
237 {
238 u_int32_t A = ctxt->md5_sta;
239 u_int32_t B = ctxt->md5_stb;
240 u_int32_t C = ctxt->md5_stc;
241 u_int32_t D = ctxt->md5_std;
242 #if BYTE_ORDER == LITTLE_ENDIAN
243 u_int32_t *X = (u_int32_t *)b64;
244 #endif
245 #if BYTE_ORDER == BIG_ENDIAN
246 /* 4 byte words */
247 /* what a brute force but fast! */
248 u_int32_t X[16];
249 u_int8_t *y = (u_int8_t *)X;
250 y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
251 y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
252 y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
253 y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
254 y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
255 y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
256 y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
257 y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
258 y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
259 y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
260 y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
261 y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
262 y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
263 y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
264 y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
265 y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
266 #endif
267
268 ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
269 ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
270 ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
271 ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
272 ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
273 ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
274 ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
275 ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
276
277 ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
278 ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
279 ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
280 ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
281 ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
282 ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
283 ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
284 ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
285
286 ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
287 ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
288 ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
289 ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
290 ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
291 ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
292 ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
293 ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
294
295 ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
296 ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
297 ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
298 ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
299 ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
300 ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
301 ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
302 ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
303
304 ctxt->md5_sta += A;
305 ctxt->md5_stb += B;
306 ctxt->md5_stc += C;
307 ctxt->md5_std += D;
308 }
This page took 0.072747 seconds and 5 git commands to generate.