crypt-aes.c 13 KB

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