Coverage Report

Created: 2024-05-20 06:23

/src/mupdf/source/fitz/crypt-aes.c
Line
Count
Source (jump to first uncovered line)
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
#include <string.h>
42
43
4.18k
#define aes_context fz_aes
44
45
/* AES block cipher implementation from XYSSL */
46
47
/* To prevent coverity being confused by sign extensions from shifts, we
48
 * have replaced "unsigned long" by "uint32_t". To match styles, we have
49
 * similarly replaced "unsigned char" by uint8_t. */
50
51
52
/*
53
 * 32-bit integer manipulation macros (little endian)
54
 */
55
#ifndef GET_ULONG_LE
56
37.3M
#define GET_ULONG_LE(n,b,i)         \
57
37.3M
{               \
58
37.3M
  (n) = ( (uint32_t) (b)[(i)] )     \
59
37.3M
    | ( (uint32_t) (b)[(i) + 1] << 8 )    \
60
37.3M
    | ( (uint32_t) (b)[(i) + 2] << 16 ) \
61
37.3M
    | ( (uint32_t) (b)[(i) + 3] << 24 );  \
62
37.3M
}
63
#endif
64
65
#ifndef PUT_ULONG_LE
66
37.1M
#define PUT_ULONG_LE(n,b,i)       \
67
37.1M
{             \
68
37.1M
  (b)[(i) ] = (uint8_t) ( (n) );    \
69
37.1M
  (b)[(i) + 1] = (uint8_t) ( (n) >> 8 );  \
70
37.1M
  (b)[(i) + 2] = (uint8_t) ( (n) >> 16 ); \
71
37.1M
  (b)[(i) + 3] = (uint8_t) ( (n) >> 24 ); \
72
37.1M
}
73
#endif
74
75
/*
76
 * Forward S-box & tables
77
 */
78
static uint8_t FSb[256];
79
static uint32_t FT0[256];
80
static uint32_t FT1[256];
81
static uint32_t FT2[256];
82
static uint32_t FT3[256];
83
84
/*
85
 * Reverse S-box & tables
86
 */
87
static uint8_t RSb[256];
88
static uint32_t RT0[256];
89
static uint32_t RT1[256];
90
static uint32_t RT2[256];
91
static uint32_t RT3[256];
92
93
/*
94
 * Round constants
95
 */
96
static uint32_t RCON[10];
97
98
/*
99
 * Tables generation code
100
 */
101
1.53k
#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
102
522
#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
103
1.02k
#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
104
105
static int aes_init_done = 0;
106
107
static void aes_gen_tables( void )
108
1
{
109
1
  int i, x, y, z;
110
1
  int pow[256];
111
1
  int log[256];
112
113
  /*
114
   * compute pow and log tables over GF(2^8)
115
   */
116
257
  for( i = 0, x = 1; i < 256; i++ )
117
256
  {
118
256
    pow[i] = x;
119
256
    log[x] = i;
120
256
    x = ( x ^ XTIME( x ) ) & 0xFF;
121
256
  }
122
123
  /*
124
   * calculate the round constants
125
   */
126
11
  for( i = 0, x = 1; i < 10; i++ )
127
10
  {
128
10
    RCON[i] = (uint32_t) x;
129
10
    x = XTIME( x ) & 0xFF;
130
10
  }
131
132
  /*
133
   * generate the forward and reverse S-boxes
134
   */
135
1
  FSb[0x00] = 0x63;
136
1
  RSb[0x63] = 0x00;
137
138
256
  for( i = 1; i < 256; i++ )
139
255
  {
140
255
    x = pow[255 - log[i]];
141
142
255
    y = x; y = ( (y << 1) | (y >> 7) ) & 0xFF;
143
255
    x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
144
255
    x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
145
255
    x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
146
255
    x ^= y ^ 0x63;
147
148
255
    FSb[i] = (uint8_t) x;
149
255
    RSb[x] = (uint8_t) i;
150
255
  }
151
152
  /*
153
   * generate the forward and reverse tables
154
   */
155
257
  for( i = 0; i < 256; i++ )
156
256
  {
157
256
    x = FSb[i];
158
256
    y = XTIME( x ) & 0xFF;
159
256
    z = ( y ^ x ) & 0xFF;
160
161
256
    FT0[i] = ( (uint32_t) y ) ^
162
256
      ( (uint32_t) x << 8 ) ^
163
256
      ( (uint32_t) x << 16 ) ^
164
256
      ( (uint32_t) z << 24 );
165
166
256
    FT1[i] = ROTL8( FT0[i] );
167
256
    FT2[i] = ROTL8( FT1[i] );
168
256
    FT3[i] = ROTL8( FT2[i] );
169
170
256
    x = RSb[i];
171
172
256
    RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
173
256
      ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
174
256
      ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
175
256
      ( (uint32_t) MUL( 0x0B, x ) << 24 );
176
177
256
    RT1[i] = ROTL8( RT0[i] );
178
256
    RT2[i] = ROTL8( RT1[i] );
179
256
    RT3[i] = ROTL8( RT2[i] );
180
256
  }
181
1
}
182
183
/*
184
 * AES key schedule (encryption)
185
 */
