]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/utilLib/rijndael-alg-ref.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / utilLib / rijndael-alg-ref.c
1 /* rijndael-alg-ref.c v2.0 August '99
2 * Reference ANSI C code
3 * authors: Paulo Barreto
4 * Vincent Rijmen
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include "rijndael-alg-ref.h"
11
12 #define SC ((BC - 4) >> 1)
13
14 #include "boxes-ref.h"
15
16 static const 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
34
35 static word8 mul(word8 a, word8 b) {
36 /* multiply two elements of GF(2^m)
37 * needed for MixColumn and InvMixColumn
38 */
39 if (a && b) return Alogtable[(Logtable[a] + Logtable[b])%255];
40 else return 0;
41 }
42
43 static void KeyAddition(word8 a[4][MAXBC], word8 rk[4][MAXBC], word8 BC) {
44 /* Exor corresponding text input and round key input bytes
45 */
46 int i, j;
47
48 for(i = 0; i < 4; i++)
49 for(j = 0; j < BC; j++) a[i][j] ^= rk[i][j];
50 }
51
52 static void ShiftRow(word8 a[4][MAXBC], word8 d, word8 BC) {
53 /* Row 0 remains unchanged
54 * The other three rows are shifted a variable amount
55 */
56 word8 tmp[MAXBC];
57 int i, j;
58
59 for(i = 1; i < 4; i++) {
60 for(j = 0; j < BC; j++) tmp[j] = a[i][(j + shifts[SC][i][d]) % BC];
61 for(j = 0; j < BC; j++) a[i][j] = tmp[j];
62 }
63 }
64
65 static void Substitution(word8 a[4][MAXBC], const word8 box[256], word8 BC) {
66 /* Replace every byte of the input by the byte at that place
67 * in the nonlinear S-box
68 */
69 int i, j;
70
71 for(i = 0; i < 4; i++)
72 for(j = 0; j < BC; j++) a[i][j] = box[a[i][j]] ;
73 }
74
75 static void MixColumn(word8 a[4][MAXBC], word8 BC) {
76 /* Mix the four bytes of every column in a linear way
77 */
78 word8 b[4][MAXBC];
79 int i, j;
80
81 for(j = 0; j < BC; j++)
82 for(i = 0; i < 4; i++)
83 b[i][j] = mul(2,a[i][j])
84 ^ mul(3,a[(i + 1) % 4][j])
85 ^ a[(i + 2) % 4][j]
86 ^ a[(i + 3) % 4][j];
87 for(i = 0; i < 4; i++)
88 for(j = 0; j < BC; j++) a[i][j] = b[i][j];
89 }
90
91 static void InvMixColumn(word8 a[4][MAXBC], word8 BC) {
92 /* Mix the four bytes of every column in a linear way
93 * This is the opposite operation of Mixcolumn
94 */
95 word8 b[4][MAXBC];
96 int i, j;
97
98 for(j = 0; j < BC; j++)
99 for(i = 0; i < 4; i++)
100 b[i][j] = mul(0xe,a[i][j])
101 ^ mul(0xb,a[(i + 1) % 4][j])
102 ^ mul(0xd,a[(i + 2) % 4][j])
103 ^ mul(0x9,a[(i + 3) % 4][j]);
104 for(i = 0; i < 4; i++)
105 for(j = 0; j < BC; j++) a[i][j] = b[i][j];
106 }
107
108 int _rijndaelKeySched (word8 k[4][MAXKC], int keyBits, int blockBits, word8 W[MAXROUNDS+1][4][MAXBC]) {
109 /* Calculate the necessary round keys
110 * The number of calculations depends on keyBits and blockBits
111 */
112 int KC, BC, ROUNDS;
113 int i, j, t, rconpointer = 0;
114 word8 tk[4][MAXKC];
115
116 switch (keyBits) {
117 case 128: KC = 4; break;
118 case 192: KC = 6; break;
119 case 256: KC = 8; break;
120 default : return (-1);
121 }
122
123 switch (blockBits) {
124 case 128: BC = 4; break;
125 case 192: BC = 6; break;
126 case 256: BC = 8; break;
127 default : return (-2);
128 }
129
130 switch (keyBits >= blockBits ? keyBits : blockBits) {
131 case 128: ROUNDS = 10; break;
132 case 192: ROUNDS = 12; break;
133 case 256: ROUNDS = 14; break;
134 default : return (-3); /* this cannot happen */
135 }
136
137
138 for(j = 0; j < KC; j++)
139 for(i = 0; i < 4; i++)
140 tk[i][j] = k[i][j];
141 t = 0;
142 /* copy values into round key array */
143 for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
144 for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
145
146 while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
147 /* calculate new values */
148 for(i = 0; i < 4; i++)
149 tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
150 tk[0][0] ^= rcon[rconpointer++];
151
152 if (KC != 8)
153 for(j = 1; j < KC; j++)
154 for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
155 else {
156 for(j = 1; j < KC/2; j++)
157 for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
158 for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
159 for(j = KC/2 + 1; j < KC; j++)
160 for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
161 }
162 /* copy values into round key array */
163 for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
164 for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
165 }
166
167 return 0;
168 }
169
170 int _rijndaelEncrypt (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC])
171 {
172 /* Encryption of one block.
173 */
174 int r, BC, ROUNDS;
175
176 switch (blockBits) {
177 case 128: BC = 4; break;
178 case 192: BC = 6; break;
179 case 256: BC = 8; break;
180 default : return (-2);
181 }
182
183 switch (keyBits >= blockBits ? keyBits : blockBits) {
184 case 128: ROUNDS = 10; break;
185 case 192: ROUNDS = 12; break;
186 case 256: ROUNDS = 14; break;
187 default : return (-3); /* this cannot happen */
188 }
189
190 /* begin with a key addition
191 */
192 KeyAddition(a,rk[0],BC);
193
194 /* ROUNDS-1 ordinary rounds
195 */
196 for(r = 1; r < ROUNDS; r++) {
197 Substitution(a,S,BC);
198 ShiftRow(a,0,BC);
199 MixColumn(a,BC);
200 KeyAddition(a,rk[r],BC);
201 }
202
203 /* Last round is special: there is no MixColumn
204 */
205 Substitution(a,S,BC);
206 ShiftRow(a,0,BC);
207 KeyAddition(a,rk[ROUNDS],BC);
208
209 return 0;
210 }
211
212
213 #ifndef __APPLE__
214
215 int rijndaelEncryptRound (word8 a[4][MAXBC], int keyBits, int blockBits,
216 word8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
217 /* Encrypt only a certain number of rounds.
218 * Only used in the Intermediate Value Known Answer Test.
219 */
220 {
221 int r, BC, ROUNDS;
222
223 switch (blockBits) {
224 case 128: BC = 4; break;
225 case 192: BC = 6; break;
226 case 256: BC = 8; break;
227 default : return (-2);
228 }
229
230 switch (keyBits >= blockBits ? keyBits : blockBits) {
231 case 128: ROUNDS = 10; break;
232 case 192: ROUNDS = 12; break;
233 case 256: ROUNDS = 14; break;
234 default : return (-3); /* this cannot happen */
235 }
236
237 /* make number of rounds sane */
238 if (rounds > ROUNDS) rounds = ROUNDS;
239
240 /* begin with a key addition
241 */
242 KeyAddition(a,rk[0],BC);
243
244 /* at most ROUNDS-1 ordinary rounds
245 */
246 for(r = 1; (r <= rounds) && (r < ROUNDS); r++) {
247 Substitution(a,S,BC);
248 ShiftRow(a,0,BC);
249 MixColumn(a,BC);
250 KeyAddition(a,rk[r],BC);
251 }
252
253 /* if necessary, do the last, special, round:
254 */
255 if (rounds == ROUNDS) {
256 Substitution(a,S,BC);
257 ShiftRow(a,0,BC);
258 KeyAddition(a,rk[ROUNDS],BC);
259 }
260
261 return 0;
262 }
263 #endif /* __APPLE__ */
264
265 int _rijndaelDecrypt (word8 a[4][MAXBC], int keyBits, int blockBits, word8 rk[MAXROUNDS+1][4][MAXBC])
266 {
267 int r, BC, ROUNDS;
268
269 switch (blockBits) {
270 case 128: BC = 4; break;
271 case 192: BC = 6; break;
272 case 256: BC = 8; break;
273 default : return (-2);
274 }
275
276 switch (keyBits >= blockBits ? keyBits : blockBits) {
277 case 128: ROUNDS = 10; break;
278 case 192: ROUNDS = 12; break;
279 case 256: ROUNDS = 14; break;
280 default : return (-3); /* this cannot happen */
281 }
282
283 /* To decrypt: apply the inverse operations of the encrypt routine,
284 * in opposite order
285 *
286 * (KeyAddition is an involution: it 's equal to its inverse)
287 * (the inverse of Substitution with table S is Substitution with the inverse table of S)
288 * (the inverse of Shiftrow is Shiftrow over a suitable distance)
289 */
290
291 /* First the special round:
292 * without InvMixColumn
293 * with extra KeyAddition
294 */
295 KeyAddition(a,rk[ROUNDS],BC);
296 Substitution(a,Si,BC);
297 ShiftRow(a,1,BC);
298
299 /* ROUNDS-1 ordinary rounds
300 */
301 for(r = ROUNDS-1; r > 0; r--) {
302 KeyAddition(a,rk[r],BC);
303 InvMixColumn(a,BC);
304 Substitution(a,Si,BC);
305 ShiftRow(a,1,BC);
306 }
307
308 /* End with the extra key addition
309 */
310
311 KeyAddition(a,rk[0],BC);
312
313 return 0;
314 }
315
316 #ifndef __APPLE__
317
318 int rijndaelDecryptRound (word8 a[4][MAXBC], int keyBits, int blockBits,
319 word8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
320 /* Decrypt only a certain number of rounds.
321 * Only used in the Intermediate Value Known Answer Test.
322 * Operations rearranged such that the intermediate values
323 * of decryption correspond with the intermediate values
324 * of encryption.
325 */
326 {
327 int r, BC, ROUNDS;
328
329 switch (blockBits) {
330 case 128: BC = 4; break;
331 case 192: BC = 6; break;
332 case 256: BC = 8; break;
333 default : return (-2);
334 }
335
336 switch (keyBits >= blockBits ? keyBits : blockBits) {
337 case 128: ROUNDS = 10; break;
338 case 192: ROUNDS = 12; break;
339 case 256: ROUNDS = 14; break;
340 default : return (-3); /* this cannot happen */
341 }
342
343
344 /* make number of rounds sane */
345 if (rounds > ROUNDS) rounds = ROUNDS;
346
347 /* First the special round:
348 * without InvMixColumn
349 * with extra KeyAddition
350 */
351 KeyAddition(a,rk[ROUNDS],BC);
352 Substitution(a,Si,BC);
353 ShiftRow(a,1,BC);
354
355 /* ROUNDS-1 ordinary rounds
356 */
357 for(r = ROUNDS-1; r > rounds; r--) {
358 KeyAddition(a,rk[r],BC);
359 InvMixColumn(a,BC);
360 Substitution(a,Si,BC);
361 ShiftRow(a,1,BC);
362 }
363
364 if (rounds == 0) {
365 /* End with the extra key addition
366 */
367 KeyAddition(a,rk[0],BC);
368 }
369
370 return 0;
371 }
372
373 #endif /* __APPLE__ */