Coverage Report

Created: 2025-12-31 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/mupdf/source/fitz/crypt-aes.c
Line
Count
Source
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
0
#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
0
#define GET_ULONG_LE(n,b,i)         \
57
0
{               \
58
0
  (n) = ( (uint32_t) (b)[(i)] )     \
59
0
    | ( (uint32_t) (b)[(i) + 1] << 8 )    \
60
0
    | ( (uint32_t) (b)[(i) + 2] << 16 ) \
61
0
    | ( (uint32_t) (b)[(i) + 3] << 24 );  \
62
0
}
63
#endif
64
65
#ifndef PUT_ULONG_LE
66
0
#define PUT_ULONG_LE(n,b,i)       \
67
0
{             \
68
0
  (b)[(i) ] = (uint8_t) ( (n) );    \
69
0
  (b)[(i) + 1] = (uint8_t) ( (n) >> 8 );  \
70
0
  (b)[(i) + 2] = (uint8_t) ( (n) >> 16 ); \
71
0
  (b)[(i) + 3] = (uint8_t) ( (n) >> 24 ); \
72
0
}
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
0
#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
102
0
#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
103
0
#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
0
{
109
0
  int i, x, y, z;
110
0
  int pow[256];
111
0
  int log[256];
112
113
  /*
114
   * compute pow and log tables over GF(2^8)
115
   */
116
0
  for( i = 0, x = 1; i < 256; i++ )
117
0
  {
118
0
    pow[i] = x;
119
0
    log[x] = i;
120
0
    x = ( x ^ XTIME( x ) ) & 0xFF;
121
0
  }
122
123
  /*
124
   * calculate the round constants
125
   */
126
0
  for( i = 0, x = 1; i < 10; i++ )
127
0
  {
128
0
    RCON[i] = (uint32_t) x;
129
0
    x = XTIME( x ) & 0xFF;
130
0
  }
131
132
  /*
133
   * generate the forward and reverse S-boxes
134
   */
135
0
  FSb[0x00] = 0x63;
136
0
  RSb[0x63] = 0x00;
137
138
0
  for( i = 1; i < 256; i++ )
139
0
  {
140
0
    x = pow[255 - log[i]];
141
142
0
    y = x; y = ( (y << 1) | (y >> 7) ) & 0xFF;
143
0
    x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
144
0
    x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
145
0
    x ^= y; y = ( (y << 1) | (y >> 7) ) & 0xFF;
146
0
    x ^= y ^ 0x63;
147
148
0
    FSb[i] = (uint8_t) x;
149
0
    RSb[x] = (uint8_t) i;
150
0
  }
151
152
  /*
153
   * generate the forward and reverse tables
154
   */
155
0
  for( i = 0; i < 256; i++ )
156
0
  {
157
0
    x = FSb[i];
158
0
    y = XTIME( x ) & 0xFF;
159
0
    z = ( y ^ x ) & 0xFF;
160
161
0
    FT0[i] = ( (uint32_t) y ) ^
162
0
      ( (uint32_t) x << 8 ) ^
163
0
      ( (uint32_t) x << 16 ) ^
164
0
      ( (uint32_t) z << 24 );
165
166
0
    FT1[i] = ROTL8( FT0[i] );
167
0
    FT2[i] = ROTL8( FT1[i] );
168
0
    FT3[i] = ROTL8( FT2[i] );
169
170
0
    x = RSb[i];
171
172
0
    RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
173
0
      ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
174
0
      ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
175
0
      ( (uint32_t) MUL( 0x0B, x ) << 24 );
176
177
0
    RT1[i] = ROTL8( RT0[i] );
178
0
    RT2[i] = ROTL8( RT1[i] );
179
0
    RT3[i] = ROTL8( RT2[i] );
180
0
  }
181
0
}
182
183
/*
184
 * AES key schedule (encryption)
185
 */
