maint: update copyright
[gnulib.git] / lib / rijndael-api-fst.c
1 /* rijndael-api-fst.c --- Rijndael cipher implementation.
2  * Copyright (C) 2005-2006, 2009-2014 Free Software Foundation, Inc.
3  *
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.
8  *
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.
13  *
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/>.
16  *
17  */
18
19 /* Adapted for gnulib by Simon Josefsson.
20  *
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
24  */
25
26 #include <config.h>
27
28 /**
29  * rijndael-api-fst.c
30  *
31  * @version 2.9 (December 2000)
32  *
33  * Optimised ANSI C code for the Rijndael cipher (now AES)
34  *
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>
38  *
39  * This code is hereby placed in the public domain.
40  *
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.
52  *
53  * Acknowledgements:
54  *
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.
59  *
60  * Andrew Bales <Andrew.Bales@Honeywell.com>
61  * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
62  * John Skodon <skodonj@webquill.com>
63  */
64
65 #include "rijndael-alg-fst.h"
66 #include "rijndael-api-fst.h"
67
68 #include <assert.h>
69 #include <stdlib.h>
70 #include <string.h>
71
72 rijndael_rc
73 rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction,
74                  size_t keyLen, const char *keyMaterial)
75 {
76   size_t i;
77   char *keyMat;
78   char cipherKey[RIJNDAEL_MAXKB];
79
80   if (key == NULL)
81     {
82       return RIJNDAEL_BAD_KEY_INSTANCE;
83     }
84
85   if ((direction == RIJNDAEL_DIR_ENCRYPT)
86       || (direction == RIJNDAEL_DIR_DECRYPT))
87     {
88       key->direction = direction;
89     }
90   else
91     {
92       return RIJNDAEL_BAD_KEY_DIR;
93     }
94
95   if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256))
96     {
97       key->keyLen = keyLen;
98     }
99   else
100     {
101       return RIJNDAEL_BAD_KEY_MAT;
102     }
103
104   if (keyMaterial != NULL)
105     {
106       strncpy (key->keyMaterial, keyMaterial, keyLen / 4);
107     }
108
109   /* initialize key schedule: */
110   keyMat = key->keyMaterial;
111   for (i = 0; i < key->keyLen / 8; i++)
112     {
113       char t, v;
114
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;
124
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;
134
135       cipherKey[i] = v;
136     }
137   if (direction == RIJNDAEL_DIR_ENCRYPT)
138     {
139       key->Nr = rijndaelKeySetupEnc (key->rk, cipherKey, keyLen);
140     }
141   else
142     {
143       key->Nr = rijndaelKeySetupDec (key->rk, cipherKey, keyLen);
144     }
145   rijndaelKeySetupEnc (key->ek, cipherKey, keyLen);
146   return 0;
147 }
148
149 rijndael_rc
150 rijndaelCipherInit (rijndaelCipherInstance *cipher, rijndael_mode mode,
151                     const char *IV)
152 {
153   if ((mode == RIJNDAEL_MODE_ECB) || (mode == RIJNDAEL_MODE_CBC)
154       || (mode == RIJNDAEL_MODE_CFB1))
155     {
156       cipher->mode = mode;
157     }
158   else
159     {
160       return RIJNDAEL_BAD_CIPHER_MODE;
161     }
162   if (IV != NULL)
163     {
164       int i;
165       for (i = 0; i < RIJNDAEL_MAX_IV_SIZE; i++)
166         {
167           int t, j;
168
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;
178
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;
188
189           cipher->IV[i] = (uint8_t) j;
190         }
191     }
192   else
193     {
194       memset (cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
195     }
196   return 0;
197 }
198
199 int
200 rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
201                       const rijndaelKeyInstance *key,
202                       const char *input,
203                       size_t inputLen, char *outBuffer)
204 {
205   size_t i, k, t, numBlocks;
206   char block[16], *iv;
207
208   if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
209     {
210       return RIJNDAEL_BAD_CIPHER_STATE;
211     }
212   if (input == NULL || inputLen <= 0)
213     {
214       return 0;                 /* nothing to do */
215     }
216
217   numBlocks = inputLen / 128;
218
219   switch (cipher->mode)
220     {
221     case RIJNDAEL_MODE_ECB:
222       for (i = numBlocks; i > 0; i--)
223         {
224           rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
225           input += 16;
226           outBuffer += 16;
227         }
228       break;
229
230     case RIJNDAEL_MODE_CBC:
231       iv = cipher->IV;
232       for (i = numBlocks; i > 0; i--)
233         {
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;
246         }
247       break;
248
249     case RIJNDAEL_MODE_CFB1:
250       iv = cipher->IV;
251       for (i = numBlocks; i > 0; i--)
252         {
253           memcpy (outBuffer, input, 16);
254           for (k = 0; k < 128; k++)
255             {
256               rijndaelEncrypt (key->ek, key->Nr, iv, block);
257               outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
258               for (t = 0; t < 15; t++)
259                 {
260                   iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
261                 }
262               iv[15] = (iv[15] << 1) |
263                 ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
264             }
265           outBuffer += 16;
266           input += 16;
267         }
268       break;
269
270     default:
271       return RIJNDAEL_BAD_CIPHER_STATE;
272     }
273
274   return 128 * numBlocks;
275 }
276
277 int
278 rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
279                     const rijndaelKeyInstance *key,
280                     const char *input,
281                     size_t inputOctets, char *outBuffer)
282 {
283   size_t i, numBlocks, padLen;
284   char block[16], *iv;
285
286   if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
287     {
288       return RIJNDAEL_BAD_CIPHER_STATE;
289     }
290   if (input == NULL || inputOctets <= 0)
291     {
292       return 0;                 /* nothing to do */
293     }
294
295   numBlocks = inputOctets / 16;
296
297   switch (cipher->mode)
298     {
299     case RIJNDAEL_MODE_ECB:
300       for (i = numBlocks; i > 0; i--)
301         {
302           rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
303           input += 16;
304           outBuffer += 16;
305         }
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;
312
313     case RIJNDAEL_MODE_CBC:
314       iv = cipher->IV;
315       for (i = numBlocks; i > 0; i--)
316         {
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;
329         }
330       padLen = 16 - (inputOctets - 16 * numBlocks);
331       assert (padLen > 0 && padLen <= 16);
332       for (i = 0; i < 16 - padLen; i++)
333         {
334           block[i] = input[i] ^ iv[i];
335         }
336       for (i = 16 - padLen; i < 16; i++)
337         {
338           block[i] = (char) padLen ^ iv[i];
339         }
340       rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
341       memcpy (cipher->IV, outBuffer, 16);
342       break;
343
344     default:
345       return RIJNDAEL_BAD_CIPHER_STATE;
346     }
347
348   return 16 * (numBlocks + 1);
349 }
350
351 int
352 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
353                       const rijndaelKeyInstance *key,
354                       const char *input,
355                       size_t inputLen, char *outBuffer)
356 {
357   size_t i, k, t, numBlocks;
358   char block[16], *iv;
359
360   if (cipher == NULL
361       || key == NULL
362       || (cipher->mode != RIJNDAEL_MODE_CFB1
363           && key->direction == RIJNDAEL_DIR_ENCRYPT))
364     {
365       return RIJNDAEL_BAD_CIPHER_STATE;
366     }
367   if (input == NULL || inputLen <= 0)
368     {
369       return 0;                 /* nothing to do */
370     }
371
372   numBlocks = inputLen / 128;
373
374   switch (cipher->mode)
375     {
376     case RIJNDAEL_MODE_ECB:
377       for (i = numBlocks; i > 0; i--)
378         {
379           rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
380           input += 16;
381           outBuffer += 16;
382         }
383       break;
384
385     case RIJNDAEL_MODE_CBC:
386       iv = cipher->IV;
387       for (i = numBlocks; i > 0; i--)
388         {
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;
398         }
399       break;
400
401     case RIJNDAEL_MODE_CFB1:
402       iv = cipher->IV;
403       for (i = numBlocks; i > 0; i--)
404         {
405           memcpy (outBuffer, input, 16);
406           for (k = 0; k < 128; k++)
407             {
408               rijndaelEncrypt (key->ek, key->Nr, iv, block);
409               for (t = 0; t < 15; t++)
410                 {
411                   iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
412                 }
413               iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
414               outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
415             }
416           outBuffer += 16;
417           input += 16;
418         }
419       break;
420
421     default:
422       return RIJNDAEL_BAD_CIPHER_STATE;
423     }
424
425   return 128 * numBlocks;
426 }
427
428 int
429 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
430                     const rijndaelKeyInstance *key,
431                     const char *input,
432                     size_t inputOctets, char *outBuffer)
433 {
434   size_t i, numBlocks, padLen;
435   char block[16];
436
437   if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_ENCRYPT)
438     {
439       return RIJNDAEL_BAD_CIPHER_STATE;
440     }
441   if (input == NULL || inputOctets <= 0)
442     {
443       return 0;                 /* nothing to do */
444     }
445   if (inputOctets % 16 != 0)
446     {
447       return RIJNDAEL_BAD_DATA;
448     }
449
450   numBlocks = inputOctets / 16;
451
452   switch (cipher->mode)
453     {
454     case RIJNDAEL_MODE_ECB:
455       /* all blocks but last */
456       for (i = numBlocks - 1; i > 0; i--)
457         {
458           rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
459           input += 16;
460           outBuffer += 16;
461         }
462       /* last block */
463       rijndaelDecrypt (key->rk, key->Nr, input, block);
464       padLen = block[15];
465       if (padLen >= 16)
466         {
467           return RIJNDAEL_BAD_DATA;
468         }
469       for (i = 16 - padLen; i < 16; i++)
470         {
471           if (block[i] != padLen)
472             {
473               return RIJNDAEL_BAD_DATA;
474             }
475         }
476       memcpy (outBuffer, block, 16 - padLen);
477       break;
478
479     case RIJNDAEL_MODE_CBC:
480       /* all blocks but last */
481       for (i = numBlocks - 1; i > 0; i--)
482         {
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;
492         }
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)
501         {
502           return RIJNDAEL_BAD_DATA;
503         }
504       for (i = 16 - padLen; i < 16; i++)
505         {
506           if (block[i] != padLen)
507             {
508               return RIJNDAEL_BAD_DATA;
509             }
510         }
511       memcpy (outBuffer, block, 16 - padLen);
512       break;
513
514     default:
515       return RIJNDAEL_BAD_CIPHER_STATE;
516     }
517
518   return 16 * numBlocks - padLen;
519 }