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