1 /* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */
2
3 /*
4 * rijndael-api-fst.c v2.3 April '2000
5 *
6 * Optimised ANSI C code
7 *
8 * authors: v1.0: Antoon Bosselaers
9 * v2.0: Vincent Rijmen
10 * v2.1: Vincent Rijmen
11 * v2.2: Vincent Rijmen
12 * v2.3: Paulo Barreto
13 * v2.4: Vincent Rijmen
14 *
15 * This code is placed in the public domain.
16 */
17
18 #include <sys/param.h>
19 #ifdef _KERNEL
20 #include <sys/systm.h>
21 #else
22 #include <string.h>
23 #endif
24
25 #include <crypto/rijndael/rijndael_local.h>
26 #include <crypto/rijndael/rijndael-api-fst.h>
27
28 #ifndef TRUE
29 #define TRUE 1
30 #endif
31
32 typedef uint8_t BYTE;
33
rijndael_makeKey(keyInstance * key,BYTE direction,int keyLen,const char * keyMaterial)34 int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen,
35 const char *keyMaterial) {
36
37 if (key == NULL) {
38 return BAD_KEY_INSTANCE;
39 }
40
41 if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
42 key->direction = direction;
43 } else {
44 return BAD_KEY_DIR;
45 }
46
47 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
48 key->keyLen = keyLen;
49 } else {
50 return BAD_KEY_MAT;
51 }
52
53 if (keyMaterial != NULL) {
54 memcpy(key->keyMaterial, keyMaterial, keyLen/8);
55 }
56
57 /* initialize key schedule: */
58 if (direction == DIR_ENCRYPT) {
59 key->Nr = rijndaelKeySetupEnc(key->rk, key->keyMaterial, keyLen);
60 } else {
61 key->Nr = rijndaelKeySetupDec(key->rk, key->keyMaterial, keyLen);
62 }
63 rijndaelKeySetupEnc(key->ek, key->keyMaterial, keyLen);
64 return TRUE;
65 }
66
rijndael_cipherInit(cipherInstance * cipher,BYTE mode,char * IV)67 int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
68 if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
69 cipher->mode = mode;
70 } else {
71 return BAD_CIPHER_MODE;
72 }
73 if (IV != NULL) {
74 memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
75 } else {
76 memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
77 }
78 return TRUE;
79 }
80
rijndael_blockEncrypt(cipherInstance * cipher,keyInstance * key,const BYTE * input,int inputLen,BYTE * outBuffer)81 int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
82 const BYTE *input, int inputLen, BYTE *outBuffer) {
83 int i, k, numBlocks;
84 uint8_t block[16], iv[4][4];
85
86 if (cipher == NULL ||
87 key == NULL ||
88 key->direction == DIR_DECRYPT) {
89 return BAD_CIPHER_STATE;
90 }
91 if (input == NULL || inputLen <= 0) {
92 return 0; /* nothing to do */
93 }
94
95 numBlocks = inputLen/128;
96
97 switch (cipher->mode) {
98 case MODE_ECB:
99 for (i = numBlocks; i > 0; i--) {
100 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
101 input += 16;
102 outBuffer += 16;
103 }
104 break;
105
106 case MODE_CBC:
107 #if 1 /*STRICT_ALIGN*/
108 memcpy(block, cipher->IV, 16);
109 memcpy(iv, input, 16);
110 ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0];
111 ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1];
112 ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2];
113 ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3];
114 #else
115 ((uint32_t*)block)[0] = ((uint32_t*)cipher->IV)[0] ^ ((uint32_t*)input)[0];
116 ((uint32_t*)block)[1] = ((uint32_t*)cipher->IV)[1] ^ ((uint32_t*)input)[1];
117 ((uint32_t*)block)[2] = ((uint32_t*)cipher->IV)[2] ^ ((uint32_t*)input)[2];
118 ((uint32_t*)block)[3] = ((uint32_t*)cipher->IV)[3] ^ ((uint32_t*)input)[3];
119 #endif
120 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
121 input += 16;
122 for (i = numBlocks - 1; i > 0; i--) {
123 #if 1 /*STRICT_ALIGN*/
124 memcpy(block, outBuffer, 16);
125 memcpy(iv, input, 16);
126 ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0];
127 ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1];
128 ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2];
129 ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3];
130 #else
131 ((uint32_t*)block)[0] = ((uint32_t*)outBuffer)[0] ^ ((uint32_t*)input)[0];
132 ((uint32_t*)block)[1] = ((uint32_t*)outBuffer)[1] ^ ((uint32_t*)input)[1];
133 ((uint32_t*)block)[2] = ((uint32_t*)outBuffer)[2] ^ ((uint32_t*)input)[2];
134 ((uint32_t*)block)[3] = ((uint32_t*)outBuffer)[3] ^ ((uint32_t*)input)[3];
135 #endif
136 outBuffer += 16;
137 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
138 input += 16;
139 }
140 break;
141
142 case MODE_CFB1:
143 #if 1 /*STRICT_ALIGN*/
144 memcpy(iv, cipher->IV, 16);
145 #else /* !STRICT_ALIGN */
146 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV ));
147 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
148 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
149 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
150 #endif /* ?STRICT_ALIGN */
151 for (i = numBlocks; i > 0; i--) {
152 for (k = 0; k < 128; k++) {
153 *((uint32_t*) block ) = *((uint32_t*)iv[0]);
154 *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
155 *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
156 *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
157 rijndaelEncrypt(key->ek, key->Nr, block,
158 block);
159 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
160 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
161 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
162 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
163 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
164 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
165 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
166 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
167 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
168 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
169 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
170 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
171 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
172 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
173 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
174 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
175 iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1);
176 }
177 }
178 break;
179
180 default:
181 return BAD_CIPHER_STATE;
182 }
183
184 explicit_bzero(block, sizeof(block));
185 return 128*numBlocks;
186 }
187
188 /**
189 * Encrypt data partitioned in octets, using RFC 2040-like padding.
190 *
191 * @param input data to be encrypted (octet sequence)
192 * @param inputOctets input length in octets (not bits)
193 * @param outBuffer encrypted output data
194 *
195 * @return length in octets (not bits) of the encrypted output buffer.
196 */
rijndael_padEncrypt(cipherInstance * cipher,keyInstance * key,const BYTE * input,int inputOctets,BYTE * outBuffer)197 int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key,
198 const BYTE *input, int inputOctets, BYTE *outBuffer) {
199 int i, numBlocks, padLen;
200 uint8_t block[16], *iv, *cp;
201
202 if (cipher == NULL ||
203 key == NULL ||
204 key->direction == DIR_DECRYPT) {
205 return BAD_CIPHER_STATE;
206 }
207 if (input == NULL || inputOctets <= 0) {
208 return 0; /* nothing to do */
209 }
210
211 numBlocks = inputOctets/16;
212
213 switch (cipher->mode) {
214 case MODE_ECB:
215 for (i = numBlocks; i > 0; i--) {
216 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
217 input += 16;
218 outBuffer += 16;
219 }
220 padLen = 16 - (inputOctets - 16*numBlocks);
221 if (padLen <= 0 || padLen > 16)
222 return BAD_CIPHER_STATE;
223 memcpy(block, input, 16 - padLen);
224 for (cp = block + 16 - padLen; cp < block + 16; cp++)
225 *cp = padLen;
226 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
227 break;
228
229 case MODE_CBC:
230 iv = cipher->IV;
231 for (i = numBlocks; i > 0; i--) {
232 ((uint32_t*)block)[0] = ((const uint32_t*)input)[0] ^ ((uint32_t*)iv)[0];
233 ((uint32_t*)block)[1] = ((const uint32_t*)input)[1] ^ ((uint32_t*)iv)[1];
234 ((uint32_t*)block)[2] = ((const uint32_t*)input)[2] ^ ((uint32_t*)iv)[2];
235 ((uint32_t*)block)[3] = ((const uint32_t*)input)[3] ^ ((uint32_t*)iv)[3];
236 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
237 iv = outBuffer;
238 input += 16;
239 outBuffer += 16;
240 }
241 padLen = 16 - (inputOctets - 16*numBlocks);
242 if (padLen <= 0 || padLen > 16)
243 return BAD_CIPHER_STATE;
244 for (i = 0; i < 16 - padLen; i++) {
245 block[i] = input[i] ^ iv[i];
246 }
247 for (i = 16 - padLen; i < 16; i++) {
248 block[i] = (BYTE)padLen ^ iv[i];
249 }
250 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
251 break;
252
253 default:
254 return BAD_CIPHER_STATE;
255 }
256
257 explicit_bzero(block, sizeof(block));
258 return 16*(numBlocks + 1);
259 }
260
rijndael_blockDecrypt(cipherInstance * cipher,keyInstance * key,const BYTE * input,int inputLen,BYTE * outBuffer)261 int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
262 const BYTE *input, int inputLen, BYTE *outBuffer) {
263 int i, k, numBlocks;
264 uint8_t block[16], iv[4][4];
265
266 if (cipher == NULL ||
267 key == NULL ||
268 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
269 return BAD_CIPHER_STATE;
270 }
271 if (input == NULL || inputLen <= 0) {
272 return 0; /* nothing to do */
273 }
274
275 numBlocks = inputLen/128;
276
277 switch (cipher->mode) {
278 case MODE_ECB:
279 for (i = numBlocks; i > 0; i--) {
280 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
281 input += 16;
282 outBuffer += 16;
283 }
284 break;
285
286 case MODE_CBC:
287 #if 1 /*STRICT_ALIGN */
288 memcpy(iv, cipher->IV, 16);
289 #else
290 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV ));
291 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
292 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
293 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
294 #endif
295 for (i = numBlocks; i > 0; i--) {
296 rijndaelDecrypt(key->rk, key->Nr, input, block);
297 ((uint32_t*)block)[0] ^= *((uint32_t*)iv[0]);
298 ((uint32_t*)block)[1] ^= *((uint32_t*)iv[1]);
299 ((uint32_t*)block)[2] ^= *((uint32_t*)iv[2]);
300 ((uint32_t*)block)[3] ^= *((uint32_t*)iv[3]);
301 #if 1 /*STRICT_ALIGN*/
302 memcpy(iv, input, 16);
303 memcpy(outBuffer, block, 16);
304 #else
305 *((uint32_t*)iv[0]) = ((uint32_t*)input)[0]; ((uint32_t*)outBuffer)[0] = ((uint32_t*)block)[0];
306 *((uint32_t*)iv[1]) = ((uint32_t*)input)[1]; ((uint32_t*)outBuffer)[1] = ((uint32_t*)block)[1];
307 *((uint32_t*)iv[2]) = ((uint32_t*)input)[2]; ((uint32_t*)outBuffer)[2] = ((uint32_t*)block)[2];
308 *((uint32_t*)iv[3]) = ((uint32_t*)input)[3]; ((uint32_t*)outBuffer)[3] = ((uint32_t*)block)[3];
309 #endif
310 input += 16;
311 outBuffer += 16;
312 }
313 break;
314
315 case MODE_CFB1:
316 #if 1 /*STRICT_ALIGN */
317 memcpy(iv, cipher->IV, 16);
318 #else
319 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV));
320 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
321 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
322 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
323 #endif
324 for (i = numBlocks; i > 0; i--) {
325 for (k = 0; k < 128; k++) {
326 *((uint32_t*) block ) = *((uint32_t*)iv[0]);
327 *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
328 *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
329 *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
330 rijndaelEncrypt(key->ek, key->Nr, block,
331 block);
332 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
333 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
334 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
335 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
336 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
337 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
338 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
339 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
340 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
341 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
342 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
343 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
344 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
345 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
346 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
347 iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1);
348 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
349 }
350 }
351 break;
352
353 default:
354 return BAD_CIPHER_STATE;
355 }
356
357 explicit_bzero(block, sizeof(block));
358 return 128*numBlocks;
359 }
360
rijndael_padDecrypt(cipherInstance * cipher,keyInstance * key,const BYTE * input,int inputOctets,BYTE * outBuffer)361 int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
362 const BYTE *input, int inputOctets, BYTE *outBuffer) {
363 int i, numBlocks, padLen, rval;
364 uint8_t block[16];
365 uint32_t iv[4];
366
367 if (cipher == NULL ||
368 key == NULL ||
369 key->direction == DIR_ENCRYPT) {
370 return BAD_CIPHER_STATE;
371 }
372 if (input == NULL || inputOctets <= 0) {
373 return 0; /* nothing to do */
374 }
375 if (inputOctets % 16 != 0) {
376 return BAD_DATA;
377 }
378
379 numBlocks = inputOctets/16;
380
381 switch (cipher->mode) {
382 case MODE_ECB:
383 /* all blocks but last */
384 for (i = numBlocks - 1; i > 0; i--) {
385 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
386 input += 16;
387 outBuffer += 16;
388 }
389 /* last block */
390 rijndaelDecrypt(key->rk, key->Nr, input, block);
391 padLen = block[15];
392 if (padLen >= 16) {
393 rval = BAD_DATA;
394 goto out;
395 }
396 for (i = 16 - padLen; i < 16; i++) {
397 if (block[i] != padLen) {
398 rval = BAD_DATA;
399 goto out;
400 }
401 }
402 memcpy(outBuffer, block, 16 - padLen);
403 break;
404
405 case MODE_CBC:
406 memcpy(iv, cipher->IV, 16);
407 /* all blocks but last */
408 for (i = numBlocks - 1; i > 0; i--) {
409 rijndaelDecrypt(key->rk, key->Nr, input, block);
410 ((uint32_t*)block)[0] ^= iv[0];
411 ((uint32_t*)block)[1] ^= iv[1];
412 ((uint32_t*)block)[2] ^= iv[2];
413 ((uint32_t*)block)[3] ^= iv[3];
414 memcpy(iv, input, 16);
415 memcpy(outBuffer, block, 16);
416 input += 16;
417 outBuffer += 16;
418 }
419 /* last block */
420 rijndaelDecrypt(key->rk, key->Nr, input, block);
421 ((uint32_t*)block)[0] ^= iv[0];
422 ((uint32_t*)block)[1] ^= iv[1];
423 ((uint32_t*)block)[2] ^= iv[2];
424 ((uint32_t*)block)[3] ^= iv[3];
425 padLen = block[15];
426 if (padLen <= 0 || padLen > 16) {
427 rval = BAD_DATA;
428 goto out;
429 }
430 for (i = 16 - padLen; i < 16; i++) {
431 if (block[i] != padLen) {
432 rval = BAD_DATA;
433 goto out;
434 }
435 }
436 memcpy(outBuffer, block, 16 - padLen);
437 break;
438
439 default:
440 return BAD_CIPHER_STATE;
441 }
442
443 rval = 16*numBlocks - padLen;
444
445 out:
446 explicit_bzero(block, sizeof(block));
447 return rval;
448 }
449