MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / net / wireless / rtlink.org / md5.c
blobc723eb5aa605deb1f3e5cba5f2e83855eb868d4f
1 /* This MD5 code is based on code from Dynamics -- HUT Mobile IP
2 * Copyright (C) 1998-2001, Dynamics group
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. See README and COPYING for
7 * more details.
9 Module Name:
10 md5.c
12 Abstract:
13 contain MD5 and AES cipher algorithm
15 Revision History:
16 Who When What
17 -------- ---------- ----------------------------------------------
18 jan 10-28-03 Initial
20 #include "rt_config.h"
22 /**
23 * md5_mac:
24 * @key: pointer to the key used for MAC generation
25 * @key_len: length of the key in bytes
26 * @data: pointer to the data area for which the MAC is generated
27 * @data_len: length of the data in bytes
28 * @mac: pointer to the buffer holding space for the MAC; the buffer should
29 * have space for 128-bit (16 bytes) MD5 hash value
31 * md5_mac() determines the message authentication code by using secure hash
32 * MD5(key | data | key).
34 void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
36 MD5_CTX context;
38 MD5Init(&context);
39 MD5Update(&context, key, key_len);
40 MD5Update(&context, data, data_len);
41 MD5Update(&context, key, key_len);
42 MD5Final(mac, &context);
45 /**
46 * hmac_md5:
47 * @key: pointer to the key used for MAC generation
48 * @key_len: length of the key in bytes
49 * @data: pointer to the data area for which the MAC is generated
50 * @data_len: length of the data in bytes
51 * @mac: pointer to the buffer holding space for the MAC; the buffer should
52 * have space for 128-bit (16 bytes) MD5 hash value
54 * hmac_md5() determines the message authentication code using HMAC-MD5.
55 * This implementation is based on the sample code presented in RFC 2104.
57 void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
59 MD5_CTX context;
60 u8 k_ipad[65]; /* inner padding - key XORd with ipad */
61 u8 k_opad[65]; /* outer padding - key XORd with opad */
62 u8 tk[16];
63 int i;
65 //assert(key != NULL && data != NULL && mac != NULL);
67 /* if key is longer than 64 bytes reset it to key = MD5(key) */
68 if (key_len > 64) {
69 MD5_CTX ttcontext;
71 MD5Init(&ttcontext);
72 MD5Update(&ttcontext, key, key_len);
73 MD5Final(tk, &ttcontext);
74 //key=(PUCHAR)ttcontext.buf;
75 key = tk;
76 key_len = 16;
79 /* the HMAC_MD5 transform looks like:
81 * MD5(K XOR opad, MD5(K XOR ipad, text))
83 * where K is an n byte key
84 * ipad is the byte 0x36 repeated 64 times
85 * opad is the byte 0x5c repeated 64 times
86 * and text is the data being protected */
88 /* start out by storing key in pads */
89 NdisZeroMemory(k_ipad, sizeof(k_ipad));
90 NdisZeroMemory(k_opad, sizeof(k_opad));
91 //assert(key_len < sizeof(k_ipad));
92 NdisMoveMemory(k_ipad, key, key_len);
93 NdisMoveMemory(k_opad, key, key_len);
95 /* XOR key with ipad and opad values */
96 for (i = 0; i < 64; i++) {
97 k_ipad[i] ^= 0x36;
98 k_opad[i] ^= 0x5c;
101 /* perform inner MD5 */
102 MD5Init(&context); /* init context for 1st pass */
103 MD5Update(&context, k_ipad, 64); /* start with inner pad */
104 MD5Update(&context, data, data_len); /* then text of datagram */
105 MD5Final(mac, &context); /* finish up 1st pass */
107 /* perform outer MD5 */
108 MD5Init(&context); /* init context for 2nd pass */
109 MD5Update(&context, k_opad, 64); /* start with outer pad */
110 MD5Update(&context, mac, 16); /* then results of 1st hash */
111 MD5Final(mac, &context); /* finish up 2nd pass */
115 /* ===== start - public domain MD5 implementation ===== */
117 * This code implements the MD5 message-digest algorithm.
118 * The algorithm is due to Ron Rivest. This code was
119 * written by Colin Plumb in 1993, no copyright is claimed.
120 * This code is in the public domain; do with it what you wish.
122 * Equivalent code is available from RSA Data Security, Inc.
123 * This code has been tested against that, and is equivalent,
124 * except that you don't need to include two pages of legalese
125 * with every copy.
127 * To compute the message digest of a chunk of bytes, declare an
128 * MD5Context structure, pass it to MD5Init, call MD5Update as
129 * needed on buffers full of bytes, and then call MD5Final, which
130 * will fill a supplied 16-byte array with the digest.
133 #ifndef BIG_ENDIAN
134 #define byteReverse(buf, len) /* Nothing */
135 #else
136 void byteReverse(unsigned char *buf, unsigned longs);
137 void byteReverse(unsigned char *buf, unsigned longs)
139 do {
140 *(ULONG *)buf = SWAP32(*(ULONG *)buf);
141 buf += 4;
142 } while (--longs);
144 #endif
147 * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
148 * initialization constants.
150 void MD5Init(struct MD5Context *ctx)
152 ctx->buf[0] = 0x67452301;
153 ctx->buf[1] = 0xefcdab89;
154 ctx->buf[2] = 0x98badcfe;
155 ctx->buf[3] = 0x10325476;
157 ctx->bits[0] = 0;
158 ctx->bits[1] = 0;
162 * Update context to reflect the concatenation of another buffer full
163 * of bytes.
165 void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len)
167 u32 t;
169 /* Update bitcount */
171 t = ctx->bits[0];
172 if ((ctx->bits[0] = t + ((u32) len << 3)) < t)
173 ctx->bits[1]++; /* Carry from low to high */
174 ctx->bits[1] += len >> 29;
176 t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
178 /* Handle any leading odd-sized chunks */
180 if (t) {
181 unsigned char *p = (unsigned char *) ctx->in + t;
183 t = 64 - t;
184 if (len < t) {
185 NdisMoveMemory(p, buf, len);
186 return;
188 NdisMoveMemory(p, buf, t);
189 byteReverse(ctx->in, 16);
190 MD5Transform(ctx->buf, (u32 *) ctx->in);
191 buf += t;
192 len -= t;
194 /* Process data in 64-byte chunks */
196 while (len >= 64) {
197 NdisMoveMemory(ctx->in, buf, 64);
198 byteReverse(ctx->in, 16);
199 MD5Transform(ctx->buf, (u32 *) ctx->in);
200 buf += 64;
201 len -= 64;
204 /* Handle any remaining bytes of data. */
206 NdisMoveMemory(ctx->in, buf, len);
210 * Final wrapup - pad to 64-byte boundary with the bit pattern
211 * 1 0* (64-bit count of bits processed, MSB-first)
213 void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
215 unsigned count;
216 unsigned char *p;
218 /* Compute number of bytes mod 64 */
219 count = (ctx->bits[0] >> 3) & 0x3F;
221 /* Set the first char of padding to 0x80. This is safe since there is
222 always at least one byte free */
223 p = ctx->in + count;
224 *p++ = 0x80;
226 /* Bytes of padding needed to make 64 bytes */
227 count = 64 - 1 - count;
229 /* Pad out to 56 mod 64 */
230 if (count < 8) {
231 /* Two lots of padding: Pad the first block to 64 bytes */
232 NdisZeroMemory(p, count);
233 byteReverse(ctx->in, 16);
234 MD5Transform(ctx->buf, (u32 *) ctx->in);
236 /* Now fill the next block with 56 bytes */
237 NdisZeroMemory(ctx->in, 56);
238 } else {
239 /* Pad block to 56 bytes */
240 NdisZeroMemory(p, count - 8);
242 byteReverse(ctx->in, 14);
244 /* Append length in bits and transform */
245 ((u32 *) ctx->in)[14] = ctx->bits[0];
246 ((u32 *) ctx->in)[15] = ctx->bits[1];
248 MD5Transform(ctx->buf, (u32 *) ctx->in);
249 byteReverse((unsigned char *) ctx->buf, 4);
250 NdisMoveMemory(digest, ctx->buf, 16);
251 NdisZeroMemory(ctx, sizeof(ctx)); /* In case it's sensitive */
254 //#ifndef ASM_MD5
255 #if 1
257 /* The four core functions - F1 is optimized somewhat */
259 /* #define F1(x, y, z) (x & y | ~x & z) */
260 #define F1(x, y, z) (z ^ (x & (y ^ z)))
261 #define F2(x, y, z) F1(z, x, y)
262 #define F3(x, y, z) (x ^ y ^ z)
263 #define F4(x, y, z) (y ^ (x | ~z))
265 /* This is the central step in the MD5 algorithm. */
266 #define MD5STEP(f, w, x, y, z, data, s) \
267 ( w += f(x, y, z) + data, w =( w<<s | w>>(32-s))&0xffffffff, w += x )
270 * The core of the MD5 algorithm, this alters an existing MD5 hash to
271 * reflect the addition of 16 longwords of new data. MD5Update blocks
272 * the data and converts bytes into longwords for this routine.
274 void MD5Transform(u32 buf[4], u32 in[16])
276 register u32 a, b, c, d;
278 a = buf[0];
279 b = buf[1];
280 c = buf[2];
281 d = buf[3];
283 MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
284 MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
285 MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
286 MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
287 MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
288 MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
289 MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
290 MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
291 MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
292 MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
293 MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
294 MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
295 MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
296 MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
297 MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
298 MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
300 MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
301 MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
302 MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
303 MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
304 MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
305 MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
306 MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
307 MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
308 MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
309 MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
310 MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
311 MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
312 MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
313 MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
314 MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
315 MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
317 MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
318 MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
319 MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
320 MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
321 MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
322 MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
323 MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
324 MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
325 MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
326 MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
327 MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
328 MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
329 MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
330 MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
331 MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
332 MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
334 MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
335 MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
336 MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
337 MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
338 MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
339 MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
340 MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
341 MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
342 MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
343 MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
344 MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
345 MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
346 MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
347 MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
348 MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
349 MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
351 buf[0] += a;
352 buf[1] += b;
353 buf[2] += c;
354 buf[3] += d;
356 #endif
358 void SHAInit(SHA_CTX *ctx) {
359 int i;
361 ctx->lenW = 0;
362 ctx->sizeHi = ctx->sizeLo = 0;
364 /* Initialize H with the magic constants (see FIPS180 for constants)
366 ctx->H[0] = 0x67452301L;
367 ctx->H[1] = 0xefcdab89L;
368 ctx->H[2] = 0x98badcfeL;
369 ctx->H[3] = 0x10325476L;
370 ctx->H[4] = 0xc3d2e1f0L;
372 for (i = 0; i < 80; i++)
373 ctx->W[i] = 0;
376 #define SHA_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xffffffffL)
378 void SHAHashBlock(SHA_CTX *ctx) {
379 int t;
380 unsigned long A,B,C,D,E,TEMP;
382 for (t = 16; t <= 79; t++)
383 ctx->W[t] = SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
385 A = ctx->H[0];
386 B = ctx->H[1];
387 C = ctx->H[2];
388 D = ctx->H[3];
389 E = ctx->H[4];
391 for (t = 0; t <= 19; t++) {
392 TEMP = (SHA_ROTL(A,5) + (((C^D)&B)^D) + E + ctx->W[t] + 0x5a827999L) & 0xffffffffL;
393 E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
395 for (t = 20; t <= 39; t++) {
396 TEMP = (SHA_ROTL(A,5) + (B^C^D) + E + ctx->W[t] + 0x6ed9eba1L) & 0xffffffffL;
397 E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
399 for (t = 40; t <= 59; t++) {
400 TEMP = (SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL) & 0xffffffffL;
401 E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
403 for (t = 60; t <= 79; t++) {
404 TEMP = (SHA_ROTL(A,5) + (B^C^D) + E + ctx->W[t] + 0xca62c1d6L) & 0xffffffffL;
405 E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
408 ctx->H[0] += A;
409 ctx->H[1] += B;
410 ctx->H[2] += C;
411 ctx->H[3] += D;
412 ctx->H[4] += E;
415 void SHAUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len)
417 int i;
419 /* Read the data into W and process blocks as they get full
421 for (i = 0; i < len; i++) {
422 ctx->W[ctx->lenW / 4] <<= 8;
423 ctx->W[ctx->lenW / 4] |= (unsigned long)dataIn[i];
424 if ((++ctx->lenW) % 64 == 0) {
425 SHAHashBlock(ctx);
426 ctx->lenW = 0;
428 ctx->sizeLo += 8;
429 ctx->sizeHi += (ctx->sizeLo < 8);
434 void SHAFinal(SHA_CTX *ctx, unsigned char hashout[20]) {
435 unsigned char pad0x80 = 0x80;
436 unsigned char pad0x00 = 0x00;
437 unsigned char padlen[8];
438 int i;
440 /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
442 padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
443 padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
444 padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
445 padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
446 padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
447 padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
448 padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
449 padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
450 SHAUpdate(ctx, &pad0x80, 1);
451 while (ctx->lenW != 56)
452 SHAUpdate(ctx, &pad0x00, 1);
453 SHAUpdate(ctx, padlen, 8);
455 /* Output hash
457 for (i = 0; i < 20; i++) {
458 hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
459 ctx->H[i / 4] <<= 8;
463 * Re-initialize the context (also zeroizes contents)
465 SHAInit(ctx);
468 /* forward S-box */
470 static uint32 FSb[256] =
472 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
473 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
474 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
475 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
476 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
477 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
478 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
479 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
480 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
481 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
482 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
483 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
484 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
485 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
486 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
487 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
488 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
489 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
490 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
491 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
492 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
493 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
494 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
495 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
496 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
497 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
498 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
499 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
500 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
501 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
502 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
503 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
506 /* forward table */
508 #define FT \
510 V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
511 V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
512 V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
513 V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
514 V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
515 V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
516 V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
517 V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
518 V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
519 V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
520 V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
521 V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
522 V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
523 V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
524 V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
525 V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
526 V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
527 V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
528 V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
529 V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
530 V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
531 V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
532 V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
533 V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
534 V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
535 V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
536 V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
537 V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
538 V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
539 V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
540 V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
541 V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
542 V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
543 V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
544 V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
545 V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
546 V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
547 V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
548 V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
549 V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
550 V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
551 V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
552 V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
553 V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
554 V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
555 V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
556 V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
557 V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
558 V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
559 V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
560 V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
561 V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
562 V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
563 V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
564 V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
565 V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
566 V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
567 V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
568 V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
569 V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
570 V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
571 V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
572 V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
573 V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
575 #define V(a,b,c,d) 0x##a##b##c##d
576 static uint32 FT0[256] = { FT };
577 #undef V
579 #define V(a,b,c,d) 0x##d##a##b##c
580 static uint32 FT1[256] = { FT };
581 #undef V
583 #define V(a,b,c,d) 0x##c##d##a##b
584 static uint32 FT2[256] = { FT };
585 #undef V
587 #define V(a,b,c,d) 0x##b##c##d##a
588 static uint32 FT3[256] = { FT };
589 #undef V
591 #undef FT
593 /* reverse S-box */
595 static uint32 RSb[256] =
597 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
598 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
599 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
600 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
601 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
602 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
603 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
604 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
605 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
606 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
607 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
608 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
609 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
610 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
611 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
612 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
613 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
614 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
615 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
616 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
617 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
618 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
619 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
620 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
621 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
622 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
623 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
624 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
625 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
626 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
627 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
628 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
631 /* reverse table */
633 #define RT \
635 V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
636 V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
637 V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
638 V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
639 V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
640 V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
641 V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
642 V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
643 V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
644 V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
645 V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
646 V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
647 V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
648 V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
649 V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
650 V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
651 V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
652 V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
653 V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
654 V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
655 V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
656 V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
657 V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
658 V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
659 V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
660 V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
661 V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
662 V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
663 V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
664 V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
665 V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
666 V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
667 V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
668 V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
669 V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
670 V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
671 V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
672 V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
673 V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
674 V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
675 V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
676 V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
677 V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
678 V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
679 V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
680 V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
681 V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
682 V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
683 V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
684 V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
685 V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
686 V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
687 V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
688 V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
689 V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
690 V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
691 V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
692 V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
693 V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
694 V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
695 V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
696 V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
697 V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
698 V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
700 #define V(a,b,c,d) 0x##a##b##c##d
701 static uint32 RT0[256] = { RT };
702 #undef V
704 #define V(a,b,c,d) 0x##d##a##b##c
705 static uint32 RT1[256] = { RT };
706 #undef V
708 #define V(a,b,c,d) 0x##c##d##a##b
709 static uint32 RT2[256] = { RT };
710 #undef V
712 #define V(a,b,c,d) 0x##b##c##d##a
713 static uint32 RT3[256] = { RT };
714 #undef V
716 #undef RT
718 /* round constants */
720 static uint32 RCON[10] =
722 0x01000000, 0x02000000, 0x04000000, 0x08000000,
723 0x10000000, 0x20000000, 0x40000000, 0x80000000,
724 0x1B000000, 0x36000000
727 /* key schedule tables */
729 static int KT_init = 1;
731 static uint32 KT0[256];
732 static uint32 KT1[256];
733 static uint32 KT2[256];
734 static uint32 KT3[256];
736 /* platform-independant 32-bit integer manipulation macros */
738 #define GET_UINT32(n,b,i) \
740 (n) = ( (uint32) (b)[(i) ] << 24 ) \
741 | ( (uint32) (b)[(i) + 1] << 16 ) \
742 | ( (uint32) (b)[(i) + 2] << 8 ) \
743 | ( (uint32) (b)[(i) + 3] ); \
746 #define PUT_UINT32(n,b,i) \
748 (b)[(i) ] = (uint8) ( (n) >> 24 ); \
749 (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
750 (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
751 (b)[(i) + 3] = (uint8) ( (n) ); \
754 /* AES key scheduling routine */
756 int aes_set_key( aes_context *ctx, uint8 *key, int nbits )
758 int i;
759 uint32 *RK, *SK;
761 switch( nbits )
763 case 128: ctx->nr = 10; break;
764 case 192: ctx->nr = 12; break;
765 case 256: ctx->nr = 14; break;
766 default : return( 1 );
769 RK = ctx->erk;
771 for( i = 0; i < (nbits >> 5); i++ )
773 GET_UINT32( RK[i], key, i * 4 );
776 /* setup encryption round keys */
778 switch( nbits )
780 case 128:
782 for( i = 0; i < 10; i++, RK += 4 )
784 RK[4] = RK[0] ^ RCON[i] ^
785 ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^
786 ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^
787 ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^
788 ( FSb[ (uint8) ( RK[3] >> 24 ) ] );
790 RK[5] = RK[1] ^ RK[4];
791 RK[6] = RK[2] ^ RK[5];
792 RK[7] = RK[3] ^ RK[6];
794 break;
796 case 192:
798 for( i = 0; i < 8; i++, RK += 6 )
800 RK[6] = RK[0] ^ RCON[i] ^
801 ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^
802 ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^
803 ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^
804 ( FSb[ (uint8) ( RK[5] >> 24 ) ] );
806 RK[7] = RK[1] ^ RK[6];
807 RK[8] = RK[2] ^ RK[7];
808 RK[9] = RK[3] ^ RK[8];
809 RK[10] = RK[4] ^ RK[9];
810 RK[11] = RK[5] ^ RK[10];
812 break;
814 case 256:
816 for( i = 0; i < 7; i++, RK += 8 )
818 RK[8] = RK[0] ^ RCON[i] ^
819 ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^
820 ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^
821 ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^
822 ( FSb[ (uint8) ( RK[7] >> 24 ) ] );
824 RK[9] = RK[1] ^ RK[8];
825 RK[10] = RK[2] ^ RK[9];
826 RK[11] = RK[3] ^ RK[10];
828 RK[12] = RK[4] ^
829 ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^
830 ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^
831 ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^
832 ( FSb[ (uint8) ( RK[11] ) ] );
834 RK[13] = RK[5] ^ RK[12];
835 RK[14] = RK[6] ^ RK[13];
836 RK[15] = RK[7] ^ RK[14];
838 break;
841 /* setup decryption round keys */
843 if( KT_init )
845 for( i = 0; i < 256; i++ )
847 KT0[i] = RT0[ FSb[i] ];
848 KT1[i] = RT1[ FSb[i] ];
849 KT2[i] = RT2[ FSb[i] ];
850 KT3[i] = RT3[ FSb[i] ];
853 KT_init = 0;
856 SK = ctx->drk;
858 *SK++ = *RK++;
859 *SK++ = *RK++;
860 *SK++ = *RK++;
861 *SK++ = *RK++;
863 for( i = 1; i < ctx->nr; i++ )
865 RK -= 8;
867 *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
868 KT1[ (uint8) ( *RK >> 16 ) ] ^
869 KT2[ (uint8) ( *RK >> 8 ) ] ^
870 KT3[ (uint8) ( *RK ) ]; RK++;
872 *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
873 KT1[ (uint8) ( *RK >> 16 ) ] ^
874 KT2[ (uint8) ( *RK >> 8 ) ] ^
875 KT3[ (uint8) ( *RK ) ]; RK++;
877 *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
878 KT1[ (uint8) ( *RK >> 16 ) ] ^
879 KT2[ (uint8) ( *RK >> 8 ) ] ^
880 KT3[ (uint8) ( *RK ) ]; RK++;
882 *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
883 KT1[ (uint8) ( *RK >> 16 ) ] ^
884 KT2[ (uint8) ( *RK >> 8 ) ] ^
885 KT3[ (uint8) ( *RK ) ]; RK++;
888 RK -= 8;
890 *SK++ = *RK++;
891 *SK++ = *RK++;
892 *SK++ = *RK++;
893 *SK++ = *RK++;
895 return( 0 );
898 /* AES 128-bit block encryption routine */
900 void aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] )
902 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
904 RK = ctx->erk;
905 GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
906 GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
907 GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
908 GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
910 #define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
912 RK += 4; \
914 X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \
915 FT1[ (uint8) ( Y1 >> 16 ) ] ^ \
916 FT2[ (uint8) ( Y2 >> 8 ) ] ^ \
917 FT3[ (uint8) ( Y3 ) ]; \
919 X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \
920 FT1[ (uint8) ( Y2 >> 16 ) ] ^ \
921 FT2[ (uint8) ( Y3 >> 8 ) ] ^ \
922 FT3[ (uint8) ( Y0 ) ]; \
924 X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \
925 FT1[ (uint8) ( Y3 >> 16 ) ] ^ \
926 FT2[ (uint8) ( Y0 >> 8 ) ] ^ \
927 FT3[ (uint8) ( Y1 ) ]; \
929 X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \
930 FT1[ (uint8) ( Y0 >> 16 ) ] ^ \
931 FT2[ (uint8) ( Y1 >> 8 ) ] ^ \
932 FT3[ (uint8) ( Y2 ) ]; \
935 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
936 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
937 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
938 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
939 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
940 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
941 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
942 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
943 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
945 if( ctx->nr > 10 )
947 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
948 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
951 if( ctx->nr > 12 )
953 AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
954 AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
957 /* last round */
959 RK += 4;
961 X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^
962 ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^
963 ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^
964 ( FSb[ (uint8) ( Y3 ) ] );
966 X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^
967 ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^
968 ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^
969 ( FSb[ (uint8) ( Y0 ) ] );
971 X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^
972 ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^
973 ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^
974 ( FSb[ (uint8) ( Y1 ) ] );
976 X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^
977 ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^
978 ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^
979 ( FSb[ (uint8) ( Y2 ) ] );
981 PUT_UINT32( X0, output, 0 );
982 PUT_UINT32( X1, output, 4 );
983 PUT_UINT32( X2, output, 8 );
984 PUT_UINT32( X3, output, 12 );
987 /* AES 128-bit block decryption routine */
989 void aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] )
991 uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
993 RK = ctx->drk;
995 GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
996 GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
997 GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
998 GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
1000 #define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
1002 RK += 4; \
1004 X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \
1005 RT1[ (uint8) ( Y3 >> 16 ) ] ^ \
1006 RT2[ (uint8) ( Y2 >> 8 ) ] ^ \
1007 RT3[ (uint8) ( Y1 ) ]; \
1009 X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \
1010 RT1[ (uint8) ( Y0 >> 16 ) ] ^ \
1011 RT2[ (uint8) ( Y3 >> 8 ) ] ^ \
1012 RT3[ (uint8) ( Y2 ) ]; \
1014 X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \
1015 RT1[ (uint8) ( Y1 >> 16 ) ] ^ \
1016 RT2[ (uint8) ( Y0 >> 8 ) ] ^ \
1017 RT3[ (uint8) ( Y3 ) ]; \
1019 X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \
1020 RT1[ (uint8) ( Y2 >> 16 ) ] ^ \
1021 RT2[ (uint8) ( Y1 >> 8 ) ] ^ \
1022 RT3[ (uint8) ( Y0 ) ]; \
1025 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
1026 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
1027 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
1028 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
1029 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
1030 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
1031 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
1032 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
1033 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
1035 if( ctx->nr > 10 )
1037 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
1038 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
1041 if( ctx->nr > 12 )
1043 AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
1044 AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
1047 /* last round */
1049 RK += 4;
1051 X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^
1052 ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^
1053 ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^
1054 ( RSb[ (uint8) ( Y1 ) ] );
1056 X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^
1057 ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^
1058 ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^
1059 ( RSb[ (uint8) ( Y2 ) ] );
1061 X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^
1062 ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^
1063 ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^
1064 ( RSb[ (uint8) ( Y3 ) ] );
1066 X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^
1067 ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^
1068 ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^
1069 ( RSb[ (uint8) ( Y0 ) ] );
1071 PUT_UINT32( X0, output, 0 );
1072 PUT_UINT32( X1, output, 4 );
1073 PUT_UINT32( X2, output, 8 );
1074 PUT_UINT32( X3, output, 12 );
1077 void hmac_sha1(unsigned char *text, int text_len, unsigned char *key, int key_len, unsigned char *digest)
1079 SHA_CTX context;
1080 unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
1081 unsigned char k_opad[65]; /* outer padding - key XORd with opad */
1082 int i;
1084 /* if key is longer than 64 bytes reset it to key=SHA1(key) */
1085 if (key_len > 64)
1087 SHA_CTX tctx;
1089 SHAInit(&tctx);
1090 SHAUpdate(&tctx, key, key_len);
1091 SHAFinal(&tctx, key);
1093 key_len = 20;
1097 * the HMAC_SHA1 transform looks like:
1099 * SHA1(K XOR opad, SHA1(K XOR ipad, text))
1101 * where K is an n byte key
1102 * ipad is the byte 0x36 repeated 64 times
1103 * opad is the byte 0x5c repeated 64 times
1104 * and text is the data being protected
1107 /* start out by storing key in pads */
1108 memset(k_ipad, 0, sizeof k_ipad);
1109 memset(k_opad, 0, sizeof k_opad);
1110 memcpy(k_ipad, key, key_len);
1111 memcpy(k_opad, key, key_len);
1113 /* XOR key with ipad and opad values */
1114 for (i = 0; i < 64; i++)
1116 k_ipad[i] ^= 0x36;
1117 k_opad[i] ^= 0x5c;
1120 /* perform inner SHA1*/
1121 SHAInit(&context); /* init context for 1st pass */
1122 SHAUpdate(&context, k_ipad, 64); /* start with inner pad */
1123 SHAUpdate(&context, text, text_len); /* then text of datagram */
1124 SHAFinal(&context, digest); /* finish up 1st pass */
1126 /* perform outer SHA1 */
1127 SHAInit(&context); /* init context for 2nd pass */
1128 SHAUpdate(&context, k_opad, 64); /* start with outer pad */
1129 SHAUpdate(&context, digest, 20); /* then results of 1st hash */
1130 SHAFinal(&context, digest); /* finish up 2nd pass */
1134 * F(P, S, c, i) = U1 xor U2 xor ... Uc
1135 * U1 = PRF(P, S || Int(i))
1136 * U2 = PRF(P, U1)
1137 * Uc = PRF(P, Uc-1)
1140 void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
1142 unsigned char digest[36], digest1[SHA_DIGEST_LEN];
1143 int i, j;
1145 /* U1 = PRF(P, S || int(i)) */
1146 memcpy(digest, ssid, ssidlength);
1147 digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
1148 digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
1149 digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
1150 digest[ssidlength+3] = (unsigned char)(count & 0xff);
1151 hmac_sha1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update
1153 /* output = U1 */
1154 memcpy(output, digest1, SHA_DIGEST_LEN);
1156 for (i = 1; i < iterations; i++)
1158 /* Un = PRF(P, Un-1) */
1159 hmac_sha1(digest1, SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update
1160 memcpy(digest1, digest, SHA_DIGEST_LEN);
1162 /* output = output xor Un */
1163 for (j = 0; j < SHA_DIGEST_LEN; j++)
1165 output[j] ^= digest[j];
1170 * password - ascii string up to 63 characters in length
1171 * ssid - octet string up to 32 octets
1172 * ssidlength - length of ssid in octets
1173 * output must be 40 octets in length and outputs 256 bits of key
1175 int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output)
1177 if ((strlen(password) > 63) || (ssidlength > 32))
1178 return 0;
1180 F(password, ssid, ssidlength, 4096, 1, output);
1181 F(password, ssid, ssidlength, 4096, 2, &output[SHA_DIGEST_LEN]);
1182 return 1;