Annotation of src/usr.bin/ssh/rijndael.c, Revision 1.4
1.3 markus 1: /*
2: * rijndael-alg-fst.c v2.4 April '2000
3: * rijndael-alg-api.c v2.4 April '2000
4: *
5: * Optimised ANSI C code
6: *
7: * authors: v1.0: Antoon Bosselaers
8: * v2.0: Vincent Rijmen, K.U.Leuven
9: * v2.3: Paulo Barreto
10: * v2.4: Vincent Rijmen, K.U.Leuven
11: *
12: * This code is placed in the public domain.
13: */
14:
15: #include <stdio.h>
16: #include <stdlib.h>
17: #include <assert.h>
1.1 markus 18:
19: #include "rijndael.h"
1.3 markus 20: #include "rijndael_boxes.h"
1.1 markus 21:
1.3 markus 22: int
23: rijndael_keysched(u_int8_t k[RIJNDAEL_MAXKC][4],
24: u_int8_t W[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS)
1.1 markus 25: {
1.3 markus 26: /* Calculate the necessary round keys
27: * The number of calculations depends on keyBits and blockBits
28: */
29: int j, r, t, rconpointer = 0;
30: u_int8_t tk[RIJNDAEL_MAXKC][4];
31: int KC = ROUNDS - 6;
1.1 markus 32:
1.3 markus 33: for (j = KC-1; j >= 0; j--) {
34: *((u_int32_t*)tk[j]) = *((u_int32_t*)k[j]);
1.1 markus 35: }
1.3 markus 36: r = 0;
37: t = 0;
38: /* copy values into round key array */
39: for (j = 0; (j < KC) && (r < ROUNDS + 1); ) {
40: for (; (j < KC) && (t < 4); j++, t++) {
41: *((u_int32_t*)W[r][t]) = *((u_int32_t*)tk[j]);
42: }
43: if (t == 4) {
44: r++;
45: t = 0;
46: }
1.1 markus 47: }
1.3 markus 48:
49: while (r < ROUNDS + 1) { /* while not enough round key material calculated */
50: /* calculate new values */
51: tk[0][0] ^= S[tk[KC-1][1]];
52: tk[0][1] ^= S[tk[KC-1][2]];
53: tk[0][2] ^= S[tk[KC-1][3]];
54: tk[0][3] ^= S[tk[KC-1][0]];
55: tk[0][0] ^= rcon[rconpointer++];
56:
57: if (KC != 8) {
58: for (j = 1; j < KC; j++) {
59: *((u_int32_t*)tk[j]) ^= *((u_int32_t*)tk[j-1]);
60: }
61: } else {
62: for (j = 1; j < KC/2; j++) {
63: *((u_int32_t*)tk[j]) ^= *((u_int32_t*)tk[j-1]);
64: }
65: tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
66: tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
67: tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
68: tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
69: for (j = KC/2 + 1; j < KC; j++) {
70: *((u_int32_t*)tk[j]) ^= *((u_int32_t*)tk[j-1]);
71: }
72: }
73: /* copy values into round key array */
74: for (j = 0; (j < KC) && (r < ROUNDS + 1); ) {
75: for (; (j < KC) && (t < 4); j++, t++) {
76: *((u_int32_t*)W[r][t]) = *((u_int32_t*)tk[j]);
77: }
78: if (t == 4) {
79: r++;
80: t = 0;
81: }
82: }
83: }
84: return 0;
1.2 markus 85: }
1.1 markus 86:
1.3 markus 87: int
88: rijndael_key_enc_to_dec(u_int8_t W[RIJNDAEL_MAXROUNDS+1][4][4], int ROUNDS)
89: {
90: int r;
91: u_int8_t *w;
1.1 markus 92:
1.3 markus 93: for (r = 1; r < ROUNDS; r++) {
94: w = W[r][0];
95: *((u_int32_t*)w) = *((u_int32_t*)U1[w[0]])
96: ^ *((u_int32_t*)U2[w[1]])
97: ^ *((u_int32_t*)U3[w[2]])
98: ^ *((u_int32_t*)U4[w[3]]);
99:
100: w = W[r][1];
101: *((u_int32_t*)w) = *((u_int32_t*)U1[w[0]])
102: ^ *((u_int32_t*)U2[w[1]])
103: ^ *((u_int32_t*)U3[w[2]])
104: ^ *((u_int32_t*)U4[w[3]]);
105:
106: w = W[r][2];
107: *((u_int32_t*)w) = *((u_int32_t*)U1[w[0]])
108: ^ *((u_int32_t*)U2[w[1]])
109: ^ *((u_int32_t*)U3[w[2]])
110: ^ *((u_int32_t*)U4[w[3]]);
111:
112: w = W[r][3];
113: *((u_int32_t*)w) = *((u_int32_t*)U1[w[0]])
114: ^ *((u_int32_t*)U2[w[1]])
115: ^ *((u_int32_t*)U3[w[2]])
116: ^ *((u_int32_t*)U4[w[3]]);
1.1 markus 117: }
1.3 markus 118: return 0;
119: }
1.1 markus 120:
1.3 markus 121: /**
122: * Encrypt a single block.
123: */
124: int
125: rijndael_encrypt(rijndael_key *key, u_int8_t a[16], u_int8_t b[16])
126: {
127: u_int8_t (*rk)[4][4] = key->keySched;
128: int ROUNDS = key->ROUNDS;
129: int r;
130: u_int8_t temp[4][4];
131:
132: *((u_int32_t*)temp[0]) = *((u_int32_t*)(a )) ^ *((u_int32_t*)rk[0][0]);
133: *((u_int32_t*)temp[1]) = *((u_int32_t*)(a+ 4)) ^ *((u_int32_t*)rk[0][1]);
134: *((u_int32_t*)temp[2]) = *((u_int32_t*)(a+ 8)) ^ *((u_int32_t*)rk[0][2]);
135: *((u_int32_t*)temp[3]) = *((u_int32_t*)(a+12)) ^ *((u_int32_t*)rk[0][3]);
136: *((u_int32_t*)(b )) = *((u_int32_t*)T1[temp[0][0]])
137: ^ *((u_int32_t*)T2[temp[1][1]])
138: ^ *((u_int32_t*)T3[temp[2][2]])
139: ^ *((u_int32_t*)T4[temp[3][3]]);
140: *((u_int32_t*)(b + 4)) = *((u_int32_t*)T1[temp[1][0]])
141: ^ *((u_int32_t*)T2[temp[2][1]])
142: ^ *((u_int32_t*)T3[temp[3][2]])
143: ^ *((u_int32_t*)T4[temp[0][3]]);
144: *((u_int32_t*)(b + 8)) = *((u_int32_t*)T1[temp[2][0]])
145: ^ *((u_int32_t*)T2[temp[3][1]])
146: ^ *((u_int32_t*)T3[temp[0][2]])
147: ^ *((u_int32_t*)T4[temp[1][3]]);
148: *((u_int32_t*)(b +12)) = *((u_int32_t*)T1[temp[3][0]])
149: ^ *((u_int32_t*)T2[temp[0][1]])
150: ^ *((u_int32_t*)T3[temp[1][2]])
151: ^ *((u_int32_t*)T4[temp[2][3]]);
152: for (r = 1; r < ROUNDS-1; r++) {
153: *((u_int32_t*)temp[0]) = *((u_int32_t*)(b )) ^ *((u_int32_t*)rk[r][0]);
154: *((u_int32_t*)temp[1]) = *((u_int32_t*)(b+ 4)) ^ *((u_int32_t*)rk[r][1]);
155: *((u_int32_t*)temp[2]) = *((u_int32_t*)(b+ 8)) ^ *((u_int32_t*)rk[r][2]);
156: *((u_int32_t*)temp[3]) = *((u_int32_t*)(b+12)) ^ *((u_int32_t*)rk[r][3]);
157:
158: *((u_int32_t*)(b )) = *((u_int32_t*)T1[temp[0][0]])
159: ^ *((u_int32_t*)T2[temp[1][1]])
160: ^ *((u_int32_t*)T3[temp[2][2]])
161: ^ *((u_int32_t*)T4[temp[3][3]]);
162: *((u_int32_t*)(b + 4)) = *((u_int32_t*)T1[temp[1][0]])
163: ^ *((u_int32_t*)T2[temp[2][1]])
164: ^ *((u_int32_t*)T3[temp[3][2]])
165: ^ *((u_int32_t*)T4[temp[0][3]]);
166: *((u_int32_t*)(b + 8)) = *((u_int32_t*)T1[temp[2][0]])
167: ^ *((u_int32_t*)T2[temp[3][1]])
168: ^ *((u_int32_t*)T3[temp[0][2]])
169: ^ *((u_int32_t*)T4[temp[1][3]]);
170: *((u_int32_t*)(b +12)) = *((u_int32_t*)T1[temp[3][0]])
171: ^ *((u_int32_t*)T2[temp[0][1]])
172: ^ *((u_int32_t*)T3[temp[1][2]])
173: ^ *((u_int32_t*)T4[temp[2][3]]);
1.1 markus 174: }
1.3 markus 175: /* last round is special */
176: *((u_int32_t*)temp[0]) = *((u_int32_t*)(b )) ^ *((u_int32_t*)rk[ROUNDS-1][0]);
177: *((u_int32_t*)temp[1]) = *((u_int32_t*)(b+ 4)) ^ *((u_int32_t*)rk[ROUNDS-1][1]);
178: *((u_int32_t*)temp[2]) = *((u_int32_t*)(b+ 8)) ^ *((u_int32_t*)rk[ROUNDS-1][2]);
179: *((u_int32_t*)temp[3]) = *((u_int32_t*)(b+12)) ^ *((u_int32_t*)rk[ROUNDS-1][3]);
180: b[ 0] = T1[temp[0][0]][1];
181: b[ 1] = T1[temp[1][1]][1];
182: b[ 2] = T1[temp[2][2]][1];
183: b[ 3] = T1[temp[3][3]][1];
184: b[ 4] = T1[temp[1][0]][1];
185: b[ 5] = T1[temp[2][1]][1];
186: b[ 6] = T1[temp[3][2]][1];
187: b[ 7] = T1[temp[0][3]][1];
188: b[ 8] = T1[temp[2][0]][1];
189: b[ 9] = T1[temp[3][1]][1];
190: b[10] = T1[temp[0][2]][1];
191: b[11] = T1[temp[1][3]][1];
192: b[12] = T1[temp[3][0]][1];
193: b[13] = T1[temp[0][1]][1];
194: b[14] = T1[temp[1][2]][1];
195: b[15] = T1[temp[2][3]][1];
196: *((u_int32_t*)(b )) ^= *((u_int32_t*)rk[ROUNDS][0]);
197: *((u_int32_t*)(b+ 4)) ^= *((u_int32_t*)rk[ROUNDS][1]);
198: *((u_int32_t*)(b+ 8)) ^= *((u_int32_t*)rk[ROUNDS][2]);
199: *((u_int32_t*)(b+12)) ^= *((u_int32_t*)rk[ROUNDS][3]);
1.1 markus 200:
1.3 markus 201: return 0;
1.2 markus 202: }
1.1 markus 203:
1.3 markus 204: /**
205: * Decrypt a single block.
206: */
207: int
208: rijndael_decrypt(rijndael_key *key, u_int8_t a[16], u_int8_t b[16])
209: {
210: u_int8_t (*rk)[4][4] = key->keySched;
211: int ROUNDS = key->ROUNDS;
212: int r;
213: u_int8_t temp[4][4];
214:
215: *((u_int32_t*)temp[0]) = *((u_int32_t*)(a )) ^ *((u_int32_t*)rk[ROUNDS][0]);
216: *((u_int32_t*)temp[1]) = *((u_int32_t*)(a+ 4)) ^ *((u_int32_t*)rk[ROUNDS][1]);
217: *((u_int32_t*)temp[2]) = *((u_int32_t*)(a+ 8)) ^ *((u_int32_t*)rk[ROUNDS][2]);
218: *((u_int32_t*)temp[3]) = *((u_int32_t*)(a+12)) ^ *((u_int32_t*)rk[ROUNDS][3]);
219:
220: *((u_int32_t*)(b )) = *((u_int32_t*)T5[temp[0][0]])
221: ^ *((u_int32_t*)T6[temp[3][1]])
1.4 ! markus 222: ^ *((u_int32_t*)T7[temp[2][2]])
! 223: ^ *((u_int32_t*)T8[temp[1][3]]);
1.3 markus 224: *((u_int32_t*)(b+ 4)) = *((u_int32_t*)T5[temp[1][0]])
1.4 ! markus 225: ^ *((u_int32_t*)T6[temp[0][1]])
! 226: ^ *((u_int32_t*)T7[temp[3][2]])
! 227: ^ *((u_int32_t*)T8[temp[2][3]]);
1.3 markus 228: *((u_int32_t*)(b+ 8)) = *((u_int32_t*)T5[temp[2][0]])
1.4 ! markus 229: ^ *((u_int32_t*)T6[temp[1][1]])
! 230: ^ *((u_int32_t*)T7[temp[0][2]])
! 231: ^ *((u_int32_t*)T8[temp[3][3]]);
1.3 markus 232: *((u_int32_t*)(b+12)) = *((u_int32_t*)T5[temp[3][0]])
1.4 ! markus 233: ^ *((u_int32_t*)T6[temp[2][1]])
! 234: ^ *((u_int32_t*)T7[temp[1][2]])
! 235: ^ *((u_int32_t*)T8[temp[0][3]]);
1.3 markus 236: for (r = ROUNDS-1; r > 1; r--) {
237: *((u_int32_t*)temp[0]) = *((u_int32_t*)(b )) ^ *((u_int32_t*)rk[r][0]);
238: *((u_int32_t*)temp[1]) = *((u_int32_t*)(b+ 4)) ^ *((u_int32_t*)rk[r][1]);
239: *((u_int32_t*)temp[2]) = *((u_int32_t*)(b+ 8)) ^ *((u_int32_t*)rk[r][2]);
240: *((u_int32_t*)temp[3]) = *((u_int32_t*)(b+12)) ^ *((u_int32_t*)rk[r][3]);
241: *((u_int32_t*)(b )) = *((u_int32_t*)T5[temp[0][0]])
1.4 ! markus 242: ^ *((u_int32_t*)T6[temp[3][1]])
! 243: ^ *((u_int32_t*)T7[temp[2][2]])
! 244: ^ *((u_int32_t*)T8[temp[1][3]]);
1.3 markus 245: *((u_int32_t*)(b+ 4)) = *((u_int32_t*)T5[temp[1][0]])
1.4 ! markus 246: ^ *((u_int32_t*)T6[temp[0][1]])
! 247: ^ *((u_int32_t*)T7[temp[3][2]])
! 248: ^ *((u_int32_t*)T8[temp[2][3]]);
1.3 markus 249: *((u_int32_t*)(b+ 8)) = *((u_int32_t*)T5[temp[2][0]])
1.4 ! markus 250: ^ *((u_int32_t*)T6[temp[1][1]])
! 251: ^ *((u_int32_t*)T7[temp[0][2]])
! 252: ^ *((u_int32_t*)T8[temp[3][3]]);
1.3 markus 253: *((u_int32_t*)(b+12)) = *((u_int32_t*)T5[temp[3][0]])
1.4 ! markus 254: ^ *((u_int32_t*)T6[temp[2][1]])
! 255: ^ *((u_int32_t*)T7[temp[1][2]])
! 256: ^ *((u_int32_t*)T8[temp[0][3]]);
1.1 markus 257: }
1.3 markus 258: /* last round is special */
259: *((u_int32_t*)temp[0]) = *((u_int32_t*)(b )) ^ *((u_int32_t*)rk[1][0]);
260: *((u_int32_t*)temp[1]) = *((u_int32_t*)(b+ 4)) ^ *((u_int32_t*)rk[1][1]);
261: *((u_int32_t*)temp[2]) = *((u_int32_t*)(b+ 8)) ^ *((u_int32_t*)rk[1][2]);
262: *((u_int32_t*)temp[3]) = *((u_int32_t*)(b+12)) ^ *((u_int32_t*)rk[1][3]);
263: b[ 0] = S5[temp[0][0]];
264: b[ 1] = S5[temp[3][1]];
265: b[ 2] = S5[temp[2][2]];
266: b[ 3] = S5[temp[1][3]];
267: b[ 4] = S5[temp[1][0]];
268: b[ 5] = S5[temp[0][1]];
269: b[ 6] = S5[temp[3][2]];
270: b[ 7] = S5[temp[2][3]];
271: b[ 8] = S5[temp[2][0]];
272: b[ 9] = S5[temp[1][1]];
273: b[10] = S5[temp[0][2]];
274: b[11] = S5[temp[3][3]];
275: b[12] = S5[temp[3][0]];
276: b[13] = S5[temp[2][1]];
277: b[14] = S5[temp[1][2]];
278: b[15] = S5[temp[0][3]];
279: *((u_int32_t*)(b )) ^= *((u_int32_t*)rk[0][0]);
280: *((u_int32_t*)(b+ 4)) ^= *((u_int32_t*)rk[0][1]);
281: *((u_int32_t*)(b+ 8)) ^= *((u_int32_t*)rk[0][2]);
282: *((u_int32_t*)(b+12)) ^= *((u_int32_t*)rk[0][3]);
1.1 markus 283:
1.3 markus 284: return 0;
1.2 markus 285: }
1.1 markus 286:
1.3 markus 287: int
288: rijndael_makekey(rijndael_key *key, int direction, int keyLen, u_int8_t *keyMaterial)
289: {
290: u_int8_t k[RIJNDAEL_MAXKC][4];
291: int i;
292:
293: if (key == NULL)
294: return -1;
295: if ((direction != RIJNDAEL_ENCRYPT) && (direction != RIJNDAEL_DECRYPT))
296: return -1;
297: if ((keyLen != 128) && (keyLen != 192) && (keyLen != 256))
298: return -1;
299:
300: key->ROUNDS = keyLen/32 + 6;
301:
302: /* initialize key schedule: */
303: for (i = 0; i < keyLen/8; i++)
304: k[i >> 2][i & 3] = (u_int8_t)keyMaterial[i];
305:
306: rijndael_keysched(k, key->keySched, key->ROUNDS);
307: if (direction == RIJNDAEL_DECRYPT)
308: rijndael_key_enc_to_dec(key->keySched, key->ROUNDS);
309: return 0;
1.2 markus 310: }