186
int fz_aes_setkey_enc( aes_context *ctx, const uint8_t *key, int keysize )
187
36.8k
{
188
36.8k
  int i;
189
36.8k
  uint32_t *RK;
190
191
36.8k
#if !defined(XYSSL_AES_ROM_TABLES)
192
36.8k
  if( aes_init_done == 0 )
193
1
  {
194
1
    aes_gen_tables();
195
1
    aes_init_done = 1;
196
1
  }
197
36.8k
#endif
198
199
36.8k
  switch( keysize )
200
36.8k
  {
201
36.3k
  case 128: ctx->nr = 10; break;
202
0
  case 192: ctx->nr = 12; break;
203
589
  case 256: ctx->nr = 14; break;
204
0
  default : return 1;
205
36.8k
  }
206
207
#if defined(PADLOCK_ALIGN16)
208
  ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
209
#else
210
36.8k
  ctx->rk = RK = ctx->buf;
211
36.8k
#endif
212
213
186k
  for( i = 0; i < (keysize >> 5); i++ )
214
149k
  {
215
149k
    GET_ULONG_LE( RK[i], key, i << 2 );
216
149k
  }
217
218
36.8k
  switch( ctx->nr )
219
36.8k
  {
220
36.3k
  case 10:
221
222
399k
    for( i = 0; i < 10; i++, RK += 4 )
223
363k
    {
224
363k
      RK[4] = RK[0] ^ RCON[i] ^
225
363k
        ( FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
226
363k
        ( FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
227
363k
        ( FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
228
363k
        ( FSb[ ( RK[3] ) & 0xFF ] << 24 );
229
230
363k
      RK[5] = RK[1] ^ RK[4];
231
363k
      RK[6] = RK[2] ^ RK[5];
232
363k
      RK[7] = RK[3] ^ RK[6];
233
363k
    }
234
36.3k
    break;
235
236
0
  case 12:
237
238
0
    for( i = 0; i < 8; i++, RK += 6 )
239
0
    {
240
0
      RK[6] = RK[0] ^ RCON[i] ^
241
0
        ( FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
242
0
        ( FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
243
0
        ( FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
244
0
        ( FSb[ ( RK[5] ) & 0xFF ] << 24 );
245
246
0
      RK[7] = RK[1] ^ RK[6];
247
0
      RK[8] = RK[2] ^ RK[7];
248
0
      RK[9] = RK[3] ^ RK[8];
249
0
      RK[10] = RK[4] ^ RK[9];
250
0
      RK[11] = RK[5] ^ RK[10];
251
0
    }
252
0
    break;
253
254
589
  case 14:
255
256
4.71k
    for( i = 0; i < 7; i++, RK += 8 )
257
4.12k
    {
258
4.12k
      RK[8] = RK[0] ^ RCON[i] ^
259
4.12k
        ( FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
260
4.12k
        ( FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
261
4.12k
        ( FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
262
4.12k
        ( FSb[ ( RK[7] ) & 0xFF ] << 24 );
263
264
4.12k
      RK[9] = RK[1] ^ RK[8];
265
4.12k
      RK[10] = RK[2] ^ RK[9];
266
4.12k
      RK[11] = RK[3] ^ RK[10];
267
268
4.12k
      RK[12] = RK[4] ^
269
4.12k
        ( FSb[ ( RK[11] ) & 0xFF ] ) ^
270
4.12k
        ( FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
271
4.12k
        ( FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
272
4.12k
        ( FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
273
274
4.12k
      RK[13] = RK[5] ^ RK[12];
275
4.12k
      RK[14] = RK[6] ^ RK[13];
276
4.12k
      RK[15] = RK[7] ^ RK[14];
277
4.12k
    }
278
589
    break;
279
280
0
  default:
281
282
0
    break;
283
36.8k
  }
284
36.8k
  return 0;
285
36.8k
}
286
287
/*
288
 * AES key schedule (decryption)
289
 */
290
int fz_aes_setkey_dec(aes_context *ctx, const uint8_t *key, int keysize)
291
4.18k
{
292
4.18k
  int i, j;
293
4.18k
  aes_context cty;
294
4.18k
  uint32_t *RK;
295
4.18k
  uint32_t *SK;
296
297
4.18k
  switch( keysize )
298
4.18k
  {
299
3.59k
  case 128: ctx->nr = 10; break;
300
0
  case 192: ctx->nr = 12; break;
301
589
  case 256: ctx->nr = 14; break;
302
3
  default: return 1;
303
4.18k
  }
304
305
#if defined(PADLOCK_ALIGN16)
306
  ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
307
#else
308
4.18k
  ctx->rk = RK = ctx->buf;
309
4.18k
#endif
310
311
4.18k
  i = fz_aes_setkey_enc( &cty, key, keysize );
312
4.18k
  if (i)
313
0
    return i;
314
4.18k
  SK = cty.rk + cty.nr * 4;
315
316
4.18k
  *RK++ = *SK++;
317
4.18k
  *RK++ = *SK++;
318
4.18k
  *RK++ = *SK++;
319
4.18k
  *RK++ = *SK++;
320
321
44.1k
  for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
322
39.9k
  {
323
199k
    for( j = 0; j < 4; j++, SK++ )
324
159k
    {
325
159k
      *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
326
159k
        RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
327
159k
        RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
328
159k
        RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
329
159k
    }
330
39.9k
  }
331
332
4.18k
  *RK++ = *SK++;
333
4.18k
  *RK++ = *SK++;
334
4.18k
  *RK++ = *SK++;
335
4.18k
  *RK = *SK;
336
337
4.18k
  memset( &cty, 0, sizeof( aes_context ) );
338
4.18k
  return 0;
339
4.18k
}
340
341
79.8M
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
342
79.8M
{           \
343
79.8M
  X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \
344
79.8M
    FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
345
79.8M
    FT2[ ( Y2 >> 16 ) & 0xFF ] ^  \
346
79.8M
    FT3[ ( Y3 >> 24 ) & 0xFF ]; \
347
79.8M
            \
348
79.8M
  X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \
349
79.8M
    FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
350
79.8M
    FT2[ ( Y3 >> 16 ) & 0xFF ] ^  \
351
79.8M
    FT3[ ( Y0 >> 24 ) & 0xFF ]; \
352
79.8M
            \
353
79.8M
  X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \
354
79.8M
    FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
355
79.8M
    FT2[ ( Y0 >> 16 ) & 0xFF ] ^  \
356
79.8M
    FT3[ ( Y1 >> 24 ) & 0xFF ]; \
357
79.8M
            \
358
79.8M
  X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \
359
79.8M
    FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
360
79.8M
    FT2[ ( Y1 >> 16 ) & 0xFF ] ^  \
361
79.8M
    FT3[ ( Y2 >> 24 ) & 0xFF ]; \
362
79.8M
}
363
364
3.77M
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
365
3.77M
{           \
366
3.77M
  X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \
367
3.77M
    RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
368
3.77M
    RT2[ ( Y2 >> 16 ) & 0xFF ] ^  \
369
3.77M
    RT3[ ( Y1 >> 24 ) & 0xFF ]; \
370
3.77M
            \
371
3.77M
  X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \
372
3.77M
    RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
373
3.77M
    RT2[ ( Y3 >> 16 ) & 0xFF ] ^  \
374
3.77M
    RT3[ ( Y2 >> 24 ) & 0xFF ]; \
375
3.77M
            \
376
3.77M
  X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \
377
3.77M
    RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
378
3.77M
    RT2[ ( Y0 >> 16 ) & 0xFF ] ^  \
379
3.77M
    RT3[ ( Y3 >> 24 ) & 0xFF ]; \
380
3.77M
            \
381
3.77M
  X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \
382
3.77M
    RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
383
3.77M
    RT2[ ( Y1 >> 16 ) & 0xFF ] ^  \
384
3.77M
    RT3[ ( Y0 >> 24 ) & 0xFF ]; \
385
3.77M
}
386
387
/*
388
 * AES-ECB block encryption/decryption
389
 */
390
void fz_aes_crypt_ecb( aes_context *ctx,
391
  int mode,
392
  const uint8_t input[16],
393
  uint8_t output[16] )
394
9.29M
{
395
9.29M
  int i;
396
9.29M
  uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
397
398
#if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
399
  if( padlock_supports( PADLOCK_ACE ) )
400
  {
401
    if( padlock_xcryptecb( ctx, mode, input, output ) == 0 )
402
      return;
403
  }
404
#endif
405
406
9.29M
  RK = ctx->rk;
407
408
9.29M
  GET_ULONG_LE( X0, input, 0 ); X0 ^= *RK++;
409
9.29M
  GET_ULONG_LE( X1, input, 4 ); X1 ^= *RK++;
410
9.29M
  GET_ULONG_LE( X2, input, 8 ); X2 ^= *RK++;
411
9.29M
  GET_ULONG_LE( X3, input, 12 ); X3 ^= *RK++;
412
413
9.29M
  if( mode == FZ_AES_DECRYPT )
414
417k
  {
415
2.09M
    for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
416
1.67M
    {
417
1.67M
      AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
418
1.67M
      AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
419
1.67M
    }
420
421
417k
    AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
422
423
417k
    X0 = *RK++ ^ ( RSb[ ( Y0 ) & 0xFF ] ) ^
424
417k
      ( RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
425
417k
      ( RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
426
417k
      ( RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
427
428
417k
    X1 = *RK++ ^ ( RSb[ ( Y1 ) & 0xFF ] ) ^
429
417k
      ( RSb[ ( Y0 >>8 ) & 0xFF ] << 8 ) ^
430
417k
      ( RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
431
417k
      ( RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
432
433
417k
    X2 = *RK++ ^ ( RSb[ ( Y2 ) & 0xFF ] ) ^
434
417k
      ( RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
435
417k
      ( RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
436
417k
      ( RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
437
438
417k
    X3 = *RK ^ ( RSb[ ( Y3 ) & 0xFF ] ) ^
439
417k
      ( RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
440
417k
      ( RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
441
417k
      ( RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
442
417k
  }
443
8.87M
  else /* FZ_AES_ENCRYPT */
444
8.87M
  {
445
44.3M
    for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
446
35.5M
    {
447
35.5M
      AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
448
35.5M
      AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
449
35.5M
    }
450
451
8.87M
    AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
452
453
8.87M
    X0 = *RK++ ^ ( FSb[ ( Y0 ) & 0xFF ] ) ^
454
8.87M
      ( FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
455
8.87M
      ( FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
456
8.87M
      ( FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
457
458
8.87M
    X1 = *RK++ ^ ( FSb[ ( Y1 ) & 0xFF ] ) ^
459
8.87M
      ( FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
460
8.87M
      ( FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
461
8.87M
      ( FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
462
463
8.87M
    X2 = *RK++ ^ ( FSb[ ( Y2 ) & 0xFF ] ) ^
464
8.87M
      ( FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
465
8.87M
      ( FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
466
8.87M
      ( FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
467
468
8.87M
    X3 = *RK ^ ( FSb[ ( Y3 ) & 0xFF ] ) ^
469
8.87M
      ( FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
470
8.87M
      ( FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
471
8.87M
      ( FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
472
8.87M
  }
473
474
9.29M
  PUT_ULONG_LE( X0, output, 0 );
475
9.29M
  PUT_ULONG_LE( X1, output, 4 );
476
9.29M
  PUT_ULONG_LE( X2, output, 8 );
477
9.29M
  PUT_ULONG_LE( X3, output, 12 );
478
9.29M
}
479
480
/*
481
 * AES-CBC buffer encryption/decryption
482
 */
483
void fz_aes_crypt_cbc( aes_context *ctx,
484
  int mode,
485
  size_t length,
486
  uint8_t iv[16],
487
  const uint8_t *input,
488
  uint8_t *output )
489
406k
{
490
406k
  int i;
491
406k
  uint8_t temp[16];
492
493
#if defined(XYSSL_PADLOCK_C) && defined(XYSSL_HAVE_X86)
494
  if( padlock_supports( PADLOCK_ACE ) )
495
  {
496
    if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
497
      return;
498
  }
499
#endif
500
501
406k
  if( mode == FZ_AES_DECRYPT )
502
374k
  {
503
791k
    while( length > 0 )
504
417k
    {
505
417k
      memcpy( temp, input, 16 );
506
417k
      fz_aes_crypt_ecb( ctx, mode, input, output );
507
508
7.09M
      for( i = 0; i < 16; i++ )
509
6.67M
        output[i] = (uint8_t)( output[i] ^ iv[i] );
510
511
417k
      memcpy( iv, temp, 16 );
512
513
417k
      input += 16;
514
417k
      output += 16;
515
417k
      length -= 16;
516
417k
    }
517
374k
  }
518
32.7k
  else
519
32.7k
  {
520
8.90M
    while( length > 0 )
521
8.87M
    {
522
150M
      for( i = 0; i < 16; i++ )
523
142M
        output[i] = (uint8_t)( input[i] ^ iv[i] );
524
525
8.87M
      fz_aes_crypt_ecb( ctx, mode, output, output );
526
8.87M
      memcpy( iv, output, 16 );
527
528
8.87M
      input += 16;
529
8.87M
      output += 16;
530
8.87M
      length -= 16;
531
8.87M
    }
532
32.7k
  }
533
406k
}
534
535
#ifdef UNUSED
536
/*
537
 * AES-CFB buffer encryption/decryption
538
 */
539
void fz_aes_crypt_cfb( aes_context *ctx,
540
  int mode,
541
  int length,
542
  int *iv_off,
543
  uint8_t iv[16],
544
  const uint8_t *input,
545
  uint8_t *output )
546
{
547
  int c, n = *iv_off;
548
549
  if( mode == FZ_AES_DECRYPT )
550
  {
551
    while( length-- )
552
    {
553
      if( n == 0 )
554
        fz_aes_crypt_ecb( ctx, FZ_AES_ENCRYPT, iv, iv );
555
556
      c = *input++;
557
      *output++ = (uint8_t)( c ^ iv[n] );
558
      iv[n] = (uint8_t) c;
559
560
      n = (n + 1) & 0x0F;
561
    }
562
  }
563
  else
564
  {
565
    while( length-- )
566
    {
567
      if( n == 0 )
568
        fz_aes_crypt_ecb( ctx, FZ_AES_ENCRYPT, iv, iv );
569
570
      iv[n] = *output++ = (uint8_t)( iv[n] ^ *input++ );
571
572
      n = (n + 1) & 0x0F;
573
    }
574
  }
575
576
  *iv_off = n;
577
}
578
#endif