update nearly all FSF copyright year lists to include 2009
[gnulib.git] / lib / rijndael-api-fst.c
1 /* rijndael-api-fst.c --- Rijndael cipher implementation.
2  * Copyright (C) 2005, 2006, 2009 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, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  */
20
21 /* Adapted for gnulib by Simon Josefsson.
22  *
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
26  */
27
28 #include <config.h>
29
30 /**
31  * rijndael-api-fst.c
32  *
33  * @version 2.9 (December 2000)
34  *
35  * Optimised ANSI C code for the Rijndael cipher (now AES)
36  *
37  * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
38  * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
39  * @author Paulo Barreto <paulo.barreto@terra.com.br>
40  *
41  * This code is hereby placed in the public domain.
42  *
43  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
44  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
47  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
50  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
51  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
52  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
53  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54  *
55  * Acknowledgements:
56  *
57  * We are deeply indebted to the following people for their bug reports,
58  * fixes, and improvement suggestions to this implementation. Though we
59  * tried to list all contributions, we apologise in advance for any
60  * missing reference.
61  *
62  * Andrew Bales <Andrew.Bales@Honeywell.com>
63  * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
64  * John Skodon <skodonj@webquill.com>
65  */
66
67 #include "rijndael-alg-fst.h"
68 #include "rijndael-api-fst.h"
69
70 #include <assert.h>
71 #include <stdlib.h>
72 #include <string.h>
73
74 rijndael_rc
75 rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction,
76                  size_t keyLen, const char *keyMaterial)
77 {
78   size_t i;
79   char *keyMat;
80   char cipherKey[RIJNDAEL_MAXKB];
81
82   if (key == NULL)
83     {
84       return RIJNDAEL_BAD_KEY_INSTANCE;
85     }
86
87   if ((direction == RIJNDAEL_DIR_ENCRYPT)
88       || (direction == RIJNDAEL_DIR_DECRYPT))
89     {
90       key->direction = direction;
91     }
92   else
93     {
94       return RIJNDAEL_BAD_KEY_DIR;
95     }
96
97   if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256))
98     {
99       key->keyLen = keyLen;
100     }
101   else
102     {
103       return RIJNDAEL_BAD_KEY_MAT;
104     }
105
106   if (keyMaterial != NULL)
107     {
108       strncpy (key->keyMaterial, keyMaterial, keyLen / 4);
109     }
110
111   /* initialize key schedule: */
112   keyMat = key->keyMaterial;
113   for (i = 0; i < key->keyLen / 8; i++)
114     {
115       char t, v;
116
117       t = *keyMat++;
118       if ((t >= '0') && (t <= '9'))
119         v = (t - '0') << 4;
120       else if ((t >= 'a') && (t <= 'f'))
121         v = (t - 'a' + 10) << 4;
122       else if ((t >= 'A') && (t <= 'F'))
123         v = (t - 'A' + 10) << 4;
124       else
125         return RIJNDAEL_BAD_KEY_MAT;
126
127       t = *keyMat++;
128       if ((t >= '0') && (t <= '9'))
129         v ^= (t - '0');
130       else if ((t >= 'a') && (t <= 'f'))
131         v ^= (t - 'a' + 10);
132       else if ((t >= 'A') && (t <= 'F'))
133         v ^= (t - 'A' + 10);
134       else
135         return RIJNDAEL_BAD_KEY_MAT;
136
137       cipherKey[i] = v;
138     }
139   if (direction == RIJNDAEL_DIR_ENCRYPT)
140     {
141       key->Nr = rijndaelKeySetupEnc (key->rk, cipherKey, keyLen);
142     }
143   else
144     {
145       key->Nr = rijndaelKeySetupDec (key->rk, cipherKey, keyLen);
146     }
147   rijndaelKeySetupEnc (key->ek, cipherKey, keyLen);
148   return 0;
149 }
150
151 rijndael_rc
152 rijndaelCipherInit (rijndaelCipherInstance *cipher, rijndael_mode mode,
153                     const char *IV)
154 {
155   if ((mode == RIJNDAEL_MODE_ECB) || (mode == RIJNDAEL_MODE_CBC)
156       || (mode == RIJNDAEL_MODE_CFB1))
157     {
158       cipher->mode = mode;
159     }
160   else
161     {
162       return RIJNDAEL_BAD_CIPHER_MODE;
163     }
164   if (IV != NULL)
165     {
166       int i;
167       for (i = 0; i < RIJNDAEL_MAX_IV_SIZE; i++)
168         {
169           int t, j;
170
171           t = IV[2 * i];
172           if ((t >= '0') && (t <= '9'))
173             j = (t - '0') << 4;
174           else if ((t >= 'a') && (t <= 'f'))
175             j = (t - 'a' + 10) << 4;
176           else if ((t >= 'A') && (t <= 'F'))
177             j = (t - 'A' + 10) << 4;
178           else
179             return RIJNDAEL_BAD_CIPHER_INSTANCE;
180
181           t = IV[2 * i + 1];
182           if ((t >= '0') && (t <= '9'))
183             j ^= (t - '0');
184           else if ((t >= 'a') && (t <= 'f'))
185             j ^= (t - 'a' + 10);
186           else if ((t >= 'A') && (t <= 'F'))
187             j ^= (t - 'A' + 10);
188           else
189             return RIJNDAEL_BAD_CIPHER_INSTANCE;
190
191           cipher->IV[i] = (uint8_t) j;
192         }
193     }
194   else
195     {
196       memset (cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
197     }
198   return 0;
199 }
200
201 int
202 rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
203                       const rijndaelKeyInstance *key,
204                       const char *input,
205                       size_t inputLen, char *outBuffer)
206 {
207   size_t i, k, t, numBlocks;
208   char block[16], *iv;
209
210   if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
211     {
212       return RIJNDAEL_BAD_CIPHER_STATE;
213     }
214   if (input == NULL || inputLen <= 0)
215     {
216       return 0;                 /* nothing to do */
217     }
218
219   numBlocks = inputLen / 128;
220
221   switch (cipher->mode)
222     {
223     case RIJNDAEL_MODE_ECB:
224       for (i = numBlocks; i > 0; i--)
225         {
226           rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
227           input += 16;
228           outBuffer += 16;
229         }
230       break;
231
232     case RIJNDAEL_MODE_CBC:
233       iv = cipher->IV;
234       for (i = numBlocks; i > 0; i--)
235         {
236           ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
237             ((uint32_t *) iv)[0];
238           ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
239             ((uint32_t *) iv)[1];
240           ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
241             ((uint32_t *) iv)[2];
242           ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
243             ((uint32_t *) iv)[3];
244           rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
245           memcpy (cipher->IV, outBuffer, 16);
246           input += 16;
247           outBuffer += 16;
248         }
249       break;
250
251     case RIJNDAEL_MODE_CFB1:
252       iv = cipher->IV;
253       for (i = numBlocks; i > 0; i--)
254         {
255           memcpy (outBuffer, input, 16);
256           for (k = 0; k < 128; k++)
257             {
258               rijndaelEncrypt (key->ek, key->Nr, iv, block);
259               outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
260               for (t = 0; t < 15; t++)
261                 {
262                   iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
263                 }
264               iv[15] = (iv[15] << 1) |
265                 ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
266             }
267           outBuffer += 16;
268           input += 16;
269         }
270       break;
271
272     default:
273       return RIJNDAEL_BAD_CIPHER_STATE;
274     }
275
276   return 128 * numBlocks;
277 }
278
279 int
280 rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
281                     const rijndaelKeyInstance *key,
282                     const char *input,
283                     size_t inputOctets, char *outBuffer)
284 {
285   size_t i, numBlocks, padLen;
286   char block[16], *iv;
287
288   if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
289     {
290       return RIJNDAEL_BAD_CIPHER_STATE;
291     }
292   if (input == NULL || inputOctets <= 0)
293     {
294       return 0;                 /* nothing to do */
295     }
296
297   numBlocks = inputOctets / 16;
298
299   switch (cipher->mode)
300     {
301     case RIJNDAEL_MODE_ECB:
302       for (i = numBlocks; i > 0; i--)
303         {
304           rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
305           input += 16;
306           outBuffer += 16;
307         }
308       padLen = 16 - (inputOctets - 16 * numBlocks);
309       assert (padLen > 0 && padLen <= 16);
310       memcpy (block, input, 16 - padLen);
311       memset (block + 16 - padLen, padLen, padLen);
312       rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
313       break;
314
315     case RIJNDAEL_MODE_CBC:
316       iv = cipher->IV;
317       for (i = numBlocks; i > 0; i--)
318         {
319           ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
320             ((uint32_t *) iv)[0];
321           ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
322             ((uint32_t *) iv)[1];
323           ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
324             ((uint32_t *) iv)[2];
325           ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
326             ((uint32_t *) iv)[3];
327           rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
328           memcpy (cipher->IV, outBuffer, 16);
329           input += 16;
330           outBuffer += 16;
331         }
332       padLen = 16 - (inputOctets - 16 * numBlocks);
333       assert (padLen > 0 && padLen <= 16);
334       for (i = 0; i < 16 - padLen; i++)
335         {
336           block[i] = input[i] ^ iv[i];
337         }
338       for (i = 16 - padLen; i < 16; i++)
339         {
340           block[i] = (char) padLen ^ iv[i];
341         }
342       rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
343       memcpy (cipher->IV, outBuffer, 16);
344       break;
345
346     default:
347       return RIJNDAEL_BAD_CIPHER_STATE;
348     }
349
350   return 16 * (numBlocks + 1);
351 }
352
353 int
354 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
355                       const rijndaelKeyInstance *key,
356                       const char *input,
357                       size_t inputLen, char *outBuffer)
358 {
359   size_t i, k, t, numBlocks;
360   char block[16], *iv;
361
362   if (cipher == NULL
363       || key == NULL
364       || (cipher->mode != RIJNDAEL_MODE_CFB1
365           && key->direction == RIJNDAEL_DIR_ENCRYPT))
366     {
367       return RIJNDAEL_BAD_CIPHER_STATE;
368     }
369   if (input == NULL || inputLen <= 0)
370     {
371       return 0;                 /* nothing to do */
372     }
373
374   numBlocks = inputLen / 128;
375
376   switch (cipher->mode)
377     {
378     case RIJNDAEL_MODE_ECB:
379       for (i = numBlocks; i > 0; i--)
380         {
381           rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
382           input += 16;
383           outBuffer += 16;
384         }
385       break;
386
387     case RIJNDAEL_MODE_CBC:
388       iv = cipher->IV;
389       for (i = numBlocks; i > 0; i--)
390         {
391           rijndaelDecrypt (key->rk, key->Nr, input, block);
392           ((uint32_t *) block)[0] ^= ((uint32_t *) iv)[0];
393           ((uint32_t *) block)[1] ^= ((uint32_t *) iv)[1];
394           ((uint32_t *) block)[2] ^= ((uint32_t *) iv)[2];
395           ((uint32_t *) block)[3] ^= ((uint32_t *) iv)[3];
396           memcpy (cipher->IV, input, 16);
397           memcpy (outBuffer, block, 16);
398           input += 16;
399           outBuffer += 16;
400         }
401       break;
402
403     case RIJNDAEL_MODE_CFB1:
404       iv = cipher->IV;
405       for (i = numBlocks; i > 0; i--)
406         {
407           memcpy (outBuffer, input, 16);
408           for (k = 0; k < 128; k++)
409             {
410               rijndaelEncrypt (key->ek, key->Nr, iv, block);
411               for (t = 0; t < 15; t++)
412                 {
413                   iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
414                 }
415               iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
416               outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
417             }
418           outBuffer += 16;
419           input += 16;
420         }
421       break;
422
423     default:
424       return RIJNDAEL_BAD_CIPHER_STATE;
425     }
426
427   return 128 * numBlocks;
428 }
429
430 int
431 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
432                     const rijndaelKeyInstance *key,
433                     const char *input,
434                     size_t inputOctets, char *outBuffer)
435 {
436   size_t i, numBlocks, padLen;
437   char block[16];
438
439   if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_ENCRYPT)
440     {
441       return RIJNDAEL_BAD_CIPHER_STATE;
442     }
443   if (input == NULL || inputOctets <= 0)
444     {
445       return 0;                 /* nothing to do */
446     }
447   if (inputOctets % 16 != 0)
448     {
449       return RIJNDAEL_BAD_DATA;
450     }
451
452   numBlocks = inputOctets / 16;
453
454   switch (cipher->mode)
455     {
456     case RIJNDAEL_MODE_ECB:
457       /* all blocks but last */
458       for (i = numBlocks - 1; i > 0; i--)
459         {
460           rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
461           input += 16;
462           outBuffer += 16;
463         }
464       /* last block */
465       rijndaelDecrypt (key->rk, key->Nr, input, block);
466       padLen = block[15];
467       if (padLen >= 16)
468         {
469           return RIJNDAEL_BAD_DATA;
470         }
471       for (i = 16 - padLen; i < 16; i++)
472         {
473           if (block[i] != padLen)
474             {
475               return RIJNDAEL_BAD_DATA;
476             }
477         }
478       memcpy (outBuffer, block, 16 - padLen);
479       break;
480
481     case RIJNDAEL_MODE_CBC:
482       /* all blocks but last */
483       for (i = numBlocks - 1; i > 0; i--)
484         {
485           rijndaelDecrypt (key->rk, key->Nr, input, block);
486           ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
487           ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
488           ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
489           ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
490           memcpy (cipher->IV, input, 16);
491           memcpy (outBuffer, block, 16);
492           input += 16;
493           outBuffer += 16;
494         }
495       /* last block */
496       rijndaelDecrypt (key->rk, key->Nr, input, block);
497       ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
498       ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
499       ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
500       ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
501       padLen = block[15];
502       if (padLen <= 0 || padLen > 16)
503         {
504           return RIJNDAEL_BAD_DATA;
505         }
506       for (i = 16 - padLen; i < 16; i++)
507         {
508           if (block[i] != padLen)
509             {
510               return RIJNDAEL_BAD_DATA;
511             }
512         }
513       memcpy (outBuffer, block, 16 - padLen);
514       break;
515
516     default:
517       return RIJNDAEL_BAD_CIPHER_STATE;
518     }
519
520   return 16 * numBlocks - padLen;
521 }