1 /* rijndael-api-fst.c --- Rijndael cipher implementation.
2 * Copyright (C) 2005-2006, 2009-2012 Free Software Foundation, Inc.
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2, or (at your
7 * option) any later version.
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this file; if not, see <http://www.gnu.org/licenses/>.
19 /* Adapted for gnulib by Simon Josefsson.
21 * Based on public domain "Optimised C code" retrieved from (SHA1
22 * 7c8e4b00d06685d1dbc6724a9e0d502353de339e):
23 * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/rijndael-fst-3.0.zip
31 * @version 2.9 (December 2000)
33 * Optimised ANSI C code for the Rijndael cipher (now AES)
35 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
36 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
37 * @author Paulo Barreto <paulo.barreto@terra.com.br>
39 * This code is hereby placed in the public domain.
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
42 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
43 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
45 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
46 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
47 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
48 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
49 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
50 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
51 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
55 * We are deeply indebted to the following people for their bug reports,
56 * fixes, and improvement suggestions to this implementation. Though we
57 * tried to list all contributions, we apologise in advance for any
60 * Andrew Bales <Andrew.Bales@Honeywell.com>
61 * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
62 * John Skodon <skodonj@webquill.com>
65 #include "rijndael-alg-fst.h"
66 #include "rijndael-api-fst.h"
73 rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction,
74 size_t keyLen, const char *keyMaterial)
78 char cipherKey[RIJNDAEL_MAXKB];
82 return RIJNDAEL_BAD_KEY_INSTANCE;
85 if ((direction == RIJNDAEL_DIR_ENCRYPT)
86 || (direction == RIJNDAEL_DIR_DECRYPT))
88 key->direction = direction;
92 return RIJNDAEL_BAD_KEY_DIR;
95 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256))
101 return RIJNDAEL_BAD_KEY_MAT;
104 if (keyMaterial != NULL)
106 strncpy (key->keyMaterial, keyMaterial, keyLen / 4);
109 /* initialize key schedule: */
110 keyMat = key->keyMaterial;
111 for (i = 0; i < key->keyLen / 8; i++)
116 if ((t >= '0') && (t <= '9'))
118 else if ((t >= 'a') && (t <= 'f'))
119 v = (t - 'a' + 10) << 4;
120 else if ((t >= 'A') && (t <= 'F'))
121 v = (t - 'A' + 10) << 4;
123 return RIJNDAEL_BAD_KEY_MAT;
126 if ((t >= '0') && (t <= '9'))
128 else if ((t >= 'a') && (t <= 'f'))
130 else if ((t >= 'A') && (t <= 'F'))
133 return RIJNDAEL_BAD_KEY_MAT;
137 if (direction == RIJNDAEL_DIR_ENCRYPT)
139 key->Nr = rijndaelKeySetupEnc (key->rk, cipherKey, keyLen);
143 key->Nr = rijndaelKeySetupDec (key->rk, cipherKey, keyLen);
145 rijndaelKeySetupEnc (key->ek, cipherKey, keyLen);
150 rijndaelCipherInit (rijndaelCipherInstance *cipher, rijndael_mode mode,
153 if ((mode == RIJNDAEL_MODE_ECB) || (mode == RIJNDAEL_MODE_CBC)
154 || (mode == RIJNDAEL_MODE_CFB1))
160 return RIJNDAEL_BAD_CIPHER_MODE;
165 for (i = 0; i < RIJNDAEL_MAX_IV_SIZE; i++)
170 if ((t >= '0') && (t <= '9'))
172 else if ((t >= 'a') && (t <= 'f'))
173 j = (t - 'a' + 10) << 4;
174 else if ((t >= 'A') && (t <= 'F'))
175 j = (t - 'A' + 10) << 4;
177 return RIJNDAEL_BAD_CIPHER_INSTANCE;
180 if ((t >= '0') && (t <= '9'))
182 else if ((t >= 'a') && (t <= 'f'))
184 else if ((t >= 'A') && (t <= 'F'))
187 return RIJNDAEL_BAD_CIPHER_INSTANCE;
189 cipher->IV[i] = (uint8_t) j;
194 memset (cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
200 rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
201 const rijndaelKeyInstance *key,
203 size_t inputLen, char *outBuffer)
205 size_t i, k, t, numBlocks;
208 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
210 return RIJNDAEL_BAD_CIPHER_STATE;
212 if (input == NULL || inputLen <= 0)
214 return 0; /* nothing to do */
217 numBlocks = inputLen / 128;
219 switch (cipher->mode)
221 case RIJNDAEL_MODE_ECB:
222 for (i = numBlocks; i > 0; i--)
224 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
230 case RIJNDAEL_MODE_CBC:
232 for (i = numBlocks; i > 0; i--)
234 ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
235 ((uint32_t *) iv)[0];
236 ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
237 ((uint32_t *) iv)[1];
238 ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
239 ((uint32_t *) iv)[2];
240 ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
241 ((uint32_t *) iv)[3];
242 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
243 memcpy (cipher->IV, outBuffer, 16);
249 case RIJNDAEL_MODE_CFB1:
251 for (i = numBlocks; i > 0; i--)
253 memcpy (outBuffer, input, 16);
254 for (k = 0; k < 128; k++)
256 rijndaelEncrypt (key->ek, key->Nr, iv, block);
257 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
258 for (t = 0; t < 15; t++)
260 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
262 iv[15] = (iv[15] << 1) |
263 ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
271 return RIJNDAEL_BAD_CIPHER_STATE;
274 return 128 * numBlocks;
278 rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
279 const rijndaelKeyInstance *key,
281 size_t inputOctets, char *outBuffer)
283 size_t i, numBlocks, padLen;
286 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
288 return RIJNDAEL_BAD_CIPHER_STATE;
290 if (input == NULL || inputOctets <= 0)
292 return 0; /* nothing to do */
295 numBlocks = inputOctets / 16;
297 switch (cipher->mode)
299 case RIJNDAEL_MODE_ECB:
300 for (i = numBlocks; i > 0; i--)
302 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
306 padLen = 16 - (inputOctets - 16 * numBlocks);
307 assert (padLen > 0 && padLen <= 16);
308 memcpy (block, input, 16 - padLen);
309 memset (block + 16 - padLen, padLen, padLen);
310 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
313 case RIJNDAEL_MODE_CBC:
315 for (i = numBlocks; i > 0; i--)
317 ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
318 ((uint32_t *) iv)[0];
319 ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
320 ((uint32_t *) iv)[1];
321 ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
322 ((uint32_t *) iv)[2];
323 ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
324 ((uint32_t *) iv)[3];
325 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
326 memcpy (cipher->IV, outBuffer, 16);
330 padLen = 16 - (inputOctets - 16 * numBlocks);
331 assert (padLen > 0 && padLen <= 16);
332 for (i = 0; i < 16 - padLen; i++)
334 block[i] = input[i] ^ iv[i];
336 for (i = 16 - padLen; i < 16; i++)
338 block[i] = (char) padLen ^ iv[i];
340 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
341 memcpy (cipher->IV, outBuffer, 16);
345 return RIJNDAEL_BAD_CIPHER_STATE;
348 return 16 * (numBlocks + 1);
352 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
353 const rijndaelKeyInstance *key,
355 size_t inputLen, char *outBuffer)
357 size_t i, k, t, numBlocks;
362 || (cipher->mode != RIJNDAEL_MODE_CFB1
363 && key->direction == RIJNDAEL_DIR_ENCRYPT))
365 return RIJNDAEL_BAD_CIPHER_STATE;
367 if (input == NULL || inputLen <= 0)
369 return 0; /* nothing to do */
372 numBlocks = inputLen / 128;
374 switch (cipher->mode)
376 case RIJNDAEL_MODE_ECB:
377 for (i = numBlocks; i > 0; i--)
379 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
385 case RIJNDAEL_MODE_CBC:
387 for (i = numBlocks; i > 0; i--)
389 rijndaelDecrypt (key->rk, key->Nr, input, block);
390 ((uint32_t *) block)[0] ^= ((uint32_t *) iv)[0];
391 ((uint32_t *) block)[1] ^= ((uint32_t *) iv)[1];
392 ((uint32_t *) block)[2] ^= ((uint32_t *) iv)[2];
393 ((uint32_t *) block)[3] ^= ((uint32_t *) iv)[3];
394 memcpy (cipher->IV, input, 16);
395 memcpy (outBuffer, block, 16);
401 case RIJNDAEL_MODE_CFB1:
403 for (i = numBlocks; i > 0; i--)
405 memcpy (outBuffer, input, 16);
406 for (k = 0; k < 128; k++)
408 rijndaelEncrypt (key->ek, key->Nr, iv, block);
409 for (t = 0; t < 15; t++)
411 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
413 iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
414 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
422 return RIJNDAEL_BAD_CIPHER_STATE;
425 return 128 * numBlocks;
429 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
430 const rijndaelKeyInstance *key,
432 size_t inputOctets, char *outBuffer)
434 size_t i, numBlocks, padLen;
437 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_ENCRYPT)
439 return RIJNDAEL_BAD_CIPHER_STATE;
441 if (input == NULL || inputOctets <= 0)
443 return 0; /* nothing to do */
445 if (inputOctets % 16 != 0)
447 return RIJNDAEL_BAD_DATA;
450 numBlocks = inputOctets / 16;
452 switch (cipher->mode)
454 case RIJNDAEL_MODE_ECB:
455 /* all blocks but last */
456 for (i = numBlocks - 1; i > 0; i--)
458 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
463 rijndaelDecrypt (key->rk, key->Nr, input, block);
467 return RIJNDAEL_BAD_DATA;
469 for (i = 16 - padLen; i < 16; i++)
471 if (block[i] != padLen)
473 return RIJNDAEL_BAD_DATA;
476 memcpy (outBuffer, block, 16 - padLen);
479 case RIJNDAEL_MODE_CBC:
480 /* all blocks but last */
481 for (i = numBlocks - 1; i > 0; i--)
483 rijndaelDecrypt (key->rk, key->Nr, input, block);
484 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
485 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
486 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
487 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
488 memcpy (cipher->IV, input, 16);
489 memcpy (outBuffer, block, 16);
494 rijndaelDecrypt (key->rk, key->Nr, input, block);
495 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
496 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
497 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
498 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
500 if (padLen <= 0 || padLen > 16)
502 return RIJNDAEL_BAD_DATA;
504 for (i = 16 - padLen; i < 16; i++)
506 if (block[i] != padLen)
508 return RIJNDAEL_BAD_DATA;
511 memcpy (outBuffer, block, 16 - padLen);
515 return RIJNDAEL_BAD_CIPHER_STATE;
518 return 16 * numBlocks - padLen;