1 /* rijndael-api-fst.c --- Rijndael cipher implementation.
2 * Copyright (C) 2005, 2006 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, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 /* Adapted for gnulib by Simon Josefsson.
23 * Based on public domain "Optimised C code" retrieved from (SHA1
24 * 7c8e4b00d06685d1dbc6724a9e0d502353de339e):
25 * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/rijndael-fst-3.0.zip
33 * @version 2.9 (December 2000)
35 * Optimised ANSI C code for the Rijndael cipher (now AES)
37 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
38 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
39 * @author Paulo Barreto <paulo.barreto@terra.com.br>
41 * This code is hereby placed in the public domain.
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
47 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
50 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
52 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
53 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57 * We are deeply indebted to the following people for their bug reports,
58 * fixes, and improvement suggestions to this implementation. Though we
59 * tried to list all contributions, we apologise in advance for any
62 * Andrew Bales <Andrew.Bales@Honeywell.com>
63 * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
64 * John Skodon <skodonj@webquill.com>
67 #include "rijndael-alg-fst.h"
68 #include "rijndael-api-fst.h"
75 rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction,
76 size_t keyLen, const char *keyMaterial)
80 char cipherKey[RIJNDAEL_MAXKB];
84 return RIJNDAEL_BAD_KEY_INSTANCE;
87 if ((direction == RIJNDAEL_DIR_ENCRYPT)
88 || (direction == RIJNDAEL_DIR_DECRYPT))
90 key->direction = direction;
94 return RIJNDAEL_BAD_KEY_DIR;
97 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256))
103 return RIJNDAEL_BAD_KEY_MAT;
106 if (keyMaterial != NULL)
108 strncpy (key->keyMaterial, keyMaterial, keyLen / 4);
111 /* initialize key schedule: */
112 keyMat = key->keyMaterial;
113 for (i = 0; i < key->keyLen / 8; i++)
118 if ((t >= '0') && (t <= '9'))
120 else if ((t >= 'a') && (t <= 'f'))
121 v = (t - 'a' + 10) << 4;
122 else if ((t >= 'A') && (t <= 'F'))
123 v = (t - 'A' + 10) << 4;
125 return RIJNDAEL_BAD_KEY_MAT;
128 if ((t >= '0') && (t <= '9'))
130 else if ((t >= 'a') && (t <= 'f'))
132 else if ((t >= 'A') && (t <= 'F'))
135 return RIJNDAEL_BAD_KEY_MAT;
139 if (direction == RIJNDAEL_DIR_ENCRYPT)
141 key->Nr = rijndaelKeySetupEnc (key->rk, cipherKey, keyLen);
145 key->Nr = rijndaelKeySetupDec (key->rk, cipherKey, keyLen);
147 rijndaelKeySetupEnc (key->ek, cipherKey, keyLen);
152 rijndaelCipherInit (rijndaelCipherInstance *cipher, rijndael_mode mode,
155 if ((mode == RIJNDAEL_MODE_ECB) || (mode == RIJNDAEL_MODE_CBC)
156 || (mode == RIJNDAEL_MODE_CFB1))
162 return RIJNDAEL_BAD_CIPHER_MODE;
167 for (i = 0; i < RIJNDAEL_MAX_IV_SIZE; i++)
172 if ((t >= '0') && (t <= '9'))
174 else if ((t >= 'a') && (t <= 'f'))
175 j = (t - 'a' + 10) << 4;
176 else if ((t >= 'A') && (t <= 'F'))
177 j = (t - 'A' + 10) << 4;
179 return RIJNDAEL_BAD_CIPHER_INSTANCE;
182 if ((t >= '0') && (t <= '9'))
184 else if ((t >= 'a') && (t <= 'f'))
186 else if ((t >= 'A') && (t <= 'F'))
189 return RIJNDAEL_BAD_CIPHER_INSTANCE;
191 cipher->IV[i] = (uint8_t) j;
196 memset (cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
202 rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
203 const rijndaelKeyInstance *key,
205 size_t inputLen, char *outBuffer)
207 size_t i, k, t, numBlocks;
210 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
212 return RIJNDAEL_BAD_CIPHER_STATE;
214 if (input == NULL || inputLen <= 0)
216 return 0; /* nothing to do */
219 numBlocks = inputLen / 128;
221 switch (cipher->mode)
223 case RIJNDAEL_MODE_ECB:
224 for (i = numBlocks; i > 0; i--)
226 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
232 case RIJNDAEL_MODE_CBC:
234 for (i = numBlocks; i > 0; i--)
236 ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
237 ((uint32_t *) iv)[0];
238 ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
239 ((uint32_t *) iv)[1];
240 ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
241 ((uint32_t *) iv)[2];
242 ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
243 ((uint32_t *) iv)[3];
244 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
245 memcpy (cipher->IV, outBuffer, 16);
251 case RIJNDAEL_MODE_CFB1:
253 for (i = numBlocks; i > 0; i--)
255 memcpy (outBuffer, input, 16);
256 for (k = 0; k < 128; k++)
258 rijndaelEncrypt (key->ek, key->Nr, iv, block);
259 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
260 for (t = 0; t < 15; t++)
262 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
264 iv[15] = (iv[15] << 1) |
265 ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
273 return RIJNDAEL_BAD_CIPHER_STATE;
276 return 128 * numBlocks;
280 rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
281 const rijndaelKeyInstance *key,
283 size_t inputOctets, char *outBuffer)
285 size_t i, numBlocks, padLen;
288 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
290 return RIJNDAEL_BAD_CIPHER_STATE;
292 if (input == NULL || inputOctets <= 0)
294 return 0; /* nothing to do */
297 numBlocks = inputOctets / 16;
299 switch (cipher->mode)
301 case RIJNDAEL_MODE_ECB:
302 for (i = numBlocks; i > 0; i--)
304 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
308 padLen = 16 - (inputOctets - 16 * numBlocks);
309 assert (padLen > 0 && padLen <= 16);
310 memcpy (block, input, 16 - padLen);
311 memset (block + 16 - padLen, padLen, padLen);
312 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
315 case RIJNDAEL_MODE_CBC:
317 for (i = numBlocks; i > 0; i--)
319 ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
320 ((uint32_t *) iv)[0];
321 ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
322 ((uint32_t *) iv)[1];
323 ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
324 ((uint32_t *) iv)[2];
325 ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
326 ((uint32_t *) iv)[3];
327 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
328 memcpy (cipher->IV, outBuffer, 16);
332 padLen = 16 - (inputOctets - 16 * numBlocks);
333 assert (padLen > 0 && padLen <= 16);
334 for (i = 0; i < 16 - padLen; i++)
336 block[i] = input[i] ^ iv[i];
338 for (i = 16 - padLen; i < 16; i++)
340 block[i] = (char) padLen ^ iv[i];
342 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
343 memcpy (cipher->IV, outBuffer, 16);
347 return RIJNDAEL_BAD_CIPHER_STATE;
350 return 16 * (numBlocks + 1);
354 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
355 const rijndaelKeyInstance *key,
357 size_t inputLen, char *outBuffer)
359 size_t i, k, t, numBlocks;
364 || (cipher->mode != RIJNDAEL_MODE_CFB1
365 && key->direction == RIJNDAEL_DIR_ENCRYPT))
367 return RIJNDAEL_BAD_CIPHER_STATE;
369 if (input == NULL || inputLen <= 0)
371 return 0; /* nothing to do */
374 numBlocks = inputLen / 128;
376 switch (cipher->mode)
378 case RIJNDAEL_MODE_ECB:
379 for (i = numBlocks; i > 0; i--)
381 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
387 case RIJNDAEL_MODE_CBC:
389 for (i = numBlocks; i > 0; i--)
391 rijndaelDecrypt (key->rk, key->Nr, input, block);
392 ((uint32_t *) block)[0] ^= ((uint32_t *) iv)[0];
393 ((uint32_t *) block)[1] ^= ((uint32_t *) iv)[1];
394 ((uint32_t *) block)[2] ^= ((uint32_t *) iv)[2];
395 ((uint32_t *) block)[3] ^= ((uint32_t *) iv)[3];
396 memcpy (cipher->IV, input, 16);
397 memcpy (outBuffer, block, 16);
403 case RIJNDAEL_MODE_CFB1:
405 for (i = numBlocks; i > 0; i--)
407 memcpy (outBuffer, input, 16);
408 for (k = 0; k < 128; k++)
410 rijndaelEncrypt (key->ek, key->Nr, iv, block);
411 for (t = 0; t < 15; t++)
413 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
415 iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
416 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
424 return RIJNDAEL_BAD_CIPHER_STATE;
427 return 128 * numBlocks;
431 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
432 const rijndaelKeyInstance *key,
434 size_t inputOctets, char *outBuffer)
436 size_t i, numBlocks, padLen;
439 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_ENCRYPT)
441 return RIJNDAEL_BAD_CIPHER_STATE;
443 if (input == NULL || inputOctets <= 0)
445 return 0; /* nothing to do */
447 if (inputOctets % 16 != 0)
449 return RIJNDAEL_BAD_DATA;
452 numBlocks = inputOctets / 16;
454 switch (cipher->mode)
456 case RIJNDAEL_MODE_ECB:
457 /* all blocks but last */
458 for (i = numBlocks - 1; i > 0; i--)
460 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
465 rijndaelDecrypt (key->rk, key->Nr, input, block);
469 return RIJNDAEL_BAD_DATA;
471 for (i = 16 - padLen; i < 16; i++)
473 if (block[i] != padLen)
475 return RIJNDAEL_BAD_DATA;
478 memcpy (outBuffer, block, 16 - padLen);
481 case RIJNDAEL_MODE_CBC:
482 /* all blocks but last */
483 for (i = numBlocks - 1; i > 0; i--)
485 rijndaelDecrypt (key->rk, key->Nr, input, block);
486 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
487 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
488 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
489 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
490 memcpy (cipher->IV, input, 16);
491 memcpy (outBuffer, block, 16);
496 rijndaelDecrypt (key->rk, key->Nr, input, block);
497 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
498 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
499 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
500 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
502 if (padLen <= 0 || padLen > 16)
504 return RIJNDAEL_BAD_DATA;
506 for (i = 16 - padLen; i < 16; i++)
508 if (block[i] != padLen)
510 return RIJNDAEL_BAD_DATA;
513 memcpy (outBuffer, block, 16 - padLen);
517 return RIJNDAEL_BAD_CIPHER_STATE;
520 return 16 * numBlocks - padLen;