Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
7643 views
1
/*
2
* FIPS-197 compliant AES implementation
3
*
4
* Copyright (C) 2006-2007 Christophe Devine
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
*
10
* * Redistributions of source code _must_ retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* * Redistributions in binary form may or may not reproduce the above
13
* copyright notice, this list of conditions and the following
14
* disclaimer in the documentation and/or other materials provided
15
* with the distribution.
16
* * Neither the name of XySSL nor the names of its contributors may be
17
* used to endorse or promote products derived from this software
18
* without specific prior written permission.
19
*
20
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
26
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
*/
32
/*
33
* The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
34
*
35
* http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
36
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
37
*/
38
39
#include "mupdf/fitz.h"
40
41
#define aes_context fz_aes
42
43
/* AES block cipher implementation from XYSSL */
44
45
/*
46
* 32-bit integer manipulation macros (little endian)
47
*/
48
#ifndef GET_ULONG_LE
49
#define GET_ULONG_LE(n,b,i) \
50
{ \
51
(n) = ( (unsigned long) (b)[(i)] ) \
52
| ( (unsigned long) (b)[(i) + 1] << 8 ) \
53
| ( (unsigned long) (b)[(i) + 2] << 16 ) \
54
| ( (unsigned long) (b)[(i) + 3] << 24 ); \
55
}
56
#endif
57
58
#ifndef PUT_ULONG_LE
59
#define PUT_ULONG_LE(n,b,i) \
60
{ \
61
(b)[(i) ] = (unsigned char) ( (n) ); \
62
(b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
63
(b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
64
(b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
65
}
66
#endif
67
68
/*
69
* Forward S-box & tables
70
*/
71
static unsigned char FSb[256];
72
static unsigned long FT0[256];
73
static unsigned long FT1[256];
74
static unsigned long FT2[256];
75
static unsigned long FT3[256];
76
77
/*
78
* Reverse S-box & tables
79
*/
80
static unsigned char RSb[256];
81
static unsigned long RT0[256];
82
static unsigned long RT1[256];
83
static unsigned long RT2[256];
84
static unsigned long RT3[256];
85
86
/*
87
* Round constants
88
*/
89
static unsigned long RCON[10];
90
91
/*
92
* Tables generation code
93
*/
94
#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
95
#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
96
#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
97
98
static int aes_init_done = 0;
99
100
static void aes_gen_tables( void )
101
{
102
int i, x, y, z;
103
int pow[256];
104
int log[256];
105
106
/*
107
* compute pow and log tables over GF(2^8)
108
*/
109
for( i = 0, x = 1; i < 256; i++ )
110
{
111
pow[i] = x;
112
log[x] = i;
113
x = ( x ^ XTIME( x ) ) & 0xFF;
114
}
115
116
/*
117
* calculate the round constants
118
*/
119
for( i = 0, x = 1; i < 10; i++ )
120
{
121
RCON[i] = (unsigned long) x;
122
x = XTIME( x ) & 0xFF;
123
}
124
125
/*
126
* generate the forward and reverse S-boxes
127
*/
128
FSb[0x00] = 0x63;
129
RSb[0x63] = 0x00;
130
131
for( i = 1; i < 256; i++ )
132
{
133
x = pow[255 - log[i]];
134
135
y = x; y = ( (y << 1) | (y >> 7) ) & 0xFF;
136
x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
137
x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
138
x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
139
x ^= y ^ 0x63;
140
141
FSb[i] = (unsigned char) x;
142
RSb[x] = (unsigned char) i;
143
}
144
145
/*
146
* generate the forward and reverse tables
147
*/
148
for( i = 0; i < 256; i++ )
149
{
150
x = FSb[i];
151
y = XTIME( x ) & 0xFF;
152
z = ( y ^ x ) & 0xFF;
153
154
FT0[i] = ( (unsigned long) y ) ^
155
( (unsigned long) x << 8 ) ^
156
( (unsigned long) x << 16 ) ^
157
( (unsigned long) z << 24 );
158
159
FT1[i] = ROTL8( FT0[i] );
160
FT2[i] = ROTL8( FT1[i] );
161
FT3[i] = ROTL8( FT2[i] );
162
163
x = RSb[i];
164
165
RT0[i] = ( (unsigned long) MUL( 0x0E, x ) ) ^
166
( (unsigned long) MUL( 0x09, x ) << 8 ) ^
167
( (unsigned long) MUL( 0x0D, x ) << 16 ) ^
168
( (unsigned long) MUL( 0x0B, x ) << 24 );
169
170
RT1[i] = ROTL8( RT0[i] );
171
RT2[i] = ROTL8( RT1[i] );
172
RT3[i] = ROTL8( RT2[i] );
173
}
174
}
175
176
/*
177
* AES key schedule (encryption)
178
*/
179
int aes_setkey_enc( aes_context *ctx, const unsigned char *key, int keysize )
180
{
181
int i;
182
unsigned long *RK;
183
184
#if !defined(XYSSL_AES_ROM_TABLES)
185
if( aes_init_done == 0 )
186
{
187
aes_gen_tables();
188
aes_init_done = 1;
189
}
190
#endif
191
192
switch( keysize )
193
{
194
case 128: ctx->nr = 10; break;
195
case 192: ctx->nr = 12; break;
196
case 256: ctx->nr = 14; break;
197
default : return 1;
198
}
199
200
#if defined(PADLOCK_ALIGN16)
201
ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
202
#else
203
ctx->rk = RK = ctx->buf;
204
#endif
205
206
for( i = 0; i < (keysize >> 5); i++ )
207
{
208
GET_ULONG_LE( RK[i], key, i << 2 );
209
}
210
211
switch( ctx->nr )
212
{
213
case 10:
214
215
for( i = 0; i < 10; i++, RK += 4 )
216
{
217
RK[4] = RK[0] ^ RCON[i] ^
218
( FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
219
( FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
220
( FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
221
( FSb[ ( RK[3] ) & 0xFF ] << 24 );
222
223
RK[5] = RK[1] ^ RK[4];
224
RK[6] = RK[2] ^ RK[5];
225
RK[7] = RK[3] ^ RK[6];
226
}
227
break;
228
229
case 12:
230
231
for( i = 0; i < 8; i++, RK += 6 )
232
{
233
RK[6] = RK[0] ^ RCON[i] ^
234
( FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
235
( FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
236
( FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
237
( FSb[ ( RK[5] ) & 0xFF ] << 24 );
238
239
RK[7] = RK[1] ^ RK[6];
240
RK[8] = RK[2] ^ RK[7];
241
RK[9] = RK[3] ^ RK[8];
242
RK[10] = RK[4] ^ RK[9];
243
RK[11] = RK[5] ^ RK[10];
244
}
245
break;
246
247
case 14:
248
249
for( i = 0; i < 7; i++, RK += 8 )
250
{
251
RK[8] = RK[0] ^ RCON[i] ^
252
( FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
253
( FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
254
( FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
255
( FSb[ ( RK[7] ) & 0xFF ] << 24 );
256
257
RK[9] = RK[1] ^ RK[8];
258
RK[10] = RK[2] ^ RK[9];
259
RK[11] = RK[3] ^ RK[10];
260
261
RK[12] = RK[4] ^
262
( FSb[ ( RK[11] ) & 0xFF ] ) ^
263
( FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
264
( FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
265
( FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
266
267
RK[13] = RK[5] ^ RK[12];
268
RK[14] = RK[6] ^ RK[13];
269
RK[15] = RK[7] ^ RK[14];
270
}
271
break;
272
273
default:
274
275
break;
276
}
277
return 0;
278
}
279
280
/*
281
* AES key schedule (decryption)
282
*/
283
int aes_setkey_dec(aes_context *ctx, const unsigned char *key, int keysize)
284
{
285
int i, j;
286
aes_context cty;
287
unsigned long *RK;
288
unsigned long *SK;
289
290
switch( keysize )
291
{
292
case 128: ctx->nr = 10; break;
293
case 192: ctx->nr = 12; break;
294
case 256: ctx->nr = 14; break;
295
default: return 1;
296
}
297
298
#if defined(PADLOCK_ALIGN16)
299
ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
300
#else
301
ctx->rk = RK = ctx->buf;
302
#endif
303
304
i = aes_setkey_enc( &cty, key, keysize );
305
if (i)
306
return i;
307
SK = cty.rk + cty.nr * 4;
308
309
*RK++ = *SK++;
310
*RK++ = *SK++;
311
*RK++ = *SK++;
312
*RK++ = *SK++;
313
314
for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
315
{
316
for( j = 0; j < 4; j++, SK++ )
317
{
318
*RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
319
RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
320
RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
321
RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
322
}
323
}
324
325
*RK++ = *SK++;
326
*RK++ = *SK++;
327
*RK++ = *SK++;
328
*RK = *SK;
329
330
memset( &cty, 0, sizeof( aes_context ) );
331
return 0;
332
}
333
334
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
335
{ \
336
X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \
337
FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
338
FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
339
FT3[ ( Y3 >> 24 ) & 0xFF ]; \
340
\
341
X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \
342
FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
343
FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
344
FT3[ ( Y0 >> 24 ) & 0xFF ]; \
345
\
346
X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \
347
FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
348
FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
349
FT3[ ( Y1 >> 24 ) & 0xFF ]; \
350
\
351
X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \
352
FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
353
FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
354
FT3[ ( Y2 >> 24 ) & 0xFF ]; \
355
}
356
357
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
358
{ \
359
X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \
360
RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
361
RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
362
RT3[ ( Y1 >> 24 ) & 0xFF ]; \
363
\
364
X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \
365
RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
366
RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
367
RT3[ ( Y2 >> 24 ) & 0xFF ]; \
368
\
369
X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \
370
RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
371
RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
372
RT3[ ( Y3 >> 24 ) & 0xFF ]; \
373
\
374
X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \
375
RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
376
RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
377
RT3[ ( Y0 >> 24 ) & 0xFF ]; \
378
}
379
380
/*
381
* AES-ECB block encryption/decryption
382
*/
383
void aes_crypt_ecb( aes_context *ctx,
384
int mode,
385
const unsigned char input[16],
386
unsigned char output[16] )
387
{
388
int i;
389
unsigned long *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
390
391
#if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
392
if( padlock_supports( PADLOCK_ACE ) )
393
{
394
if( padlock_xcryptecb( ctx, mode, input, output ) == 0 )
395
return;
396
}
397
#endif
398
399
RK = ctx->rk;
400
401
GET_ULONG_LE( X0, input, 0 ); X0 ^= *RK++;
402
GET_ULONG_LE( X1, input, 4 ); X1 ^= *RK++;
403
GET_ULONG_LE( X2, input, 8 ); X2 ^= *RK++;
404
GET_ULONG_LE( X3, input, 12 ); X3 ^= *RK++;
405
406
if( mode == AES_DECRYPT )
407
{
408
for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
409
{
410
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
411
AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
412
}
413
414
AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
415
416
X0 = *RK++ ^ ( RSb[ ( Y0 ) & 0xFF ] ) ^
417
( RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
418
( RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
419
( RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
420
421
X1 = *RK++ ^ ( RSb[ ( Y1 ) & 0xFF ] ) ^
422
( RSb[ ( Y0 >>8 ) & 0xFF ] << 8 ) ^
423
( RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
424
( RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
425
426
X2 = *RK++ ^ ( RSb[ ( Y2 ) & 0xFF ] ) ^
427
( RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
428
( RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
429
( RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
430
431
X3 = *RK ^ ( RSb[ ( Y3 ) & 0xFF ] ) ^
432
( RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
433
( RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
434
( RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
435
}
436
else /* AES_ENCRYPT */
437
{
438
for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
439
{
440
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
441
AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
442
}
443
444
AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
445
446
X0 = *RK++ ^ ( FSb[ ( Y0 ) & 0xFF ] ) ^
447
( FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
448
( FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
449
( FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
450
451
X1 = *RK++ ^ ( FSb[ ( Y1 ) & 0xFF ] ) ^
452
( FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
453
( FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
454
( FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
455
456
X2 = *RK++ ^ ( FSb[ ( Y2 ) & 0xFF ] ) ^
457
( FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
458
( FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
459
( FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
460
461
X3 = *RK ^ ( FSb[ ( Y3 ) & 0xFF ] ) ^
462
( FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
463
( FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
464
( FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
465
}
466
467
PUT_ULONG_LE( X0, output, 0 );
468
PUT_ULONG_LE( X1, output, 4 );
469
PUT_ULONG_LE( X2, output, 8 );
470
PUT_ULONG_LE( X3, output, 12 );
471
}
472
473
/*
474
* AES-CBC buffer encryption/decryption
475
*/
476
void aes_crypt_cbc( aes_context *ctx,
477
int mode,
478
int length,
479
unsigned char iv[16],
480
const unsigned char *input,
481
unsigned char *output )
482
{
483
int i;
484
unsigned char temp[16];
485
486
#if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
487
if( padlock_supports( PADLOCK_ACE ) )
488
{
489
if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
490
return;
491
}
492
#endif
493
494
if( mode == AES_DECRYPT )
495
{
496
while( length > 0 )
497
{
498
memcpy( temp, input, 16 );
499
aes_crypt_ecb( ctx, mode, input, output );
500
501
for( i = 0; i < 16; i++ )
502
output[i] = (unsigned char)( output[i] ^ iv[i] );
503
504
memcpy( iv, temp, 16 );
505
506
input += 16;
507
output += 16;
508
length -= 16;
509
}
510
}
511
else
512
{
513
while( length > 0 )
514
{
515
for( i = 0; i < 16; i++ )
516
output[i] = (unsigned char)( input[i] ^ iv[i] );
517
518
aes_crypt_ecb( ctx, mode, output, output );
519
memcpy( iv, output, 16 );
520
521
input += 16;
522
output += 16;
523
length -= 16;
524
}
525
}
526
}
527
528
/*
529
* AES-CFB buffer encryption/decryption
530
*/
531
void aes_crypt_cfb( aes_context *ctx,
532
int mode,
533
int length,
534
int *iv_off,
535
unsigned char iv[16],
536
const unsigned char *input,
537
unsigned char *output )
538
{
539
int c, n = *iv_off;
540
541
if( mode == AES_DECRYPT )
542
{
543
while( length-- )
544
{
545
if( n == 0 )
546
aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
547
548
c = *input++;
549
*output++ = (unsigned char)( c ^ iv[n] );
550
iv[n] = (unsigned char) c;
551
552
n = (n + 1) & 0x0F;
553
}
554
}
555
else
556
{
557
while( length-- )
558
{
559
if( n == 0 )
560
aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
561
562
iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
563
564
n = (n + 1) & 0x0F;
565
}
566
}
567
568
*iv_off = n;
569
}
570
571