cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ctx_aes.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib AES Encryption Routines *
4 * Copyright Peter Gutmann 2000-2007 *
5 * *
6 ****************************************************************************/
7 
8 #if defined( INC_ALL )
9  #include "crypt.h"
10  #include "context.h"
11  #include "aes.h"
12  #include "aesopt.h"
13  #include "gcm.h"
14 #else
15  #include "crypt.h"
16  #include "context/context.h"
17  #include "crypt/aes.h"
18  #include "crypt/aesopt.h"
19  #include "crypt/gcm.h"
20 #endif /* Compiler-specific includes */
21 
22 /* The AES code separates encryption and decryption to make it easier to
23  do encrypt-only or decrypt-only apps, however since we don't know
24  what the user will choose to do we have to do both key schedules (this
25  is a relatively minor overhead compared to en/decryption, so it's not a
26  big problem).
27 
28  When building with VC++, the asm code used is aescrypt2.asm, built with
29  'yasm -Xvc -D ASMV2 -f win32 aescrypt2.asm', which provides the best
30  performance by using asm for the en/decrypt functions and C for the
31  key schedule */
32 
33 #ifdef USE_AES
34 
35 /* The size of an AES key and block and a keyscheduled AES key */
36 
37 #define AES_KEYSIZE 32
38 #define AES_BLOCKSIZE 16
39 #define AES_EXPANDED_KEYSIZE sizeof( AES_CTX )
40 
41 /* The size of the equivalent AES-GCM keying information */
42 
43 #define AES_GCM_CTX gcm_ctx
44 #define AES_GCM_EXPANDED_KEYSIZE sizeof( AES_GCM_CTX )
45 
46 /* The scheduled AES key and key schedule control and function return
47  codes */
48 
49 #define AES_EKEY aes_encrypt_ctx
50 #define AES_DKEY aes_decrypt_ctx
51 #define AES_2KEY AES_CTX
52 
53 /* AES-GCM can make use of various sizes of lookup tables for the GF-
54  multiplication, by default 4K tables are used (the best tradeoff between
55  speed and memory), in case the default is changed in the future we warn
56  the user that this will consume quite a bit of memory */
57 
58 #if defined( TABLES_8K ) || defined( TABLES_64K )
59  #error AES-GCM is configured to use unusually large GF-mult tables, is this deliberate?
60 #endif /* Unusually large GF-mult table sizes */
61 
62 /* The following macros are from the AES implementation, and aren't cryptlib
63  code.
64 
65  Assign memory for AES contexts in 'UNIT_SIZE' blocks of bytes with two
66  such blocks in cryptlib's AES context (one encryption and one decryption).
67  The cryptlib key schedule is then two AES contexts plus an extra UNIT_SIZE
68  block to allow for alignment adjustment by up to 'UNIT_SIZE' - 1 bytes to
69  align each of the internal AES contexts on UNIT_SIZE boundaries */
70 
71 #define UNIT_SIZE 16
72 
73 /* The size of the AES context rounded up (if necessary) to a multiple of 16
74  bytes */
75 
76 #define BYTE_SIZE( x ) ( UNIT_SIZE * ( ( sizeof( x ) + UNIT_SIZE - 1 ) / UNIT_SIZE ) )
77 
78 /* The size of the cryptlib AES context plus UNIT_SIZE bytes for possible upward
79  alignment to a UNIT_SIZE byte boundary */
80 
81 #define KS_SIZE ( BYTE_SIZE( AES_EKEY ) + BYTE_SIZE( AES_DKEY ) + UNIT_SIZE )
82 
83 /* The base address for the cryptlib AES context */
84 
85 #define KS_BASE(x) ( ( unsigned char * )( ( ( AES_CTX * ) x )->ksch ) )
86 
87 /* The AES encrypt/decrypt data within the AES context data */
88 
89 #define EKEY( x ) ( ( AES_EKEY * ) ALIGN_CEIL( KS_BASE( x ), UNIT_SIZE ) )
90 #define DKEY( x ) ( ( AES_DKEY * ) ALIGN_CEIL( KS_BASE( x ) + BYTE_SIZE( AES_EKEY ), UNIT_SIZE ) )
91 
92 /* A type to hold the cryptlib AES context */
93 
94 typedef unsigned long _unit;
95 typedef struct {
96  _unit ksch[ ( KS_SIZE + sizeof( _unit ) - 1 ) / sizeof( _unit ) ];
97  } AES_CTX;
98 
99 #define ENC_KEY( x ) EKEY( ( x )->key )
100 #define DEC_KEY( x ) DKEY( ( x )->key )
101 #define GCM_KEY( x ) ( x )->key
102 
103 /****************************************************************************
104 * *
105 * AES Self-test Routines *
106 * *
107 ****************************************************************************/
108 
109 #ifndef CONFIG_NO_SELFTEST
110 
111 /* AES FIPS test vectors */
112 
113 /* The data structure for the ( key, plaintext, ciphertext ) triplets */
114 
115 typedef struct {
116  const int keySize;
117  const BYTE key[ AES_KEYSIZE + 8 ];
118  const BYTE plaintext[ AES_BLOCKSIZE + 8 ];
119  const BYTE ciphertext[ AES_BLOCKSIZE + 8 ];
120  } AES_TEST;
121 
122 static const AES_TEST FAR_BSS testAES[] = {
123  { 16,
124  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
125  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F },
126  { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
127  0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
128  { 0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30,
129  0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A } },
130  { 24,
131  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
132  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
133  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
134  { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
135  0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
136  { 0xDD, 0xA9, 0x7C, 0xA4, 0x86, 0x4C, 0xDF, 0xE0,
137  0x6E, 0xAF, 0x70, 0xA0, 0xEC, 0x0D, 0x71, 0x91 } },
138  { 32,
139  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
140  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
141  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
142  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
143  { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
144  0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
145  { 0x8E, 0xA2, 0xB7, 0xCA, 0x51, 0x67, 0x45, 0xBF,
146  0xEA, 0xFC, 0x49, 0x90, 0x4B, 0x49, 0x60, 0x89 } }
147  };
148 
149 #if 0
150 
151 /* Test the AES code against the test vectors from the AES FIPS */
152 
153 static void printVector( const char *description, const BYTE *data,
154  const int length )
155  {
156  int i;
157 
158  printf( "%s = ", description );
159  for( i = 0; i < length; i++ )
160  printf( "%02x", data[ i ] );
161  putchar( '\n' );
162  }
163 
164 static int updateKey( BYTE *key, const int keySize,
165  CONTEXT_INFO *contextInfo,
166  const CAPABILITY_INFO *capabilityInfo,
167  const BYTE *newKey1, const BYTE *newKey2 )
168  {
169  BYTE keyData[ AES_KEYSIZE + 8 ];
170  int i;
171 
172  switch( keySize )
173  {
174  case 16:
175  memcpy( keyData, newKey2, keySize );
176  break;
177 
178  case 24:
179  memcpy( keyData, newKey1 + 8, keySize );
180  memcpy( keyData + 8, newKey2, AES_BLOCKSIZE );
181 
182  case 32:
183  memcpy( keyData, newKey1, AES_BLOCKSIZE );
184  memcpy( keyData + 16, newKey2, AES_BLOCKSIZE );
185  }
186 
187  for( i = 0; i < keySize; i++ )
188  key[ i ] ^= keyData[ i ];
189  return( capabilityInfo->initKeyFunction( contextInfo, key,
190  keySize ) );
191  }
192 
193 static int mct( CONTEXT_INFO *contextInfo,
194  const CAPABILITY_INFO *capabilityInfo,
195  const BYTE *initialKey, const int keySize,
196  const BYTE *initialIV, const BYTE *initialPT )
197  {
198  BYTE key[ AES_KEYSIZE + 8 ], iv[ AES_KEYSIZE + 8 ];
199  BYTE temp[ AES_BLOCKSIZE + 8 ];
200  int i;
201 
202  memcpy( key, initialKey, keySize );
203  if( iv != NULL )
204  memcpy( iv, initialIV, AES_BLOCKSIZE );
205  memcpy( temp, initialPT, AES_BLOCKSIZE );
206  for( i = 0; i < 100; i++ )
207  {
208  BYTE prevTemp[ AES_BLOCKSIZE + 8 ];
209  int j, status;
210 
211  status = capabilityInfo->initKeyFunction( contextInfo, key,
212  keySize );
213  if( cryptStatusError( status ) )
214  return( status );
215  printVector( "Key", key, keySize );
216  if( iv != NULL )
217  printVector( "IV", iv, AES_BLOCKSIZE );
218  printVector( "Plaintext", temp, AES_BLOCKSIZE );
219  if( iv != NULL )
220  memcpy( contextInfo->ctxConv->currentIV, iv, AES_BLOCKSIZE );
221  for( j = 0; j < 1000; j++ )
222  {
223 /* memcpy( prevTemp, temp, AES_BLOCKSIZE ); */
224  if( iv != NULL && j == 0 )
225  {
226  status = capabilityInfo->encryptCBCFunction( contextInfo, temp,
227  AES_BLOCKSIZE );
228  memcpy( prevTemp, temp, AES_BLOCKSIZE );
229  memcpy( temp, iv, AES_BLOCKSIZE );
230  }
231  else
232  {
233  status = capabilityInfo->encryptFunction( contextInfo, temp,
234  AES_BLOCKSIZE );
235  if( iv != NULL )
236  {
237  BYTE tmpTemp[ AES_BLOCKSIZE + 8 ];
238 
239  memcpy( tmpTemp, temp, AES_BLOCKSIZE );
240  memcpy( temp, prevTemp, AES_BLOCKSIZE );
241  memcpy( prevTemp, tmpTemp, AES_BLOCKSIZE );
242  }
243  }
244  if( cryptStatusError( status ) )
245  return( status );
246  }
247  printVector( "Ciphertext", temp, AES_BLOCKSIZE );
248  putchar( '\n' );
249  status = updateKey( key, keySize, contextInfo, capabilityInfo,
250  prevTemp, temp );
251  if( cryptStatusError( status ) )
252  return( status );
253  }
254 
255  return( CRYPT_OK );
256  }
257 #endif
258 
259 static int selfTest( void )
260  {
261 #if 0
262  /* ECB */
263  static const BYTE FAR_BSS mctECBKey[] = \
264  { 0x8D, 0x2E, 0x60, 0x36, 0x5F, 0x17, 0xC7, 0xDF, 0x10, 0x40, 0xD7, 0x50, 0x1B, 0x4A, 0x7B, 0x5A };
265  static const BYTE FAR_BSS mctECBPT[] = \
266  { 0x59, 0xB5, 0x08, 0x8E, 0x6D, 0xAD, 0xC3, 0xAD, 0x5F, 0x27, 0xA4, 0x60, 0x87, 0x2D, 0x59, 0x29 };
267  /* CBC */
268  static const BYTE FAR_BSS mctCBCKey[] = \
269  { 0x9D, 0xC2, 0xC8, 0x4A, 0x37, 0x85, 0x0C, 0x11, 0x69, 0x98, 0x18, 0x60, 0x5F, 0x47, 0x95, 0x8C };
270  static const BYTE FAR_BSS mctCBCIV[] = \
271  { 0x25, 0x69, 0x53, 0xB2, 0xFE, 0xAB, 0x2A, 0x04, 0xAE, 0x01, 0x80, 0xD8, 0x33, 0x5B, 0xBE, 0xD6 };
272  static const BYTE FAR_BSS mctCBCPT[] = \
273  { 0x2E, 0x58, 0x66, 0x92, 0xE6, 0x47, 0xF5, 0x02, 0x8E, 0xC6, 0xFA, 0x47, 0xA5, 0x5A, 0x2A, 0xAB };
274  /* OFB */
275  static const BYTE FAR_BSS mctOFBKey[] = \
276  { 0xB1, 0x1E, 0x4E, 0xCA, 0xE2, 0xE7, 0x1E, 0x14, 0x14, 0x5D, 0xD7, 0xDB, 0x26, 0x35, 0x65, 0x2F };
277  static const BYTE FAR_BSS mctOFBIV[] = \
278  { 0xAD, 0xD3, 0x2B, 0xF8, 0x20, 0x4C, 0x33, 0x33, 0x9C, 0x54, 0xCD, 0x58, 0x58, 0xEE, 0x0D, 0x13 };
279  static const BYTE FAR_BSS mctOFBPT[] = \
280  { 0x73, 0x20, 0x49, 0xE8, 0x9D, 0x74, 0xFC, 0xE7, 0xC5, 0xA4, 0x96, 0x64, 0x04, 0x86, 0x8F, 0xA6 };
281  /* CFB-128 */
282  static const BYTE FAR_BSS mctCFBKey[] = \
283  { 0x71, 0x15, 0x11, 0x93, 0x1A, 0x15, 0x62, 0xEA, 0x73, 0x29, 0x0A, 0x8B, 0x0A, 0x37, 0xA3, 0xB4 };
284  static const BYTE FAR_BSS mctCFBIV[] = \
285  { 0x9D, 0xCE, 0x23, 0xFD, 0x2D, 0xF5, 0x36, 0x0F, 0x79, 0x9C, 0xF1, 0x79, 0x84, 0xE4, 0x7C, 0x8D };
286  static const BYTE FAR_BSS mctCFBPT[] = \
287  { 0xF0, 0x66, 0xBE, 0x4B, 0xD6, 0x71, 0xEB, 0xC1, 0xC4, 0xCF, 0x3C, 0x00, 0x8E, 0xF2, 0xCF, 0x18 };
288 #endif /* 0 */
289  const CAPABILITY_INFO *capabilityInfo = getAESCapability();
290  BYTE keyData[ AES_EXPANDED_KEYSIZE + 8 ];
291  int i, status;
292 
293  /* The AES code requires 16-byte alignment for data structures, before
294  we try anything else we make sure that the compiler voodoo required
295  to handle this has worked */
297  return( CRYPT_ERROR_FAILED );
298 
299  for( i = 0; i < sizeof( testAES ) / sizeof( AES_TEST ); i++ )
300  {
301  status = testCipher( capabilityInfo, keyData, testAES[ i ].key,
302  testAES[ i ].keySize, testAES[ i ].plaintext,
303  testAES[ i ].ciphertext );
304  if( cryptStatusError( status ) )
305  return( status );
306  }
307 
308 #if 0 /* OK */
309  staticInitContext( &contextInfo, CONTEXT_CONV, capabilityInfo,
310  &contextData, sizeof( CONV_INFO ), keyData );
311  status = mct( &contextInfo, capabilityInfo, mctECBKey, 16,
312  NULL, mctECBPT );
313  staticDestroyContext( &contextInfo );
314  if( cryptStatusError( status ) )
315  return( CRYPT_ERROR_FAILED );
316 #endif
317 #if 0 /* OK */
318  staticInitContext( &contextInfo, CONTEXT_CONV, capabilityInfo,
319  &contextData, sizeof( CONV_INFO ), keyData );
320  status = mct( &contextInfo, capabilityInfo, mctCBCKey, 16,
321  mctCBCIV, mctCBCPT );
322  staticDestroyContext( &contextInfo );
323  if( cryptStatusError( status ) )
324  return( CRYPT_ERROR_FAILED );
325 #endif
326 
327  return( CRYPT_OK );
328  }
329 #else
330  #define selfTest NULL
331 #endif /* !CONFIG_NO_SELFTEST */
332 
333 /****************************************************************************
334 * *
335 * Control Routines *
336 * *
337 ****************************************************************************/
338 
339 /* Return context subtype-specific information */
340 
342 static int getInfo( IN_ENUM( CAPABILITY_INFO ) const CAPABILITY_INFO_TYPE type,
344  OUT void *data,
345  IN_INT_Z const int length )
346  {
347  assert( contextInfoPtr == NULL || \
348  isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
349  assert( ( length == 0 && isWritePtr( data, sizeof( int ) ) ) || \
350  ( length > 0 && isWritePtr( data, length ) ) );
351 
352  static_assert( AES_EXPANDED_KEYSIZE >= KS_SIZE, "AES context storage" );
353 
355  REQUIRES( ( ( type == CAPABILITY_INFO_STATESIZE || \
356  type == CAPABILITY_INFO_STATEALIGNTYPE ) && \
357  contextInfoPtr == NULL ) || \
358  ( type == CAPABILITY_INFO_ICV && \
359  contextInfoPtr != NULL ) );
360 
361  switch( type )
362  {
364  {
365  int *valuePtr = ( int * ) data;
366 
367 #ifdef USE_GCM
368  *valuePtr = max( AES_EXPANDED_KEYSIZE, AES_GCM_EXPANDED_KEYSIZE );
369 #else
370  *valuePtr = AES_EXPANDED_KEYSIZE;
371 #endif /* USE_GCM */
372 
373  return( CRYPT_OK );
374  }
375 
377  {
378  int *valuePtr = ( int * ) data;
379 
380  /* The AES code requires alignment to 128-bit boundaries */
381  *valuePtr = UNIT_SIZE;
382 
383  return( CRYPT_OK );
384  }
385 #ifdef USE_GCM
386  case CAPABILITY_INFO_ICV:
387  {
388  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
389 
390  REQUIRES( convInfo->mode == CRYPT_MODE_GCM );
391 
392  return( ( gcm_compute_tag( data, length,
393  GCM_KEY( convInfo ) ) == RETURN_GOOD ) ? \
395  }
396 #endif /* USE_GCM */
397 
398  default:
399  return( getDefaultInfo( type, contextInfoPtr, data, length ) );
400  }
401 
402  retIntError();
403  }
404 
405 /****************************************************************************
406 * *
407 * AES En/Decryption Routines *
408 * *
409 ****************************************************************************/
410 
411 /* Encrypt/decrypt data in ECB/CBC/CFB modes. These are just basic wrappers
412  for the AES code, which either calls down to the C/asm AES routines or
413  uses hardware assist to perform the operation directly */
414 
415 static int encryptECB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
416  int noBytes )
417  {
418  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
419 
420  return( ( aes_ecb_encrypt( buffer, buffer, noBytes,
421  ENC_KEY( convInfo ) ) == EXIT_SUCCESS ) ? \
423  }
424 
425 static int decryptECB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
426  int noBytes )
427  {
428  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
429 
430  return( ( aes_ecb_decrypt( buffer, buffer, noBytes,
431  DEC_KEY( convInfo ) ) == EXIT_SUCCESS ) ? \
433  }
434 
435 static int encryptCBC( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
436  int noBytes )
437  {
438  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
439 
440  return( ( aes_cbc_encrypt( buffer, buffer, noBytes, convInfo->currentIV,
441  ENC_KEY( convInfo ) ) == EXIT_SUCCESS ) ? \
443  }
444 
445 static int decryptCBC( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
446  int noBytes )
447  {
448  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
449 
450  return( ( aes_cbc_decrypt( buffer, buffer, noBytes, convInfo->currentIV,
451  DEC_KEY( convInfo ) ) == EXIT_SUCCESS ) ? \
453  }
454 
455 static int encryptCFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
456  int noBytes )
457  {
458  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
459 
460  return( ( aes_cfb_encrypt( buffer, buffer, noBytes, convInfo->currentIV,
461  ENC_KEY( convInfo ) ) == EXIT_SUCCESS ) ? \
463  }
464 
465 static int decryptCFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
466  int noBytes )
467  {
468  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
469 
470  return( ( aes_cfb_decrypt( buffer, buffer, noBytes, convInfo->currentIV,
471  ENC_KEY( convInfo ) ) == EXIT_SUCCESS ) ? \
473  }
474 
475 static int encryptOFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
476  int noBytes )
477  {
478  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
479 
480  return( ( aes_ofb_encrypt( buffer, buffer, noBytes, convInfo->currentIV,
481  ENC_KEY( convInfo ) ) == EXIT_SUCCESS ) ? \
483  }
484 
485 static int decryptOFB( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
486  int noBytes )
487  {
488  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
489 
490  return( ( aes_ofb_decrypt( buffer, buffer, noBytes, convInfo->currentIV,
491  ENC_KEY( convInfo ) ) == EXIT_SUCCESS ) ? \
493  }
494 
495 #ifdef USE_GCM
496 
497 static int encryptGCM( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
498  int noBytes )
499  {
500  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
501 
502  return( ( gcm_encrypt( buffer, noBytes,
503  GCM_KEY( convInfo ) ) == RETURN_GOOD ) ? \
505  }
506 
507 static int decryptGCM( CONTEXT_INFO *contextInfoPtr, BYTE *buffer,
508  int noBytes )
509  {
510  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
511 
512  return( ( gcm_decrypt( buffer, noBytes,
513  GCM_KEY( convInfo ) ) == RETURN_GOOD ) ? \
515  }
516 #endif /* USE_GCM */
517 
518 /****************************************************************************
519 * *
520 * AES Key Management Routines *
521 * *
522 ****************************************************************************/
523 
524 /* Initialise crypto parameters such as the IV and encryption mode */
525 
527 static int initParams( INOUT CONTEXT_INFO *contextInfoPtr,
528  IN_ENUM( KEYPARAM ) const KEYPARAM_TYPE paramType,
529  IN_OPT const void *data,
530  IN_INT const int dataLength )
531  {
532 #ifdef USE_GCM
533  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
534 #endif /* USE_GCM */
535 
536  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
537 
538  REQUIRES( contextInfoPtr->type == CONTEXT_CONV );
539  REQUIRES( paramType > KEYPARAM_NONE && paramType < KEYPARAM_LAST );
540 
541 #ifdef USE_GCM
542  /* Handling of crypto parameters is normally done by a global generic
543  function, however for AES-GCM we have to provide special handling
544  for IV loading */
545  if( paramType == KEYPARAM_IV && convInfo->mode == CRYPT_MODE_GCM )
546  {
547  if( gcm_init_message( data, dataLength,
548  GCM_KEY( convInfo ) ) != RETURN_GOOD )
549  return( CRYPT_ERROR_FAILED );
550  }
551  if( paramType == KEYPARAM_AAD )
552  {
553  REQUIRES( convInfo->mode == CRYPT_MODE_GCM );
554 
555  return( ( gcm_auth_header( data, dataLength,
556  GCM_KEY( convInfo ) ) == RETURN_GOOD ) ? \
558  }
559 #endif /* USE_GCM */
560 
561  /* Pass the call on down to the global parameter-handling function */
562  return( initGenericParams( contextInfoPtr, paramType, data,
563  dataLength ) );
564  }
565 
566 /* Key schedule an AES key */
567 
568 static int initKey( CONTEXT_INFO *contextInfoPtr, const void *key,
569  const int keyLength )
570  {
571  CONV_INFO *convInfo = contextInfoPtr->ctxConv;
572 
573  /* Copy the key to internal storage */
574  if( convInfo->userKey != key )
575  memcpy( convInfo->userKey, key, keyLength );
576  convInfo->userKeyLength = keyLength;
577 
578  /* Call the AES key schedule code */
579 #ifdef USE_GCM
580  if( convInfo->mode == CRYPT_MODE_GCM )
581  {
582  if( gcm_init_and_key( convInfo->userKey, keyLength,
583  GCM_KEY( convInfo ) ) != RETURN_GOOD )
584  return( CRYPT_ERROR_FAILED );
585  }
586  else
587 #endif /* USE_GCM */
588  {
589  if( aes_encrypt_key( convInfo->userKey, keyLength,
590  ENC_KEY( convInfo ) ) != EXIT_SUCCESS )
591  return( CRYPT_ERROR_FAILED );
592  if( aes_decrypt_key( convInfo->userKey, keyLength,
593  DEC_KEY( convInfo ) ) != EXIT_SUCCESS )
594  return( CRYPT_ERROR_FAILED );
595  }
596  return( CRYPT_OK );
597  }
598 
599 /****************************************************************************
600 * *
601 * Capability Access Routines *
602 * *
603 ****************************************************************************/
604 
605 static const CAPABILITY_INFO FAR_BSS capabilityInfo = {
606  CRYPT_ALGO_AES, bitsToBytes( 128 ), "AES", 3,
607  bitsToBytes( 128 ), bitsToBytes( 128 ), bitsToBytes( 256 ),
608  selfTest, getInfo, NULL, initParams, initKey, NULL,
609  encryptECB, decryptECB, encryptCBC, decryptCBC,
610  encryptCFB, decryptCFB, encryptOFB, decryptOFB,
611 #ifdef USE_GCM
612  encryptGCM, decryptGCM
613 #endif /* USE_GCM */
614  };
615 
616 const CAPABILITY_INFO *getAESCapability( void )
617  {
618  /* If we're not using compiler-generated tables, we have to manually
619  initialise the tables before we can use AES (this is only required
620  for old/broken compilers that aren't tough enough for the
621  preprocessor-based table calculations) */
622 #ifndef FIXED_TABLES
623  gen_tabs();
624 #endif /* FIXED_TABLES */
625 
626  return( &capabilityInfo );
627  }
628 #endif /* USE_AES */