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);
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);
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);
348 return RIJNDAEL_BAD_CIPHER_STATE;
351 return 16 * (numBlocks + 1);
355 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
356 const rijndaelKeyInstance *key,
358 size_t inputLen, char *outBuffer)
360 size_t i, k, t, numBlocks;
363 if (cipher == NULL ||
365 cipher->mode != RIJNDAEL_MODE_CFB1
366 && key->direction == RIJNDAEL_DIR_ENCRYPT)
368 return RIJNDAEL_BAD_CIPHER_STATE;
370 if (input == NULL || inputLen <= 0)
372 return 0; /* nothing to do */
375 numBlocks = inputLen / 128;
377 switch (cipher->mode)
379 case RIJNDAEL_MODE_ECB:
380 for (i = numBlocks; i > 0; i--)
382 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
388 case RIJNDAEL_MODE_CBC:
390 for (i = numBlocks; i > 0; i--)
392 rijndaelDecrypt (key->rk, key->Nr, input, block);
393 ((uint32_t *) block)[0] ^= ((uint32_t *) iv)[0];
394 ((uint32_t *) block)[1] ^= ((uint32_t *) iv)[1];
395 ((uint32_t *) block)[2] ^= ((uint32_t *) iv)[2];
396 ((uint32_t *) block)[3] ^= ((uint32_t *) iv)[3];
397 memcpy (cipher->IV, input, 16);
398 memcpy (outBuffer, block, 16);
404 case RIJNDAEL_MODE_CFB1:
406 for (i = numBlocks; i > 0; i--)
408 memcpy (outBuffer, input, 16);
409 for (k = 0; k < 128; k++)
411 rijndaelEncrypt (key->ek, key->Nr, iv, block);
412 for (t = 0; t < 15; t++)
414 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
416 iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
417 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
425 return RIJNDAEL_BAD_CIPHER_STATE;
428 return 128 * numBlocks;
432 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
433 const rijndaelKeyInstance *key,
435 size_t inputOctets, char *outBuffer)
437 size_t i, numBlocks, padLen;
440 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_ENCRYPT)
442 return RIJNDAEL_BAD_CIPHER_STATE;
444 if (input == NULL || inputOctets <= 0)
446 return 0; /* nothing to do */
448 if (inputOctets % 16 != 0)
450 return RIJNDAEL_BAD_DATA;
453 numBlocks = inputOctets / 16;
455 switch (cipher->mode)
457 case RIJNDAEL_MODE_ECB:
458 /* all blocks but last */
459 for (i = numBlocks - 1; i > 0; i--)
461 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
466 rijndaelDecrypt (key->rk, key->Nr, input, block);
470 return RIJNDAEL_BAD_DATA;
472 for (i = 16 - padLen; i < 16; i++)
474 if (block[i] != padLen)
476 return RIJNDAEL_BAD_DATA;
479 memcpy (outBuffer, block, 16 - padLen);
482 case RIJNDAEL_MODE_CBC:
483 /* all blocks but last */
484 for (i = numBlocks - 1; i > 0; i--)
486 rijndaelDecrypt (key->rk, key->Nr, input, block);
487 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
488 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
489 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
490 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
491 memcpy (cipher->IV, input, 16);
492 memcpy (outBuffer, block, 16);
497 rijndaelDecrypt (key->rk, key->Nr, input, block);
498 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
499 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
500 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
501 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
503 if (padLen <= 0 || padLen > 16)
505 return RIJNDAEL_BAD_DATA;
507 for (i = 16 - padLen; i < 16; i++)
509 if (block[i] != padLen)
511 return RIJNDAEL_BAD_DATA;
514 memcpy (outBuffer, block, 16 - padLen);
518 return RIJNDAEL_BAD_CIPHER_STATE;
521 return 16 * numBlocks - padLen;