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