186
int fz_aes_setkey_enc( aes_context *ctx, const uint8_t *key, int keysize )
187
0
{
188
0
  int i;
189
0
  uint32_t *RK;
190
191
0
#if !defined(XYSSL_AES_ROM_TABLES)
192
0
  if( aes_init_done == 0 )
193
0
  {
194
0
    aes_gen_tables();
195
0
    aes_init_done = 1;
196
0
  }
197
0
#endif
198
199
0
  switch( keysize )
200
0
  {
201
0
  case 128: ctx->nr = 10; break;
202
0
  case 192: ctx->nr = 12; break;
203
0
  case 256: ctx->nr = 14; break;
204
0
  default : return 1;
205
0
  }
206
207
#if defined(PADLOCK_ALIGN16)
208
  ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
209
#else
210
0
  ctx->rk = RK = ctx->buf;
211
0
#endif
212
213
0
  for( i = 0; i < (keysize >> 5); i++ )
214
0
  {
215
0
    GET_ULONG_LE( RK[i], key, i << 2 );
216
0
  }
217
218
0
  switch( ctx->nr )
219
0
  {
220
0
  case 10:
221
222
0
    for( i = 0; i < 10; i++, RK += 4 )
223
0
    {
224
0
      RK[4] = RK[0] ^ RCON[i] ^
225
0
        ( FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
226
0
        ( FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
227
0
        ( FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
228
0
        ( FSb[ ( RK[3] ) & 0xFF ] << 24 );
229
230
0
      RK[5] = RK[1] ^ RK[4];
231
0
      RK[6] = RK[2] ^ RK[5];
232
0
      RK[7] = RK[3] ^ RK[6];
233
0
    }
234
0
    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
0
  case 14:
255
256
0
    for( i = 0; i < 7; i++, RK += 8 )
257
0
    {
258
0
      RK[8] = RK[0] ^ RCON[i] ^
259
0
        ( FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
260
0
        ( FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
261
0
        ( FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
262
0
        ( FSb[ ( RK[7] ) & 0xFF ] << 24 );
263
264
0
      RK[9] = RK[1] ^ RK[8];
265
0
      RK[10] = RK[2] ^ RK[9];
266
0
      RK[11] = RK[3] ^ RK[10];
267
268
0
      RK[12] = RK[4] ^
269
0
        ( FSb[ ( RK[11] ) & 0xFF ] ) ^
270
0
        ( FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
271
0
        ( FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
272
0
        ( FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
273
274
0
      RK[13] = RK[5] ^ RK[12];
275
0
      RK[14] = RK[6] ^ RK[13];
276
0
      RK[15] = RK[7] ^ RK[14];
277
0
    }
278
0
    break;
279
280
0
  default:
281
282
0
    break;
283
0
  }
284
0
  return 0;
285
0
}
286
287
/*
288
 * AES key schedule (decryption)
289
 */
290
int fz_aes_setkey_dec(aes_context *ctx, const uint8_t *key, int keysize)
291
0
{
292
0
  int i, j;
293
0
  aes_context cty;
294
0
  uint32_t *RK;
295
0
  uint32_t *SK;
296
297
0
  switch( keysize )
298
0
  {
299
0
  case 128: ctx->nr = 10; break;
300
0
  case 192: ctx->nr = 12; break;
301
0
  case 256: ctx->nr = 14; break;
302
0
  default: return 1;
303
0
  }
304
305
#if defined(PADLOCK_ALIGN16)
306
  ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
307
#else
308
0
  ctx->rk = RK = ctx->buf;
309
0
#endif
310
311
0
  i = fz_aes_setkey_enc( &cty, key, keysize );
312
0
  if (i)
313
0
    return i;
314
0
  SK = cty.rk + cty.nr * 4;
315
316
0
  *RK++ = *SK++;
317
0
  *RK++ = *SK++;
318
0
  *RK++ = *SK++;
319
0
  *RK++ = *SK++;
320
321
0
  for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
322
0
  {
323
0
    for( j = 0; j < 4; j++, SK++ )
324
0
    {
325
0
      *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
326
0
        RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
327
0
        RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
328
0
        RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
329
0
    }
330
0
  }
331
332
0
  *RK++ = *SK++;
333
0
  *RK++ = *SK++;
334
0
  *RK++ = *SK++;
335
0
  *RK = *SK;
336
337
0
  memset( &cty, 0, sizeof( aes_context ) );
338
0
  return 0;
339
0
}
340
341
0
#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
342
0
{           \
343
0
  X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \
344
0
    FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
345
0
    FT2[ ( Y2 >> 16 ) & 0xFF ] ^  \
346
0
    FT3[ ( Y3 >> 24 ) & 0xFF ]; \
347
0
            \
348
0
  X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \
349
0
    FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
350
0
    FT2[ ( Y3 >> 16 ) & 0xFF ] ^  \
351
0
    FT3[ ( Y0 >> 24 ) & 0xFF ]; \
352
0
            \
353
0
  X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \
354
0
    FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
355
0
    FT2[ ( Y0 >> 16 ) & 0xFF ] ^  \
356
0
    FT3[ ( Y1 >> 24 ) & 0xFF ]; \
357
0
            \
358
0
  X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \
359
0
    FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
360
0
    FT2[ ( Y1 >> 16 ) & 0xFF ] ^  \
361
0
    FT3[ ( Y2 >> 24 ) & 0xFF ]; \
362
0
}
363
364
0
#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
365
0
{           \
366
0
  X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \
367
0
    RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
368
0
    RT2[ ( Y2 >> 16 ) & 0xFF ] ^  \
369
0
    RT3[ ( Y1 >> 24 ) & 0xFF ]; \
370
0
            \
371
0
  X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \
372
0
    RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
373
0
    RT2[ ( Y3 >> 16 ) & 0xFF ] ^  \
374
0
    RT3[ ( Y2 >> 24 ) & 0xFF ]; \
375
0
            \
376
0
  X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \
377
0
    RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
378
0
    RT2[ ( Y0 >> 16 ) & 0xFF ] ^  \
379
0
    RT3[ ( Y3 >> 24 ) & 0xFF ]; \
380
0
            \
381
0
  X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \
382
0
    RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
383
0
    RT2[ ( Y1 >> 16 ) & 0xFF ] ^  \
384
0
    RT3[ ( Y0 >> 24 ) & 0xFF ]; \
385
0
}
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
0
{
395
0
  int i;
396
0
  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
0
  RK = ctx->rk;
407
408
0
  GET_ULONG_LE( X0, input, 0 ); X0 ^= *RK++;
409
0
  GET_ULONG_LE( X1, input, 4 ); X1 ^= *RK++;
410
0
  GET_ULONG_LE( X2, input, 8 ); X2 ^= *RK++;
411
0
  GET_ULONG_LE( X3, input, 12 ); X3 ^= *RK++;
412
413
0
  if( mode == FZ_AES_DECRYPT )
414
0
  {
415
0
    for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
416
0
    {
417
0
      AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
418
0
      AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
419
0
    }
420
421
0
    AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
422
423
0
    X0 = *RK++ ^ ( RSb[ ( Y0 ) & 0xFF ] ) ^
424
0
      ( RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
425
0
      ( RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
426
0
      ( RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
427
428
0
    X1 = *RK++ ^ ( RSb[ ( Y1 ) & 0xFF ] ) ^
429
0
      ( RSb[ ( Y0 >>8 ) & 0xFF ] << 8 ) ^
430
0
      ( RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
431
0
      ( RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
432
433
0
    X2 = *RK++ ^ ( RSb[ ( Y2 ) & 0xFF ] ) ^
434
0
      ( RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
435
0
      ( RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
436
0
      ( RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
437
438
0
    X3 = *RK ^ ( RSb[ ( Y3 ) & 0xFF ] ) ^
439
0
      ( RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
440
0
      ( RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
441
0
      ( RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
442
0
  }
443
0
  else /* FZ_AES_ENCRYPT */
444
0
  {
445
0
    for( i = (ctx->nr >> 1) - 1; i > 0; i-- )
446
0
    {
447
0
      AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
448
0
      AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
449
0
    }
450
451
0
    AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
452
453
0
    X0 = *RK++ ^ ( FSb[ ( Y0 ) & 0xFF ] ) ^
454
0
      ( FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
455
0
      ( FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
456
0
      ( FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
457
458
0
    X1 = *RK++ ^ ( FSb[ ( Y1 ) & 0xFF ] ) ^
459
0
      ( FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
460
0
      ( FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
461
0
      ( FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
462
463
0
    X2 = *RK++ ^ ( FSb[ ( Y2 ) & 0xFF ] ) ^
464
0
      ( FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
465
0
      ( FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
466
0
      ( FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
467
468
0
    X3 = *RK ^ ( FSb[ ( Y3 ) & 0xFF ] ) ^
469
0
      ( FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
470
0
      ( FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
471
0
      ( FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
472
0
  }
473
474
0
  PUT_ULONG_LE( X0, output, 0 );
475
0
  PUT_ULONG_LE( X1, output, 4 );
476
0
  PUT_ULONG_LE( X2, output, 8 );
477
0
  PUT_ULONG_LE( X3, output, 12 );
478
0
}
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
0
{
490
0
  int i;
491
0
  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
0
  if( mode == FZ_AES_DECRYPT )
502
0
  {
503
0
    while( length > 0 )
504
0
    {
505
0
      memcpy( temp, input, 16 );
506
0
      fz_aes_crypt_ecb( ctx, mode, input, output );
507
508
0
      for( i = 0; i < 16; i++ )
509
0
        output[i] = (uint8_t)( output[i] ^ iv[i] );
510
511
0
      memcpy( iv, temp, 16 );
512
513
0
      input += 16;
514
0
      output += 16;
515
0
      length -= 16;
516
0
    }
517
0
  }
518
0
  else
519
0
  {
520
0
    while( length > 0 )
521
0
    {
522
0
      for( i = 0; i < 16; i++ )
523
0
        output[i] = (uint8_t)( input[i] ^ iv[i] );
524
525
0
      fz_aes_crypt_ecb( ctx, mode, output, output );
526
0
      memcpy( iv, output, 16 );
527
528
0
      input += 16;
529
0
      output += 16;
530
0
      length -= 16;
531
0
    }
532
0
  }
533
0
}
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