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
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
;