1 /* rijndael-api-fst.c --- Rijndael cipher implementation.
2 * Copyright (C) 2005 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
35 * @version 2.9 (December 2000)
37 * Optimised ANSI C code for the Rijndael cipher (now AES)
39 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
40 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
41 * @author Paulo Barreto <paulo.barreto@terra.com.br>
43 * This code is hereby placed in the public domain.
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
46 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
47 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
49 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
52 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
54 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
55 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 * We are deeply indebted to the following people for their bug reports,
60 * fixes, and improvement suggestions to this implementation. Though we
61 * tried to list all contributions, we apologise in advance for any
64 * Andrew Bales <Andrew.Bales@Honeywell.com>
65 * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
66 * John Skodon <skodonj@webquill.com>
69 #include "rijndael-alg-fst.h"
70 #include "rijndael-api-fst.h"
77 rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction,
78 size_t keyLen, const char *keyMaterial)
82 char cipherKey[RIJNDAEL_MAXKB];
86 return RIJNDAEL_BAD_KEY_INSTANCE;
89 if ((direction == RIJNDAEL_DIR_ENCRYPT)
90 || (direction == RIJNDAEL_DIR_DECRYPT))
92 key->direction = direction;
96 return RIJNDAEL_BAD_KEY_DIR;
99 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256))
101 key->keyLen = keyLen;
105 return RIJNDAEL_BAD_KEY_MAT;
108 if (keyMaterial != NULL)
110 strncpy (key->keyMaterial, keyMaterial, keyLen / 4);
113 /* initialize key schedule: */
114 keyMat = key->keyMaterial;
115 for (i = 0; i < key->keyLen / 8; i++)
120 if ((t >= '0') && (t <= '9'))
122 else if ((t >= 'a') && (t <= 'f'))
123 v = (t - 'a' + 10) << 4;
124 else if ((t >= 'A') && (t <= 'F'))
125 v = (t - 'A' + 10) << 4;
127 return RIJNDAEL_BAD_KEY_MAT;
130 if ((t >= '0') && (t <= '9'))
132 else if ((t >= 'a') && (t <= 'f'))
134 else if ((t >= 'A') && (t <= 'F'))
137 return RIJNDAEL_BAD_KEY_MAT;
141 if (direction == RIJNDAEL_DIR_ENCRYPT)
143 key->Nr = rijndaelKeySetupEnc (key->rk, cipherKey, keyLen);
147 key->Nr = rijndaelKeySetupDec (key->rk, cipherKey, keyLen);
149 rijndaelKeySetupEnc (key->ek, cipherKey, keyLen);
154 rijndaelCipherInit (rijndaelCipherInstance *cipher, rijndael_mode mode,
157 if ((mode == RIJNDAEL_MODE_ECB) || (mode == RIJNDAEL_MODE_CBC)
158 || (mode == RIJNDAEL_MODE_CFB1))
164 return RIJNDAEL_BAD_CIPHER_MODE;
169 for (i = 0; i < RIJNDAEL_MAX_IV_SIZE; i++)
174 if ((t >= '0') && (t <= '9'))
176 else if ((t >= 'a') && (t <= 'f'))
177 j = (t - 'a' + 10) << 4;
178 else if ((t >= 'A') && (t <= 'F'))
179 j = (t - 'A' + 10) << 4;
181 return RIJNDAEL_BAD_CIPHER_INSTANCE;
184 if ((t >= '0') && (t <= '9'))
186 else if ((t >= 'a') && (t <= 'f'))
188 else if ((t >= 'A') && (t <= 'F'))
191 return RIJNDAEL_BAD_CIPHER_INSTANCE;
193 cipher->IV[i] = (uint8_t) j;
198 memset (cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
204 rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
205 const rijndaelKeyInstance *key,
207 size_t inputLen, char *outBuffer)
209 size_t i, k, t, numBlocks;
212 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
214 return RIJNDAEL_BAD_CIPHER_STATE;
216 if (input == NULL || inputLen <= 0)
218 return 0; /* nothing to do */
221 numBlocks = inputLen / 128;
223 switch (cipher->mode)
225 case RIJNDAEL_MODE_ECB:
226 for (i = numBlocks; i > 0; i--)
228 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
234 case RIJNDAEL_MODE_CBC:
236 for (i = numBlocks; i > 0; i--)
238 ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
239 ((uint32_t *) iv)[0];
240 ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
241 ((uint32_t *) iv)[1];
242 ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
243 ((uint32_t *) iv)[2];
244 ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
245 ((uint32_t *) iv)[3];
246 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
247 memcpy (cipher->IV, outBuffer, 16);
253 case RIJNDAEL_MODE_CFB1:
255 for (i = numBlocks; i > 0; i--)
257 memcpy (outBuffer, input, 16);
258 for (k = 0; k < 128; k++)
260 rijndaelEncrypt (key->ek, key->Nr, iv, block);
261 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
262 for (t = 0; t < 15; t++)
264 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
266 iv[15] = (iv[15] << 1) |
267 ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
275 return RIJNDAEL_BAD_CIPHER_STATE;
278 return 128 * numBlocks;
282 rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
283 const rijndaelKeyInstance *key,
285 size_t inputOctets, char *outBuffer)
287 size_t i, numBlocks, padLen;
290 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
292 return RIJNDAEL_BAD_CIPHER_STATE;
294 if (input == NULL || inputOctets <= 0)
296 return 0; /* nothing to do */
299 numBlocks = inputOctets / 16;
301 switch (cipher->mode)
303 case RIJNDAEL_MODE_ECB:
304 for (i = numBlocks; i > 0; i--)
306 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
310 padLen = 16 - (inputOctets - 16 * numBlocks);
311 assert (padLen > 0 && padLen <= 16);
312 memcpy (block, input, 16 - padLen);
313 memset (block + 16 - padLen, padLen, padLen);
314 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
317 case RIJNDAEL_MODE_CBC:
319 for (i = numBlocks; i > 0; i--)
321 ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
322 ((uint32_t *) iv)[0];
323 ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
324 ((uint32_t *) iv)[1];
325 ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
326 ((uint32_t *) iv)[2];
327 ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
328 ((uint32_t *) iv)[3];
329 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
330 memcpy (cipher->IV, outBuffer, 16);
334 padLen = 16 - (inputOctets - 16 * numBlocks);
335 assert (padLen > 0 && padLen <= 16);
336 for (i = 0; i < 16 - padLen; i++)
338 block[i] = input[i] ^ iv[i];
340 for (i = 16 - padLen; i < 16; i++)
342 block[i] = (char) padLen ^ iv[i];
344 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
345 memcpy (cipher->IV, outBuffer, 16);
349 return RIJNDAEL_BAD_CIPHER_STATE;
352 return 16 * (numBlocks + 1);
356 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
357 const rijndaelKeyInstance *key,
359 size_t inputLen, char *outBuffer)
361 size_t i, k, t, numBlocks;
364 if (cipher == NULL ||
366 cipher->mode != RIJNDAEL_MODE_CFB1
367 && key->direction == RIJNDAEL_DIR_ENCRYPT)
369 return RIJNDAEL_BAD_CIPHER_STATE;
371 if (input == NULL || inputLen <= 0)
373 return 0; /* nothing to do */
376 numBlocks = inputLen / 128;
378 switch (cipher->mode)
380 case RIJNDAEL_MODE_ECB:
381 for (i = numBlocks; i > 0; i--)
383 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
389 case RIJNDAEL_MODE_CBC:
391 for (i = numBlocks; i > 0; i--)
393 rijndaelDecrypt (key->rk, key->Nr, input, block);
394 ((uint32_t *) block)[0] ^= ((uint32_t *) iv)[0];
395 ((uint32_t *) block)[1] ^= ((uint32_t *) iv)[1];
396 ((uint32_t *) block)[2] ^= ((uint32_t *) iv)[2];
397 ((uint32_t *) block)[3] ^= ((uint32_t *) iv)[3];
398 memcpy (cipher->IV, input, 16);
399 memcpy (outBuffer, block, 16);
405 case RIJNDAEL_MODE_CFB1:
407 for (i = numBlocks; i > 0; i--)
409 memcpy (outBuffer, input, 16);
410 for (k = 0; k < 128; k++)
412 rijndaelEncrypt (key->ek, key->Nr, iv, block);
413 for (t = 0; t < 15; t++)
415 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
417 iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
418 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
426 return RIJNDAEL_BAD_CIPHER_STATE;
429 return 128 * numBlocks;
433 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
434 const rijndaelKeyInstance *key,
436 size_t inputOctets, char *outBuffer)
438 size_t i, numBlocks, padLen;
441 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_ENCRYPT)
443 return RIJNDAEL_BAD_CIPHER_STATE;
445 if (input == NULL || inputOctets <= 0)
447 return 0; /* nothing to do */
449 if (inputOctets % 16 != 0)
451 return RIJNDAEL_BAD_DATA;
454 numBlocks = inputOctets / 16;
456 switch (cipher->mode)
458 case RIJNDAEL_MODE_ECB:
459 /* all blocks but last */
460 for (i = numBlocks - 1; i > 0; i--)
462 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
467 rijndaelDecrypt (key->rk, key->Nr, input, block);
471 return RIJNDAEL_BAD_DATA;
473 for (i = 16 - padLen; i < 16; i++)
475 if (block[i] != padLen)
477 return RIJNDAEL_BAD_DATA;
480 memcpy (outBuffer, block, 16 - padLen);
483 case RIJNDAEL_MODE_CBC:
484 /* all blocks but last */
485 for (i = numBlocks - 1; i > 0; i--)
487 rijndaelDecrypt (key->rk, key->Nr, input, block);
488 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
489 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
490 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
491 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
492 memcpy (cipher->IV, input, 16);
493 memcpy (outBuffer, block, 16);
498 rijndaelDecrypt (key->rk, key->Nr, input, block);
499 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
500 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
501 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
502 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
504 if (padLen <= 0 || padLen > 16)
506 return RIJNDAEL_BAD_DATA;
508 for (i = 16 - padLen; i < 16; i++)
510 if (block[i] != padLen)
512 return RIJNDAEL_BAD_DATA;
515 memcpy (outBuffer, block, 16 - padLen);
519 return RIJNDAEL_BAD_CIPHER_STATE;
522 return 16 * numBlocks - padLen;