havelib: Support overriding the result of AC_LIB_PREPARE_MULTILIB.
[gnulib.git] / lib / rijndael-api-fst.c
blobb41660125acf7096c8d141813647aa20016105ab
1 /* rijndael-api-fst.c --- Rijndael cipher implementation.
2 * Copyright (C) 2005-2006, 2009-2017 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
26 #include <config.h>
28 /**
29 * rijndael-api-fst.c
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.
53 * Acknowledgements:
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
58 * missing reference.
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"
68 #include <assert.h>
69 #include <stdlib.h>
70 #include <string.h>
72 rijndael_rc
73 rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction,
74 size_t keyLen, const char *keyMaterial)
76 size_t i;
77 char *keyMat;
78 char cipherKey[RIJNDAEL_MAXKB];
80 if (key == NULL)
82 return RIJNDAEL_BAD_KEY_INSTANCE;
85 if ((direction == RIJNDAEL_DIR_ENCRYPT)
86 || (direction == RIJNDAEL_DIR_DECRYPT))
88 key->direction = direction;
90 else
92 return RIJNDAEL_BAD_KEY_DIR;
95 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256))
97 key->keyLen = keyLen;
99 else
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++)
113 char t, v;
115 t = *keyMat++;
116 if ((t >= '0') && (t <= '9'))
117 v = (t - '0') << 4;
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;
122 else
123 return RIJNDAEL_BAD_KEY_MAT;
125 t = *keyMat++;
126 if ((t >= '0') && (t <= '9'))
127 v ^= (t - '0');
128 else if ((t >= 'a') && (t <= 'f'))
129 v ^= (t - 'a' + 10);
130 else if ((t >= 'A') && (t <= 'F'))
131 v ^= (t - 'A' + 10);
132 else
133 return RIJNDAEL_BAD_KEY_MAT;
135 cipherKey[i] = v;
137 if (direction == RIJNDAEL_DIR_ENCRYPT)
139 key->Nr = rijndaelKeySetupEnc (key->rk, cipherKey, keyLen);
141 else
143 key->Nr = rijndaelKeySetupDec (key->rk, cipherKey, keyLen);
145 rijndaelKeySetupEnc (key->ek, cipherKey, keyLen);
146 return 0;
149 rijndael_rc
150 rijndaelCipherInit (rijndaelCipherInstance *cipher, rijndael_mode mode,
151 const char *IV)
153 if ((mode == RIJNDAEL_MODE_ECB) || (mode == RIJNDAEL_MODE_CBC)
154 || (mode == RIJNDAEL_MODE_CFB1))
156 cipher->mode = mode;
158 else
160 return RIJNDAEL_BAD_CIPHER_MODE;
162 if (IV != NULL)
164 int i;
165 for (i = 0; i < RIJNDAEL_MAX_IV_SIZE; i++)
167 int t, j;
169 t = IV[2 * i];
170 if ((t >= '0') && (t <= '9'))
171 j = (t - '0') << 4;
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;
176 else
177 return RIJNDAEL_BAD_CIPHER_INSTANCE;
179 t = IV[2 * i + 1];
180 if ((t >= '0') && (t <= '9'))
181 j ^= (t - '0');
182 else if ((t >= 'a') && (t <= 'f'))
183 j ^= (t - 'a' + 10);
184 else if ((t >= 'A') && (t <= 'F'))
185 j ^= (t - 'A' + 10);
186 else
187 return RIJNDAEL_BAD_CIPHER_INSTANCE;
189 cipher->IV[i] = (uint8_t) j;
192 else
194 memset (cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
196 return 0;
200 rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
201 const rijndaelKeyInstance *key,
202 const char *input,
203 size_t inputLen, char *outBuffer)
205 size_t i, k, t, numBlocks;
206 char block[16], *iv;
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);
225 input += 16;
226 outBuffer += 16;
228 break;
230 case RIJNDAEL_MODE_CBC:
231 iv = cipher->IV;
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);
244 input += 16;
245 outBuffer += 16;
247 break;
249 case RIJNDAEL_MODE_CFB1:
250 iv = cipher->IV;
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);
265 outBuffer += 16;
266 input += 16;
268 break;
270 default:
271 return RIJNDAEL_BAD_CIPHER_STATE;
274 return 128 * numBlocks;
278 rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
279 const rijndaelKeyInstance *key,
280 const char *input,
281 size_t inputOctets, char *outBuffer)
283 size_t i, numBlocks, padLen;
284 char block[16], *iv;
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);
303 input += 16;
304 outBuffer += 16;
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);
311 break;
313 case RIJNDAEL_MODE_CBC:
314 iv = cipher->IV;
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);
327 input += 16;
328 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);
342 break;
344 default:
345 return RIJNDAEL_BAD_CIPHER_STATE;
348 return 16 * (numBlocks + 1);
352 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
353 const rijndaelKeyInstance *key,
354 const char *input,
355 size_t inputLen, char *outBuffer)
357 size_t i, k, t, numBlocks;
358 char block[16], *iv;
360 if (cipher == NULL
361 || key == NULL
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);
380 input += 16;
381 outBuffer += 16;
383 break;
385 case RIJNDAEL_MODE_CBC:
386 iv = cipher->IV;
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);
396 input += 16;
397 outBuffer += 16;
399 break;
401 case RIJNDAEL_MODE_CFB1:
402 iv = cipher->IV;
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);
416 outBuffer += 16;
417 input += 16;
419 break;
421 default:
422 return RIJNDAEL_BAD_CIPHER_STATE;
425 return 128 * numBlocks;
429 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
430 const rijndaelKeyInstance *key,
431 const char *input,
432 size_t inputOctets, char *outBuffer)
434 size_t i, numBlocks, padLen;
435 char block[16];
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);
459 input += 16;
460 outBuffer += 16;
462 /* last block */
463 rijndaelDecrypt (key->rk, key->Nr, input, block);
464 padLen = block[15];
465 if (padLen >= 16)
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);
477 break;
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);
490 input += 16;
491 outBuffer += 16;
493 /* last block */
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];
499 padLen = block[15];
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);
512 break;
514 default:
515 return RIJNDAEL_BAD_CIPHER_STATE;
518 return 16 * numBlocks - padLen;