root/common/trunk/src/rijndael-api-fst.c @ 3922

Revision 3922, 11.4 KB (checked in by ucacsva, 7 years ago)

1. Removed some tagged comments from previous commits (//SV-XXX).
2. Added newer config.[sub/guess]
3. Various fixes to sync common library with that of ANL:

  • Replaced some "dnl" comments with "#" and stripped off some dnl's from the end of lines
  • Require autoconf v2.5 with AC_PREREQ(2.5)
  • Replaced LIBOBJS="$LIBOBJS inet_ntop.o" by AC_LIBOBJ([inet_ntop])
  • Find which network interface is in use (WinXP).
  • Forgotten NDEF replaced by HAVE_MSGHDR_MSGCTRL.
  • Sets event.data to s->last.active (used by AccessGrid?'s logging code).
  • Introduced rtp_get_ssrc_count() (AccessGrid? logging code).


  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/**
2 * rijndael-api-fst.c
3 *
4 * @version 2.9 (December 2000)
5 *
6 * Optimised ANSI C code for the Rijndael cipher (now AES)
7 *
8 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
9 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
10 * @author Paulo Barreto <paulo.barreto@terra.com.br>
11 *
12 * This code is hereby placed in the public domain.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
21 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * Acknowledgements:
27 *
28 * We are deeply indebted to the following people for their bug reports,
29 * fixes, and improvement suggestions to this implementation. Though we
30 * tried to list all contributions, we apologise in advance for any
31 * missing reference.
32 *
33 * Andrew Bales <Andrew.Bales@Honeywell.com>
34 * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
35 * John Skodon <skodonj@webquill.com>
36 */
37
38#include "config_unix.h"
39#include "config_win32.h"
40#include "debug.h"
41#include "rijndael-api-fst.h"
42#include "rijndael-alg-fst.h"
43
44int makeKey(keyInstance *key, BYTE direction, int keyLen, BYTE *keyMaterial) {
45        int i;
46        char *keyMat;
47        u8 cipherKey[MAXKB];
48       
49        if (key == NULL) {
50                return BAD_KEY_INSTANCE;
51        }
52
53        if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
54                key->direction = direction;
55        } else {
56                return BAD_KEY_DIR;
57        }
58
59        if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
60                key->keyLen = keyLen;
61        } else {
62                return BAD_KEY_MAT;
63        }
64
65        if (keyMaterial != NULL) {
66                strncpy(key->keyMaterial, (char *)keyMaterial, keyLen/4);
67        }
68
69        /* initialize key schedule: */
70        keyMat = key->keyMaterial;
71        for (i = 0; i < key->keyLen/8; i++) {
72                int t, v;
73
74                t = *keyMat++;
75                if ((t >= '0') && (t <= '9')) v = (t - '0') << 4;
76                else if ((t >= 'a') && (t <= 'f')) v = (t - 'a' + 10) << 4;
77                else if ((t >= 'A') && (t <= 'F')) v = (t - 'A' + 10) << 4;
78                else return BAD_KEY_MAT;
79               
80                t = *keyMat++;
81                if ((t >= '0') && (t <= '9')) v ^= (t - '0');
82                else if ((t >= 'a') && (t <= 'f')) v ^= (t - 'a' + 10);
83                else if ((t >= 'A') && (t <= 'F')) v ^= (t - 'A' + 10);
84                else return BAD_KEY_MAT;
85               
86                cipherKey[i] = (u8)v;
87        }
88        if (direction == DIR_ENCRYPT) {
89                key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
90        } else {
91                key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
92        }
93        rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
94        return TRUE;
95}
96
97int cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
98        if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
99                cipher->mode = mode;
100        } else {
101                return BAD_CIPHER_MODE;
102        }
103        if (IV != NULL) {
104                int i;
105                for (i = 0; i < MAX_IV_SIZE; i++) {
106                        int t, j;
107
108                        t = IV[2*i];
109                        if ((t >= '0') && (t <= '9')) j = (t - '0') << 4;
110                        else if ((t >= 'a') && (t <= 'f')) j = (t - 'a' + 10) << 4;
111                        else if ((t >= 'A') && (t <= 'F')) j = (t - 'A' + 10) << 4;
112                        else return BAD_CIPHER_INSTANCE;
113               
114                        t = IV[2*i+1];
115                        if ((t >= '0') && (t <= '9')) j ^= (t - '0');
116                        else if ((t >= 'a') && (t <= 'f')) j ^= (t - 'a' + 10);
117                        else if ((t >= 'A') && (t <= 'F')) j ^= (t - 'A' + 10);
118                        else return BAD_CIPHER_INSTANCE;
119                       
120                        cipher->IV[i] = (u8)j;
121                }
122        } else {
123                memset(cipher->IV, 0, MAX_IV_SIZE);
124        }
125        return TRUE;
126}
127
128int blockEncrypt(cipherInstance *cipher, keyInstance *key,
129                BYTE *input, int inputLen, BYTE *outBuffer) {
130        int i, k, t, numBlocks;
131        u8 block[16], *iv;
132
133        if (cipher == NULL ||
134                key == NULL ||
135                key->direction == DIR_DECRYPT) {
136                return BAD_CIPHER_STATE;
137        }
138        if (input == NULL || inputLen <= 0) {
139                return 0; /* nothing to do */
140        }
141
142        numBlocks = inputLen/128;
143       
144        switch (cipher->mode) {
145        case MODE_ECB:
146                for (i = numBlocks; i > 0; i--) {
147                        rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
148                        input += 16;
149                        outBuffer += 16;
150                }
151                break;
152               
153        case MODE_CBC:
154                iv = cipher->IV;
155                for (i = numBlocks; i > 0; i--) {
156                        ((u32*)block)[0] = ((u32*)input)[0] ^ ((u32*)iv)[0];
157                        ((u32*)block)[1] = ((u32*)input)[1] ^ ((u32*)iv)[1];
158                        ((u32*)block)[2] = ((u32*)input)[2] ^ ((u32*)iv)[2];
159                        ((u32*)block)[3] = ((u32*)input)[3] ^ ((u32*)iv)[3];
160                        rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
161                        iv = outBuffer;
162                        input += 16;
163                        outBuffer += 16;
164                }
165                break;
166
167    case MODE_CFB1:
168                iv = cipher->IV;
169        for (i = numBlocks; i > 0; i--) {
170                        memcpy(outBuffer, input, 16);
171            for (k = 0; k < 128; k++) {
172                                rijndaelEncrypt(key->ek, key->Nr, iv, block);
173                outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
174                for (t = 0; t < 15; t++) {
175                        iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
176                }
177                iv[15] = (iv[15] << 1) | ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
178            }
179            outBuffer += 16;
180            input += 16;
181        }
182        break;
183
184        default:
185                return BAD_CIPHER_STATE;
186        }
187       
188        return 128*numBlocks;
189}
190
191/**
192 * Encrypt data partitioned in octets, using RFC 2040-like padding.
193 *
194 * @param   input           data to be encrypted (octet sequence)
195 * @param   inputOctets         input length in octets (not bits)
196 * @param   outBuffer       encrypted output data
197 *
198 * @return      length in octets (not bits) of the encrypted output buffer.
199 */
200int padEncrypt(cipherInstance *cipher, keyInstance *key,
201                BYTE *input, int inputOctets, BYTE *outBuffer) {
202        int i, numBlocks, padLen;
203        u8 block[16], *iv;
204
205        if (cipher == NULL ||
206                key == NULL ||
207                key->direction == DIR_DECRYPT) {
208                return BAD_CIPHER_STATE;
209        }
210        if (input == NULL || inputOctets <= 0) {
211                return 0; /* nothing to do */
212        }
213
214        numBlocks = inputOctets/16;
215
216        switch (cipher->mode) {
217        case MODE_ECB:
218                for (i = numBlocks; i > 0; i--) {
219                        rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
220                        input += 16;
221                        outBuffer += 16;
222                }
223                padLen = 16 - (inputOctets - 16*numBlocks);
224                assert(padLen > 0 && padLen <= 16);
225                memcpy(block, input, 16 - padLen);
226                memset(block + 16 - padLen, padLen, padLen);
227                rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
228                break;
229
230        case MODE_CBC:
231                iv = cipher->IV;
232                for (i = numBlocks; i > 0; i--) {
233                        ((u32*)block)[0] = ((u32*)input)[0] ^ ((u32*)iv)[0];
234                        ((u32*)block)[1] = ((u32*)input)[1] ^ ((u32*)iv)[1];
235                        ((u32*)block)[2] = ((u32*)input)[2] ^ ((u32*)iv)[2];
236                        ((u32*)block)[3] = ((u32*)input)[3] ^ ((u32*)iv)[3];
237                        rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
238                        iv = outBuffer;
239                        input += 16;
240                        outBuffer += 16;
241                }
242                padLen = 16 - (inputOctets - 16*numBlocks);
243                assert(padLen > 0 && padLen <= 16);
244                for (i = 0; i < 16 - padLen; i++) {
245                        block[i] = input[i] ^ iv[i];
246                }
247                for (i = 16 - padLen; i < 16; i++) {
248                        block[i] = (BYTE)padLen ^ iv[i];
249                }
250                rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
251                break;
252
253        default:
254                return BAD_CIPHER_STATE;
255        }
256
257        return 16*(numBlocks + 1);
258}
259
260int blockDecrypt(cipherInstance *cipher, keyInstance *key,
261                BYTE *input, int inputLen, BYTE *outBuffer) {
262        int i, k, t, numBlocks;
263        u8 block[16], *iv;
264
265        if (cipher == NULL ||
266                key == NULL ||
267                (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
268                return BAD_CIPHER_STATE;
269        }
270        if (input == NULL || inputLen <= 0) {
271                return 0; /* nothing to do */
272        }
273
274        numBlocks = inputLen/128;
275
276        switch (cipher->mode) {
277        case MODE_ECB:
278                for (i = numBlocks; i > 0; i--) {
279                        rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
280                        input += 16;
281                        outBuffer += 16;
282                }
283                break;
284               
285        case MODE_CBC:
286                iv = cipher->IV;
287                for (i = numBlocks; i > 0; i--) {
288                        rijndaelDecrypt(key->rk, key->Nr, input, block);
289                        ((u32*)block)[0] ^= ((u32*)iv)[0];
290                        ((u32*)block)[1] ^= ((u32*)iv)[1];
291                        ((u32*)block)[2] ^= ((u32*)iv)[2];
292                        ((u32*)block)[3] ^= ((u32*)iv)[3];
293                        memcpy(cipher->IV, input, 16);
294                        memcpy(outBuffer, block, 16);
295                        input += 16;
296                        outBuffer += 16;
297                }
298                break;
299
300    case MODE_CFB1:
301                iv = cipher->IV;
302        for (i = numBlocks; i > 0; i--) {
303                        memcpy(outBuffer, input, 16);
304            for (k = 0; k < 128; k++) {
305                                rijndaelEncrypt(key->ek, key->Nr, iv, block);
306                for (t = 0; t < 15; t++) {
307                        iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
308                }
309                iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
310                outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
311            }
312            outBuffer += 16;
313            input += 16;
314        }
315        break;
316
317        default:
318                return BAD_CIPHER_STATE;
319        }
320       
321        return 128*numBlocks;
322}
323
324int padDecrypt(cipherInstance *cipher, keyInstance *key,
325                BYTE *input, int inputOctets, BYTE *outBuffer) {
326        int i, numBlocks, padLen;
327        u8 block[16];
328
329        if (cipher == NULL ||
330                key == NULL ||
331                key->direction == DIR_ENCRYPT) {
332                return BAD_CIPHER_STATE;
333        }
334        if (input == NULL || inputOctets <= 0) {
335                return 0; /* nothing to do */
336        }
337        if (inputOctets % 16 != 0) {
338                return BAD_DATA;
339        }
340
341        numBlocks = inputOctets/16;
342
343        switch (cipher->mode) {
344        case MODE_ECB:
345                /* all blocks but last */
346                for (i = numBlocks - 1; i > 0; i--) {
347                        rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
348                        input += 16;
349                        outBuffer += 16;
350                }
351                /* last block */
352                rijndaelDecrypt(key->rk, key->Nr, input, block);
353                padLen = block[15];
354                if (padLen >= 16) {
355                        return BAD_DATA;
356                }
357                for (i = 16 - padLen; i < 16; i++) {
358                        if (block[i] != padLen) {
359                                return BAD_DATA;
360                        }
361                }
362                memcpy(outBuffer, block, 16 - padLen);
363                break;
364               
365        case MODE_CBC:
366                /* all blocks but last */
367                for (i = numBlocks - 1; i > 0; i--) {
368                        rijndaelDecrypt(key->rk, key->Nr, input, block);
369                        ((u32*)block)[0] ^= ((u32*)cipher->IV)[0];
370                        ((u32*)block)[1] ^= ((u32*)cipher->IV)[1];
371                        ((u32*)block)[2] ^= ((u32*)cipher->IV)[2];
372                        ((u32*)block)[3] ^= ((u32*)cipher->IV)[3];
373                        memcpy(cipher->IV, input, 16);
374                        memcpy(outBuffer, block, 16);
375                        input += 16;
376                        outBuffer += 16;
377                }
378                /* last block */
379                rijndaelDecrypt(key->rk, key->Nr, input, block);
380                ((u32*)block)[0] ^= ((u32*)cipher->IV)[0];
381                ((u32*)block)[1] ^= ((u32*)cipher->IV)[1];
382                ((u32*)block)[2] ^= ((u32*)cipher->IV)[2];
383                ((u32*)block)[3] ^= ((u32*)cipher->IV)[3];
384                padLen = block[15];
385                if (padLen <= 0 || padLen > 16) {
386                        return BAD_DATA;
387                }
388                for (i = 16 - padLen; i < 16; i++) {
389                        if (block[i] != padLen) {
390                                return BAD_DATA;
391                        }
392                }
393                memcpy(outBuffer, block, 16 - padLen);
394                break;
395       
396        default:
397                return BAD_CIPHER_STATE;
398        }
399       
400        return 16*numBlocks - padLen;
401}
402
403/**
404 *      cipherUpdateRounds:
405 *
406 *      Encrypts/Decrypts exactly one full block a specified number of rounds.
407 *      Only used in the Intermediate Value Known Answer Test. 
408 *
409 *      Returns:
410 *              TRUE - on success
411 *              BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized)
412 */
413int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key,
414                BYTE *input, int inputLen, BYTE *outBuffer, int rounds) {
415        u8 block[16];
416
417        UNUSED(inputLen);
418
419        if (cipher == NULL || key == NULL) {
420                return BAD_CIPHER_STATE;
421        }
422
423        memcpy(block, input, 16);
424
425        switch (key->direction) {
426        case DIR_ENCRYPT:
427                rijndaelEncryptRound(key->rk, key->Nr, block, rounds);
428                break;
429               
430        case DIR_DECRYPT:
431                rijndaelDecryptRound(key->rk, key->Nr, block, rounds);
432                break;
433               
434        default:
435                return BAD_KEY_DIR;
436        }
437
438        memcpy(outBuffer, block, 16);
439       
440        return TRUE;
441}
Note: See TracBrowser for help on using the browser.