1 /* rijndael-alg-fst.c   v2.0   August '99
2  * Optimised ANSI C code
3  * authors: v1.0: Antoon Bosselaers
4  *          v2.0: Vincent Rijmen
5  */
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 
10 #include "rijndael-alg-fst.h"
11 
12 #define SC	((BC - 4) >> 1)
13 
14 #include "boxes-fst.dat"
15 
16 static word8 shifts[3][4][2] = {
17    {{0, 0},
18    {1, 3},
19    {2, 2},
20    {3, 1}},
21 
22    {{0, 0},
23    {1, 5},
24    {2, 4},
25    {3, 3}},
26 
27    {{0, 0},
28    {1, 7},
29    {3, 5},
30    {4, 4}}
31 };
32 
33 
mul(word8 a,word8 b)34 word8 mul(word8 a, word8 b) {
35    /* multiply two elements of GF(2^m)
36     * needed for MixColumn and InvMixColumn
37     */
38 	if (a && b)
39 		return Alogtable[(Logtable[a] + Logtable[b])%255];
40 	else
41 		return 0;
42 }
43 
KeyAddition(word8 a[4][4],word8 rk[4][4],word8 BC)44 void KeyAddition(word8 a[4][4], word8 rk[4][4], word8 BC) {
45 	/* Exor corresponding text input and round key input bytes
46 	 */
47 	int i, j;
48 
49 	for(i = 0; i < BC; i++)
50    	for(j = 0; j < 4; j++)
51 			a[i][j] ^= rk[i][j];
52 }
53 
ShiftRow(word8 a[4][4],word8 d,word8 BC)54 void ShiftRow(word8 a[4][4], word8 d, word8 BC) {
55 	/* Row 0 remains unchanged
56 	 * The other three rows are shifted a variable amount
57 	 */
58 	word8 tmp[4];
59 	int i, j;
60 
61 	for(i = 1; i < 4; i++) {
62 		for(j = 0; j < BC; j++)
63 			tmp[j] = a[(j + shifts[SC][i][d]) % BC][i];
64 		for(j = 0; j < BC; j++)
65 			a[j][i] = tmp[j];
66 	}
67 }
68 
Substitution(word8 a[4][4],word8 box[256],word8 BC)69 void Substitution(word8 a[4][4], word8 box[256], word8 BC) {
70 	/* Replace every byte of the input by the byte at that place
71 	 * in the nonlinear S-box
72 	 */
73 	int i, j;
74 
75 	for(i = 0; i < BC; i++)
76 		for(j = 0; j < 4; j++)
77 			a[i][j] = box[a[i][j]] ;
78 }
79 
MixColumn(word8 a[4][4],word8 BC)80 void MixColumn(word8 a[4][4], word8 BC) {
81         /* Mix the four bytes of every column in a linear way
82 	 */
83 	word8 b[4][4];
84 	int i, j;
85 
86 	for(j = 0; j < BC; j++)
87 		for(i = 0; i < 4; i++)
88 			b[j][i] = mul(2,a[j][i])
89 				^ mul(3,a[j][(i + 1) % 4])
90 				^ a[j][(i + 2) % 4]
91 				^ a[j][(i + 3) % 4];
92 	for(i = 0; i < 4; i++)
93 		for(j = 0; j < BC; j++)
94 			a[j][i] = b[j][i];
95 }
96 
InvMixColumn(word8 a[4][4],word8 BC)97 void InvMixColumn(word8 a[4][4], word8 BC) {
98         /* Mix the four bytes of every column in a linear way
99 	 * This is the opposite operation of Mixcolumn
100 	 */
101 	int j;
102 
103 	for(j = 0; j < BC; j++)
104 		*((word32*)a[j]) = *((word32*)U1[a[j][0]])
105 								^ *((word32*)U2[a[j][1]])
106 								^ *((word32*)U3[a[j][2]])
107 								^ *((word32*)U4[a[j][3]]);
108 
109 
110 }
111 
rijndaelKeySched(word8 k[MAXKC][4],int keyBits,word8 W[MAXROUNDS+1][4][4])112 int rijndaelKeySched (word8 k[MAXKC][4], int keyBits, word8 W[MAXROUNDS+1][4][4])
113 {
114 	/* Calculate the necessary round keys
115 	 * The number of calculations depends on keyBits and blockBits
116 	 */
117 	int j, r, t, rconpointer = 0;
118 	word8 tk[MAXKC][4];
119 	int KC = ROUNDS - 6;
120 
121 	for(j = KC-1; j >= 0; j--)
122 		*((word32*)tk[j]) = *((word32*)k[j]);
123 	r = 0;
124 	t = 0;
125 	/* copy values into round key array */
126 	for(j = 0; (j < KC) && (r < (ROUNDS+1)); ) {
127 		for (; (j < KC) && (t < 4); j++, t++)
128 			*((word32*)W[r][t]) = *((word32*)tk[j]);
129 		if (t == 4) {
130 			r++;
131 			t = 0;
132 		}
133 	}
134 
135 	while (r < (ROUNDS+1)) { /* while not enough round key material calculated */
136 		/* calculate new values */
137 		tk[0][0] ^= S[tk[KC-1][1]];
138 		tk[0][1] ^= S[tk[KC-1][2]];
139 		tk[0][2] ^= S[tk[KC-1][3]];
140 		tk[0][3] ^= S[tk[KC-1][0]];
141 		tk[0][0] ^= rcon[rconpointer++];
142 
143 		if (KC != 8)
144 			for(j = 1; j < KC; j++)
145 				*((word32*)tk[j]) ^= *((word32*)tk[j-1]);
146 		else {
147 			for(j = 1; j < KC/2; j++)
148 				*((word32*)tk[j]) ^= *((word32*)tk[j-1]);
149 			tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
150 			tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
151 			tk[KC/2][2] ^= S[tk[KC/2 - 1][2]];
152 			tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
153 			for(j = KC/2 + 1; j < KC; j++)
154 				*((word32*)tk[j]) ^= *((word32*)tk[j-1]);
155 		}
156 		/* copy values into round key array */
157 		for(j = 0; (j < KC) && (r < (ROUNDS+1)); ) {
158 			for (; (j < KC) && (t < 4); j++, t++)
159 				*((word32*)W[r][t]) = *((word32*)tk[j]);
160 			if (t == 4) {
161 				r++;
162 				t = 0;
163 			}
164 		}
165 	}
166 
167 	return 0;
168 }
169 
rijndaelKeyEnctoDec(int keyBits,word8 W[MAXROUNDS+1][4][4])170 int rijndaelKeyEnctoDec (int keyBits, word8 W[MAXROUNDS+1][4][4])
171 {
172 	int r;
173 
174 	for (r = 1; r < ROUNDS; r++) {
175 		InvMixColumn(W[r], 4);
176 	}
177 	return 0;
178 }
179 
rijndaelEncrypt(word8 a[16],word8 b[16],word8 rk[MAXROUNDS+1][4][4])180 int rijndaelEncrypt (word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4])
181 {
182 	/* Encryption of one block.
183 	 */
184 	int r;
185    word8 temp[4][4];
186 
187     *((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[0][0]);
188     *((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[0][1]);
189     *((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[0][2]);
190     *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[0][3]);
191     *((word32*)b) = *((word32*)T1[temp[0][0]])
192            ^ *((word32*)T2[temp[1][1]])
193            ^ *((word32*)T3[temp[2][2]])
194            ^ *((word32*)T4[temp[3][3]]);
195     *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
196            ^ *((word32*)T2[temp[2][1]])
197            ^ *((word32*)T3[temp[3][2]])
198            ^ *((word32*)T4[temp[0][3]]);
199     *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
200            ^ *((word32*)T2[temp[3][1]])
201            ^ *((word32*)T3[temp[0][2]])
202            ^ *((word32*)T4[temp[1][3]]);
203     *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
204            ^ *((word32*)T2[temp[0][1]])
205            ^ *((word32*)T3[temp[1][2]])
206            ^ *((word32*)T4[temp[2][3]]);
207    for(r = 1; r < ROUNDS-1; r++) {
208 		*((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
209 		*((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
210 		*((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
211 		*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
212    *((word32*)b) = *((word32*)T1[temp[0][0]])
213            ^ *((word32*)T2[temp[1][1]])
214            ^ *((word32*)T3[temp[2][2]])
215            ^ *((word32*)T4[temp[3][3]]);
216    *((word32*)(b+4)) = *((word32*)T1[temp[1][0]])
217            ^ *((word32*)T2[temp[2][1]])
218            ^ *((word32*)T3[temp[3][2]])
219            ^ *((word32*)T4[temp[0][3]]);
220    *((word32*)(b+8)) = *((word32*)T1[temp[2][0]])
221            ^ *((word32*)T2[temp[3][1]])
222            ^ *((word32*)T3[temp[0][2]])
223            ^ *((word32*)T4[temp[1][3]]);
224    *((word32*)(b+12)) = *((word32*)T1[temp[3][0]])
225            ^ *((word32*)T2[temp[0][1]])
226            ^ *((word32*)T3[temp[1][2]])
227            ^ *((word32*)T4[temp[2][3]]);
228    }
229    /* last round is special */
230 	*((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[ROUNDS-1][0]);
231 	*((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[ROUNDS-1][1]);
232 	*((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[ROUNDS-1][2]);
233 	*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[ROUNDS-1][3]);
234    b[0] = T1[temp[0][0]][1];
235    b[1] = T1[temp[1][1]][1];
236    b[2] = T1[temp[2][2]][1];
237    b[3] = T1[temp[3][3]][1];
238    b[4] = T1[temp[1][0]][1];
239    b[5] = T1[temp[2][1]][1];
240    b[6] = T1[temp[3][2]][1];
241    b[7] = T1[temp[0][3]][1];
242    b[8] = T1[temp[2][0]][1];
243    b[9] = T1[temp[3][1]][1];
244    b[10] = T1[temp[0][2]][1];
245    b[11] = T1[temp[1][3]][1];
246    b[12] = T1[temp[3][0]][1];
247    b[13] = T1[temp[0][1]][1];
248    b[14] = T1[temp[1][2]][1];
249    b[15] = T1[temp[2][3]][1];
250 	*((word32*)b) ^= *((word32*)rk[ROUNDS][0]);
251 	*((word32*)(b+4)) ^= *((word32*)rk[ROUNDS][1]);
252 	*((word32*)(b+8)) ^= *((word32*)rk[ROUNDS][2]);
253 	*((word32*)(b+12)) ^= *((word32*)rk[ROUNDS][3]);
254 
255 	return 0;
256 }
257 
rijndaelEncryptRound(word8 a[4][4],word8 rk[MAXROUNDS+1][4][4],int rounds)258 int rijndaelEncryptRound (word8 a[4][4],
259 		word8 rk[MAXROUNDS+1][4][4], int rounds)
260 /* Encrypt only a certain number of rounds.
261  * Only used in the Intermediate Value Known Answer Test.
262  */
263 {
264 	int r;
265    word8 temp[4][4];
266 
267 
268 	/* make number of rounds sane */
269 	if (rounds > ROUNDS) rounds = ROUNDS;
270 
271 	*((word32*)a[0]) = *((word32*)a[0]) ^ *((word32*)rk[0][0]);
272 	*((word32*)a[1]) = *((word32*)a[1]) ^ *((word32*)rk[0][1]);
273 	*((word32*)a[2]) = *((word32*)a[2]) ^ *((word32*)rk[0][2]);
274 	*((word32*)a[3]) = *((word32*)a[3]) ^ *((word32*)rk[0][3]);
275 
276 	for(r = 1; (r <= rounds) && (r < ROUNDS); r++) {
277 		*((word32*)temp[0]) = *((word32*)T1[a[0][0]])
278            ^ *((word32*)T2[a[1][1]])
279            ^ *((word32*)T3[a[2][2]])
280            ^ *((word32*)T4[a[3][3]]);
281 		*((word32*)temp[1]) = *((word32*)T1[a[1][0]])
282            ^ *((word32*)T2[a[2][1]])
283            ^ *((word32*)T3[a[3][2]])
284            ^ *((word32*)T4[a[0][3]]);
285 		*((word32*)temp[2]) = *((word32*)T1[a[2][0]])
286            ^ *((word32*)T2[a[3][1]])
287            ^ *((word32*)T3[a[0][2]])
288            ^ *((word32*)T4[a[1][3]]);
289 		*((word32*)temp[3]) = *((word32*)T1[a[3][0]])
290            ^ *((word32*)T2[a[0][1]])
291            ^ *((word32*)T3[a[1][2]])
292            ^ *((word32*)T4[a[2][3]]);
293 		*((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[r][0]);
294 		*((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[r][1]);
295 		*((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[r][2]);
296 		*((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[r][3]);
297    }
298 	if (rounds == ROUNDS) {
299    	/* last round is special */
300    	temp[0][0] = T1[a[0][0]][1];
301    	temp[0][1] = T1[a[1][1]][1];
302    	temp[0][2] = T1[a[2][2]][1];
303    	temp[0][3] = T1[a[3][3]][1];
304    	temp[1][0] = T1[a[1][0]][1];
305    	temp[1][1] = T1[a[2][1]][1];
306    	temp[1][2] = T1[a[3][2]][1];
307    	temp[1][3] = T1[a[0][3]][1];
308    	temp[2][0] = T1[a[2][0]][1];
309    	temp[2][1] = T1[a[3][1]][1];
310    	temp[2][2] = T1[a[0][2]][1];
311    	temp[2][3] = T1[a[1][3]][1];
312    	temp[3][0] = T1[a[3][0]][1];
313    	temp[3][1] = T1[a[0][1]][1];
314    	temp[3][2] = T1[a[1][2]][1];
315    	temp[3][3] = T1[a[2][3]][1];
316 		*((word32*)a[0]) = *((word32*)temp[0]) ^ *((word32*)rk[ROUNDS][0]);
317 		*((word32*)a[1]) = *((word32*)temp[1]) ^ *((word32*)rk[ROUNDS][1]);
318 		*((word32*)a[2]) = *((word32*)temp[2]) ^ *((word32*)rk[ROUNDS][2]);
319 		*((word32*)a[3]) = *((word32*)temp[3]) ^ *((word32*)rk[ROUNDS][3]);
320 	}
321 
322 	return 0;
323 }
324 
325 
rijndaelDecrypt(word8 a[16],word8 b[16],word8 rk[MAXROUNDS+1][4][4])326 int rijndaelDecrypt (word8 a[16], word8 b[16], word8 rk[MAXROUNDS+1][4][4])
327 {
328 	int r;
329    word8 temp[4][4];
330 
331 
332     *((word32*)temp[0]) = *((word32*)a) ^ *((word32*)rk[ROUNDS][0]);
333     *((word32*)temp[1]) = *((word32*)(a+4)) ^ *((word32*)rk[ROUNDS][1]);
334     *((word32*)temp[2]) = *((word32*)(a+8)) ^ *((word32*)rk[ROUNDS][2]);
335     *((word32*)temp[3]) = *((word32*)(a+12)) ^ *((word32*)rk[ROUNDS][3]);
336     *((word32*)b) = *((word32*)T5[temp[0][0]])
337            ^ *((word32*)T6[temp[3][1]])
338            ^ *((word32*)T7[temp[2][2]])
339            ^ *((word32*)T8[temp[1][3]]);
340    *((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
341            ^ *((word32*)T6[temp[0][1]])
342            ^ *((word32*)T7[temp[3][2]])
343            ^ *((word32*)T8[temp[2][3]]);
344    *((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
345            ^ *((word32*)T6[temp[1][1]])
346            ^ *((word32*)T7[temp[0][2]])
347            ^ *((word32*)T8[temp[3][3]]);
348    *((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
349            ^ *((word32*)T6[temp[2][1]])
350            ^ *((word32*)T7[temp[1][2]])
351            ^ *((word32*)T8[temp[0][3]]);
352    for(r = ROUNDS-1; r > 1; r--) {
353 		*((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[r][0]);
354 		*((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[r][1]);
355 		*((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[r][2]);
356 		*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[r][3]);
357 		*((word32*)b) = *((word32*)T5[temp[0][0]])
358            ^ *((word32*)T6[temp[3][1]])
359            ^ *((word32*)T7[temp[2][2]])
360            ^ *((word32*)T8[temp[1][3]]);
361 		*((word32*)(b+4)) = *((word32*)T5[temp[1][0]])
362            ^ *((word32*)T6[temp[0][1]])
363            ^ *((word32*)T7[temp[3][2]])
364            ^ *((word32*)T8[temp[2][3]]);
365 		*((word32*)(b+8)) = *((word32*)T5[temp[2][0]])
366            ^ *((word32*)T6[temp[1][1]])
367            ^ *((word32*)T7[temp[0][2]])
368            ^ *((word32*)T8[temp[3][3]]);
369 		*((word32*)(b+12)) = *((word32*)T5[temp[3][0]])
370            ^ *((word32*)T6[temp[2][1]])
371            ^ *((word32*)T7[temp[1][2]])
372            ^ *((word32*)T8[temp[0][3]]);
373    }
374    /* last round is special */
375 	*((word32*)temp[0]) = *((word32*)b) ^ *((word32*)rk[1][0]);
376 	*((word32*)temp[1]) = *((word32*)(b+4)) ^ *((word32*)rk[1][1]);
377 	*((word32*)temp[2]) = *((word32*)(b+8)) ^ *((word32*)rk[1][2]);
378 	*((word32*)temp[3]) = *((word32*)(b+12)) ^ *((word32*)rk[1][3]);
379    b[0] = S5[temp[0][0]];
380    b[1] = S5[temp[3][1]];
381    b[2] = S5[temp[2][2]];
382    b[3] = S5[temp[1][3]];
383    b[4] = S5[temp[1][0]];
384    b[5] = S5[temp[0][1]];
385    b[6] = S5[temp[3][2]];
386    b[7] = S5[temp[2][3]];
387    b[8] = S5[temp[2][0]];
388    b[9] = S5[temp[1][1]];
389    b[10] = S5[temp[0][2]];
390    b[11] = S5[temp[3][3]];
391    b[12] = S5[temp[3][0]];
392    b[13] = S5[temp[2][1]];
393    b[14] = S5[temp[1][2]];
394    b[15] = S5[temp[0][3]];
395 	*((word32*)b) ^= *((word32*)rk[0][0]);
396 	*((word32*)(b+4)) ^= *((word32*)rk[0][1]);
397 	*((word32*)(b+8)) ^= *((word32*)rk[0][2]);
398 	*((word32*)(b+12)) ^= *((word32*)rk[0][3]);
399 
400 	return 0;
401 }
402 
403 
rijndaelDecryptRound(word8 a[4][4],word8 rk[MAXROUNDS+1][4][4],int rounds)404 int rijndaelDecryptRound (word8 a[4][4],
405 	word8 rk[MAXROUNDS+1][4][4], int rounds)
406 /* Decrypt only a certain number of rounds.
407  * Only used in the Intermediate Value Known Answer Test.
408  * Operations rearranged such that the intermediate values
409  * of decryption correspond with the intermediate values
410  * of encryption.
411  */
412 {
413 	int r;
414 
415 
416 	/* make number of rounds sane */
417 	if (rounds > ROUNDS) rounds = ROUNDS;
418 
419         /* First the special round:
420 	 *   without InvMixColumn
421 	 *   with extra KeyAddition
422 	 */
423 	KeyAddition(a,rk[ROUNDS],4);
424 	Substitution(a,Si,4);
425 	ShiftRow(a,1,4);
426 
427 	/* ROUNDS-1 ordinary rounds
428 	 */
429 	for(r = ROUNDS-1; r > rounds; r--) {
430 		KeyAddition(a,rk[r],4);
431 		InvMixColumn(a,4);
432 		Substitution(a,Si,4);
433 		ShiftRow(a,1,4);
434 	}
435 
436 	if (rounds == 0) {
437 		/* End with the extra key addition
438 		 */
439 		KeyAddition(a,rk[0],4);
440 	}
441 
442 	return 0;
443 }
444