cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
ctx_misc.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib Context Support Routines *
4 * Copyright Peter Gutmann 1995-2007 *
5 * *
6 ****************************************************************************/
7 
8 #define PKC_CONTEXT /* Indicate that we're working with PKC contexts */
9 #if defined( INC_ALL )
10  #include "crypt.h"
11  #include "context.h"
12  #ifdef USE_MD5
13  #include "md5.h"
14  #endif /* USE_MD5 */
15  #ifdef USE_RIPEMD160
16  #include "ripemd.h"
17  #endif /* USE_RIPEMD160 */
18  #include "sha.h"
19  #ifdef USE_SHA2
20  #include "sha2.h"
21  #endif /* USE_SHA2 */
22 #else
23  #include "crypt.h"
24  #include "context/context.h"
25  #ifdef USE_MD5
26  #include "crypt/md5.h"
27  #endif /* USE_MD5 */
28  #ifdef USE_RIPEMD160
29  #include "crypt/ripemd.h"
30  #endif /* USE_RIPEMD160 */
31  #include "crypt/sha.h"
32  #ifdef USE_SHA2
33  #include "crypt/sha2.h"
34  #endif /* USE_SHA2 */
35 #endif /* Compiler-specific includes */
36 
37 /****************************************************************************
38 * *
39 * Capability Management Functions *
40 * *
41 ****************************************************************************/
42 
43 /* Check that a capability info record is consistent */
44 
46 BOOLEAN sanityCheckCapability( const CAPABILITY_INFO *capabilityInfoPtr,
47  const BOOLEAN asymmetricOK )
48  {
49  CRYPT_ALGO_TYPE cryptAlgo = capabilityInfoPtr->cryptAlgo;
50 
51  assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) );
52 
53  /* Check the algorithm and mode parameters. We check for an algorithm
54  name one shorter than the maximum because as returned to an external
55  caller it's an ASCIZ string so we need to allow room for the
56  terminator */
57  if( cryptAlgo <= CRYPT_ALGO_NONE || cryptAlgo >= CRYPT_ALGO_LAST || \
58  capabilityInfoPtr->algoName == NULL || \
59  capabilityInfoPtr->algoNameLen < 3 || \
60  capabilityInfoPtr->algoNameLen > CRYPT_MAX_TEXTSIZE - 1 )
61  return( FALSE );
62 
63  /* Make sure that the minimum functions are present. We don't check for
64  the presence of the keygen function since the symmetric capabilities
65  use the generic keygen and the hash capabilities don't do keygen at
66  all */
67  if( capabilityInfoPtr->selfTestFunction == NULL || \
68  capabilityInfoPtr->getInfoFunction == NULL )
69  return( FALSE );
70  if( isStreamCipher( cryptAlgo ) )
71  {
72  if( capabilityInfoPtr->encryptOFBFunction == NULL || \
73  capabilityInfoPtr->decryptOFBFunction == NULL )
74  return( FALSE );
75  }
76  else
77  {
78  if( asymmetricOK )
79  {
80  /* If asymmetric capabilities (e.g. decrypt but not encrypt,
81  present in some tinkertoy tokens) are permitted then we only
82  check that there's at least one useful capability available */
83  if( capabilityInfoPtr->decryptFunction == NULL && \
84  capabilityInfoPtr->signFunction == NULL )
85  return( FALSE );
86  }
87  else
88  {
89  if( !isSpecialAlgo( cryptAlgo ) )
90  {
91  /* We need at least one mechanism pair to be able to do
92  anything useful with the capability */
93  if( ( capabilityInfoPtr->encryptFunction == NULL || \
94  capabilityInfoPtr->decryptFunction == NULL ) && \
95  ( capabilityInfoPtr->encryptCBCFunction == NULL || \
96  capabilityInfoPtr->decryptCBCFunction == NULL ) && \
97  ( capabilityInfoPtr->encryptCFBFunction == NULL || \
98  capabilityInfoPtr->decryptCFBFunction == NULL ) && \
99  ( capabilityInfoPtr->encryptOFBFunction == NULL || \
100  capabilityInfoPtr->decryptOFBFunction == NULL ) && \
101  ( capabilityInfoPtr->encryptGCMFunction == NULL || \
102  capabilityInfoPtr->decryptGCMFunction == NULL ) && \
103  ( capabilityInfoPtr->signFunction == NULL || \
104  capabilityInfoPtr->sigCheckFunction == NULL ) )
105  return( FALSE );
106  }
107  }
108  }
109 
110  /* Make sure that the algorithm/mode-specific parameters are
111  consistent */
112  if( capabilityInfoPtr->minKeySize > capabilityInfoPtr->keySize || \
113  capabilityInfoPtr->maxKeySize < capabilityInfoPtr->keySize )
114  return( FALSE );
115  if( isConvAlgo( cryptAlgo ) )
116  {
117  if( ( capabilityInfoPtr->blockSize < bitsToBytes( 8 ) || \
118  capabilityInfoPtr->blockSize > CRYPT_MAX_IVSIZE ) || \
119  ( capabilityInfoPtr->minKeySize < MIN_KEYSIZE || \
120  capabilityInfoPtr->maxKeySize > CRYPT_MAX_KEYSIZE ) )
121  return( FALSE );
122  if( capabilityInfoPtr->keySize > MAX_WORKING_KEYSIZE )
123  return( FALSE ); /* Requirement for key wrap */
124  if( capabilityInfoPtr->initParamsFunction == NULL || \
125  capabilityInfoPtr->initKeyFunction == NULL )
126  return( FALSE );
127  if( !isStreamCipher( cryptAlgo ) && \
128  capabilityInfoPtr->blockSize < bitsToBytes( 64 ) )
129  return( FALSE );
130  if( ( capabilityInfoPtr->encryptCBCFunction != NULL && \
131  capabilityInfoPtr->decryptCBCFunction == NULL ) || \
132  ( capabilityInfoPtr->encryptCBCFunction == NULL && \
133  capabilityInfoPtr->decryptCBCFunction != NULL ) )
134  return( FALSE );
135  if( ( capabilityInfoPtr->encryptCFBFunction != NULL && \
136  capabilityInfoPtr->decryptCFBFunction == NULL ) || \
137  ( capabilityInfoPtr->encryptCFBFunction == NULL && \
138  capabilityInfoPtr->decryptCFBFunction != NULL ) )
139  return( FALSE );
140  if( ( capabilityInfoPtr->encryptOFBFunction != NULL && \
141  capabilityInfoPtr->decryptOFBFunction == NULL ) || \
142  ( capabilityInfoPtr->encryptOFBFunction == NULL && \
143  capabilityInfoPtr->decryptOFBFunction != NULL ) )
144  return( FALSE );
145  if( ( capabilityInfoPtr->encryptGCMFunction != NULL && \
146  capabilityInfoPtr->decryptGCMFunction == NULL ) || \
147  ( capabilityInfoPtr->encryptGCMFunction == NULL && \
148  capabilityInfoPtr->decryptGCMFunction != NULL ) )
149  return( FALSE );
150 
151  return( TRUE );
152  }
153 
154  /* We've checked the conventional algorithms, beyond this point there
155  shouldn't be any conventional encryption modes present */
156  if( capabilityInfoPtr->encryptCBCFunction != NULL || \
157  capabilityInfoPtr->decryptCBCFunction != NULL || \
158  capabilityInfoPtr->encryptCFBFunction != NULL || \
159  capabilityInfoPtr->decryptCFBFunction != NULL || \
160  capabilityInfoPtr->encryptOFBFunction != NULL || \
161  capabilityInfoPtr->decryptOFBFunction != NULL || \
162  capabilityInfoPtr->encryptGCMFunction != NULL || \
163  capabilityInfoPtr->decryptGCMFunction != NULL )
164  return( FALSE );
165 
166  /* Check any remaining algorithm types */
167  if( isPkcAlgo( cryptAlgo ) )
168  {
169  const int minKeySize = isEccAlgo( cryptAlgo ) ? \
170  MIN_PKCSIZE_ECC : MIN_PKCSIZE;
171 
172  if( capabilityInfoPtr->blockSize != 0 || \
173  ( capabilityInfoPtr->minKeySize < minKeySize || \
174  capabilityInfoPtr->maxKeySize > CRYPT_MAX_PKCSIZE ) )
175  return( FALSE );
176  if( capabilityInfoPtr->initKeyFunction == NULL || \
177  capabilityInfoPtr->generateKeyFunction == NULL )
178  return( FALSE );
179 
180  return( TRUE );
181  }
182  if( isHashAlgo( cryptAlgo ) )
183  {
184  if( ( capabilityInfoPtr->blockSize < bitsToBytes( 128 ) || \
185  capabilityInfoPtr->blockSize > CRYPT_MAX_HASHSIZE ) || \
186  ( capabilityInfoPtr->minKeySize != 0 || \
187  capabilityInfoPtr->keySize != 0 || \
188  capabilityInfoPtr->maxKeySize != 0 ) )
189  return( FALSE );
190 
191  return( TRUE );
192  }
193  if( isMacAlgo( cryptAlgo ) )
194  {
195  if( ( capabilityInfoPtr->blockSize < bitsToBytes( 128 ) || \
196  capabilityInfoPtr->blockSize > CRYPT_MAX_HASHSIZE ) || \
197  ( capabilityInfoPtr->minKeySize < MIN_KEYSIZE || \
198  capabilityInfoPtr->maxKeySize > CRYPT_MAX_KEYSIZE ) )
199  return( FALSE );
200  if( capabilityInfoPtr->keySize > MAX_WORKING_KEYSIZE )
201  return( FALSE ); /* Requirement for key wrap */
202  if( capabilityInfoPtr->initKeyFunction == NULL )
203  return( FALSE );
204 
205  return( TRUE );
206  }
207  if( isSpecialAlgo( cryptAlgo ) )
208  {
209  if( capabilityInfoPtr->blockSize != 0 || \
210  capabilityInfoPtr->minKeySize < bitsToBytes( 128 ) || \
211  capabilityInfoPtr->maxKeySize > CRYPT_MAX_KEYSIZE )
212  return( FALSE );
213  if( capabilityInfoPtr->encryptFunction != NULL || \
214  capabilityInfoPtr->decryptFunction != NULL )
215  return( FALSE );
216  if( capabilityInfoPtr->initKeyFunction == NULL )
217  return( FALSE );
218 
219  return( TRUE );
220  }
221 
223  }
224 
225 /* Get information from a capability record */
226 
227 STDC_NONNULL_ARG( ( 1, 2 ) ) \
228 void getCapabilityInfo( OUT CRYPT_QUERY_INFO *cryptQueryInfo,
230  {
231  assert( isWritePtr( cryptQueryInfo, sizeof( CRYPT_QUERY_INFO ) ) );
232  assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) );
233 
234  memset( cryptQueryInfo, 0, sizeof( CRYPT_QUERY_INFO ) );
235  memcpy( cryptQueryInfo->algoName, capabilityInfoPtr->algoName,
236  capabilityInfoPtr->algoNameLen );
237  cryptQueryInfo->algoName[ capabilityInfoPtr->algoNameLen ] = '\0';
238  cryptQueryInfo->blockSize = capabilityInfoPtr->blockSize;
239  cryptQueryInfo->minKeySize = capabilityInfoPtr->minKeySize;
240  cryptQueryInfo->keySize = capabilityInfoPtr->keySize;
241  cryptQueryInfo->maxKeySize = capabilityInfoPtr->maxKeySize;
242  }
243 
244 /* Find the capability record for a given encryption algorithm */
245 
247 const CAPABILITY_INFO FAR_BSS *findCapabilityInfo(
248  const CAPABILITY_INFO_LIST *capabilityInfoList,
250  {
251  const CAPABILITY_INFO_LIST *capabilityInfoListPtr;
252  int iterationCount;
253 
254  assert( isReadPtr( capabilityInfoList, sizeof( CAPABILITY_INFO ) ) );
255 
256  /* Find the capability corresponding to the requested algorithm/mode */
257  for( capabilityInfoListPtr = capabilityInfoList, iterationCount = 0;
258  capabilityInfoListPtr != NULL && iterationCount < FAILSAFE_ITERATIONS_MED;
259  capabilityInfoListPtr = capabilityInfoListPtr->next, iterationCount++ )
260  {
261  if( capabilityInfoListPtr->info->cryptAlgo == cryptAlgo )
262  return( capabilityInfoListPtr->info );
263  }
264  ENSURES_N( iterationCount < FAILSAFE_ITERATIONS_MED );
265 
266  return( NULL );
267  }
268 
269 /****************************************************************************
270 * *
271 * Shared Context Functions *
272 * *
273 ****************************************************************************/
274 
275 /* Default handler to get object subtype-specific information. This
276  fallback function is called if the object-specific primary get-info
277  handler doesn't want to handle the query */
278 
280 int getDefaultInfo( IN_ENUM( CAPABILITY_INFO ) const CAPABILITY_INFO_TYPE type,
282  OUT void *data,
283  IN_INT_Z const int length )
284 
285  {
286  assert( contextInfoPtr == NULL || \
287  isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
288  assert( ( length == 0 && isWritePtr( data, sizeof( int ) ) ) || \
289  ( length > 0 && isWritePtr( data, length ) ) );
290 
292 
293  switch( type )
294  {
296  {
297  int *valuePtr = ( int * ) data;
298 
299  /* If we're falling through to a default handler for this then
300  it's because the context has no state information */
301  *valuePtr = 0;
302 
303  return( CRYPT_OK );
304  }
305 
307  {
308  int *valuePtr = ( int * ) data;
309 
310  /* Default alignment for the algorithm-specific state data is
311  64 bits */
312  *valuePtr = 8;
313 
314  return( CRYPT_OK );
315  }
316  }
317 
318  retIntError();
319  }
320 
321 /****************************************************************************
322 * *
323 * Bignum Support Routines *
324 * *
325 ****************************************************************************/
326 
327 #ifdef USE_PKC
328 
329 /* Clear temporary bignum values used during PKC operations */
330 
331 STDC_NONNULL_ARG( ( 1 ) ) \
332 void clearTempBignums( INOUT PKC_INFO *pkcInfo )
333  {
334  assert( isWritePtr( pkcInfo, sizeof( PKC_INFO ) ) );
335 
336  BN_clear( &pkcInfo->tmp1 );
337  BN_clear( &pkcInfo->tmp2 );
338  BN_clear( &pkcInfo->tmp3 );
339 #if defined( USE_ECDH ) || defined( USE_ECDSA )
340  if( pkcInfo->isECC )
341  {
342  BN_clear( &pkcInfo->tmp4 );
343  BN_clear( &pkcInfo->tmp5 );
344  }
345 #endif /* USE_ECDH || USE_ECDSA */
346  BN_CTX_clear( pkcInfo->bnCTX );
347  }
348 
349 /* Initialse and free the bignum information in a context */
350 
352 int initContextBignums( INOUT PKC_INFO *pkcInfo,
353  IN_RANGE( 0, 3 ) const int sideChannelProtectionLevel,
354  const BOOLEAN isECC )
355  {
356  BN_CTX *bnCTX;
357 
358  assert( isWritePtr( pkcInfo, sizeof( PKC_INFO ) ) );
359 
360  REQUIRES( sideChannelProtectionLevel >= 0 && \
361  sideChannelProtectionLevel <= 3 );
362 
363  /* Perform any required memory allocations */
364  bnCTX = BN_CTX_new();
365  if( bnCTX == NULL )
366  return( CRYPT_ERROR_MEMORY );
367 
368  /* Initialise the bignum information */
369  BN_init( &pkcInfo->param1 );
370  BN_init( &pkcInfo->param2 );
371  BN_init( &pkcInfo->param3 );
372  BN_init( &pkcInfo->param4 );
373  BN_init( &pkcInfo->param5 );
374  BN_init( &pkcInfo->param6 );
375  BN_init( &pkcInfo->param7 );
376  BN_init( &pkcInfo->param8 );
377  if( sideChannelProtectionLevel > 0 )
378  {
379  BN_init( &pkcInfo->blind1 );
380  BN_init( &pkcInfo->blind2 );
381  }
382  BN_init( &pkcInfo->tmp1 );
383  BN_init( &pkcInfo->tmp2 );
384  BN_init( &pkcInfo->tmp3 );
385 #if defined( USE_ECDH ) || defined( USE_ECDSA )
386  if( isECC )
387  {
388  pkcInfo->isECC = TRUE;
389  BN_init( &pkcInfo->tmp4 );
390  BN_init( &pkcInfo->tmp5 );
391  pkcInfo->ecCTX = EC_GROUP_new( EC_GFp_simple_method() );
392  pkcInfo->ecPoint = EC_POINT_new( pkcInfo->ecCTX );
393  pkcInfo->tmpPoint = EC_POINT_new( pkcInfo->ecCTX );
394  if( pkcInfo->ecCTX == NULL || pkcInfo->ecPoint == NULL || \
395  pkcInfo->tmpPoint == NULL )
396  {
397  if( pkcInfo->tmpPoint != NULL )
398  EC_POINT_free( pkcInfo->tmpPoint );
399  if( pkcInfo->ecPoint != NULL )
400  EC_POINT_free( pkcInfo->ecPoint );
401  if( pkcInfo->ecCTX != NULL )
402  EC_GROUP_free( pkcInfo->ecCTX );
403  BN_CTX_free( bnCTX );
404  return( CRYPT_ERROR_MEMORY );
405  }
406  }
407 #endif /* USE_ECDH || USE_ECDSA */
408  pkcInfo->bnCTX = bnCTX;
409  BN_MONT_CTX_init( &pkcInfo->montCTX1 );
410  BN_MONT_CTX_init( &pkcInfo->montCTX2 );
411  BN_MONT_CTX_init( &pkcInfo->montCTX3 );
412 
413  return( CRYPT_OK );
414  }
415 
416 STDC_NONNULL_ARG( ( 1 ) ) \
417 void freeContextBignums( INOUT PKC_INFO *pkcInfo,
418  IN_FLAGS( CONTEXT ) const int contextFlags )
419  {
420  assert( isWritePtr( pkcInfo, sizeof( PKC_INFO ) ) );
421 
422  REQUIRES_V( contextFlags >= CONTEXT_FLAG_NONE && \
423  contextFlags <= CONTEXT_FLAG_MAX );
424 
425  if( !( contextFlags & CONTEXT_FLAG_DUMMY ) )
426  {
427  BN_clear_free( &pkcInfo->param1 );
428  BN_clear_free( &pkcInfo->param2 );
429  BN_clear_free( &pkcInfo->param3 );
430  BN_clear_free( &pkcInfo->param4 );
431  BN_clear_free( &pkcInfo->param5 );
432  BN_clear_free( &pkcInfo->param6 );
433  BN_clear_free( &pkcInfo->param7 );
434  BN_clear_free( &pkcInfo->param8 );
435  if( contextFlags & CONTEXT_FLAG_SIDECHANNELPROTECTION )
436  {
437  BN_clear_free( &pkcInfo->blind1 );
438  BN_clear_free( &pkcInfo->blind2 );
439  }
440  BN_clear_free( &pkcInfo->tmp1 );
441  BN_clear_free( &pkcInfo->tmp2 );
442  BN_clear_free( &pkcInfo->tmp3 );
443 #if defined( USE_ECDH ) || defined( USE_ECDSA )
444  if( pkcInfo->isECC )
445  {
446  BN_clear_free( &pkcInfo->tmp4 );
447  BN_clear_free( &pkcInfo->tmp5 );
448  EC_POINT_free( pkcInfo->tmpPoint );
449  EC_POINT_free( pkcInfo->ecPoint );
450  EC_GROUP_free( pkcInfo->ecCTX );
451  }
452 #endif /* USE_ECDH || USE_ECDSA */
453  BN_MONT_CTX_free( &pkcInfo->montCTX1 );
454  BN_MONT_CTX_free( &pkcInfo->montCTX2 );
455  BN_MONT_CTX_free( &pkcInfo->montCTX3 );
456  BN_CTX_free( pkcInfo->bnCTX );
457  }
458  if( pkcInfo->publicKeyInfo != NULL )
459  clFree( "contextMessageFunction", pkcInfo->publicKeyInfo );
460  }
461 
462 /* Calculate a key checksum */
463 
465 int calculateBignumChecksum( INOUT PKC_INFO *pkcInfo,
466  IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo )
467  {
468  BN_ULONG checksum = 0L;
469 
470  assert( isWritePtr( pkcInfo, sizeof( PKC_INFO ) ) );
471 
472  REQUIRES( isPkcAlgo( cryptAlgo ) );
473 
474  /* Calculate the key data checksum */
475 #if defined( USE_ECDH ) || defined( USE_ECDSA )
476  if( isEccAlgo( cryptAlgo ) )
477  {
478  BN_checksum( &pkcInfo->eccParam_p, &checksum );
479  BN_checksum( &pkcInfo->eccParam_a, &checksum );
480  BN_checksum( &pkcInfo->eccParam_b, &checksum );
481  BN_checksum( &pkcInfo->eccParam_gx, &checksum );
482  BN_checksum( &pkcInfo->eccParam_gy, &checksum );
483  BN_checksum( &pkcInfo->eccParam_n, &checksum );
484  BN_checksum( &pkcInfo->eccParam_h, &checksum );
485  BN_checksum( &pkcInfo->eccParam_qx, &checksum );
486  BN_checksum( &pkcInfo->eccParam_qy, &checksum );
487  BN_checksum( &pkcInfo->eccParam_d, &checksum );
488  BN_checksum( &pkcInfo->eccParam_mont_p.RR, &checksum );
489  BN_checksum( &pkcInfo->eccParam_mont_p.N, &checksum );
490  BN_checksum( &pkcInfo->eccParam_mont_p.Ni, &checksum );
491  BN_checksum( &pkcInfo->eccParam_mont_n.RR, &checksum );
492  BN_checksum( &pkcInfo->eccParam_mont_n.N, &checksum );
493  BN_checksum( &pkcInfo->eccParam_mont_n.Ni, &checksum );
494  }
495  else
496 #endif /* USE_ECDH || USE_ECDSA */
497  if( isDlpAlgo( cryptAlgo ) )
498  {
499  BN_checksum( &pkcInfo->dlpParam_p, &checksum );
500  BN_checksum( &pkcInfo->dlpParam_g, &checksum );
501  BN_checksum( &pkcInfo->dlpParam_q, &checksum );
502  BN_checksum( &pkcInfo->dlpParam_y, &checksum );
503  BN_checksum( &pkcInfo->dlpParam_x, &checksum );
504  BN_checksum( &pkcInfo->dlpParam_mont_p.RR, &checksum );
505  BN_checksum( &pkcInfo->dlpParam_mont_p.N, &checksum );
506  BN_checksum( &pkcInfo->dlpParam_mont_p.Ni, &checksum );
507  }
508  else
509  {
510  BN_checksum( &pkcInfo->rsaParam_n, &checksum );
511  BN_checksum( &pkcInfo->rsaParam_e, &checksum );
512  BN_checksum( &pkcInfo->rsaParam_d, &checksum );
513  BN_checksum( &pkcInfo->rsaParam_p, &checksum );
514  BN_checksum( &pkcInfo->rsaParam_q, &checksum );
515  BN_checksum( &pkcInfo->rsaParam_u, &checksum );
516  BN_checksum( &pkcInfo->rsaParam_exponent1, &checksum );
517  BN_checksum( &pkcInfo->rsaParam_exponent2, &checksum );
518  BN_checksum( &pkcInfo->rsaParam_mont_n.RR, &checksum );
519  BN_checksum( &pkcInfo->rsaParam_mont_n.N, &checksum );
520  BN_checksum( &pkcInfo->rsaParam_mont_n.Ni, &checksum );
521  BN_checksum( &pkcInfo->rsaParam_mont_p.RR, &checksum );
522  BN_checksum( &pkcInfo->rsaParam_mont_p.N, &checksum );
523  BN_checksum( &pkcInfo->rsaParam_mont_p.Ni, &checksum );
524  BN_checksum( &pkcInfo->rsaParam_mont_q.RR, &checksum );
525  BN_checksum( &pkcInfo->rsaParam_mont_q.N, &checksum );
526  BN_checksum( &pkcInfo->rsaParam_mont_q.Ni, &checksum );
527  }
528 
529  /* Set or update the checksum */
530  if( pkcInfo->checksum == 0L )
531  {
532  pkcInfo->checksum = checksum;
533  return( CRYPT_OK );
534  }
535  return( ( pkcInfo->checksum == checksum ) ? CRYPT_OK : CRYPT_ERROR );
536  }
537 
538 /* Convert a byte string to and from a BIGNUM value */
539 
541 static int checkBignum( const BIGNUM *bignum,
542  IN_LENGTH_PKC const int minLength,
543  IN_LENGTH_PKC const int maxLength,
544  IN_OPT const BIGNUM *maxRange,
545  IN_ENUM_OPT( KEYSIZE_CHECK ) \
546  const KEYSIZE_CHECK_TYPE checkType )
547  {
548  BN_ULONG bnWord;
549  int bignumLength;
550 
551  assert( isReadPtr( bignum, sizeof( BIGNUM ) ) );
552  assert( maxRange == NULL || isReadPtr( maxRange, sizeof( BIGNUM ) ) );
553 
554  REQUIRES( minLength > 0 && minLength <= maxLength && \
555  maxLength <= CRYPT_MAX_PKCSIZE + \
556  ( ( checkType == KEYSIZE_CHECK_SPECIAL ) ? \
557  DLP_OVERFLOW_SIZE : 0 ) );
558  REQUIRES( checkType >= KEYSIZE_CHECK_NONE && \
559  checkType < KEYSIZE_CHECK_LAST_SPECIAL );
560 
561  /* The following should never happen because BN_bin2bn() works with
562  unsigned values but we perform the check anyway just in case someone
563  messes with the underlying bignum code */
564  ENSURES( !( BN_is_negative( bignum ) ) )
565 
566  /* A zero- or one-valued bignum on the other hand is an error because we
567  should never find zero or one in a PKC-related value. This check is
568  somewhat redundant with the one that follows, we place it here to
569  make it explicit and because the cost is near zero */
570  bnWord = BN_get_word( bignum );
571  if( bnWord < BN_MASK2 && bnWord <= 1 )
572  return( CRYPT_ERROR_BADDATA );
573 
574  /* Check that the bignum value falls within the allowed length range.
575  Before we do the general length check we perform a more specific
576  check for the case where the length is below the minimum allowed but
577  still looks at least vaguely valid, in which case we report it as a
578  too-short key rather than a bad data error */
579  bignumLength = BN_num_bytes( bignum );
580  switch( checkType )
581  {
582  case KEYSIZE_CHECK_NONE:
583  /* No specific weak-key check for this value */
584  break;
585 
586  case KEYSIZE_CHECK_PKC:
587  if( isShortPKCKey( bignumLength ) )
588  return( CRYPT_ERROR_NOSECURE );
589  break;
590 
591  case KEYSIZE_CHECK_ECC:
592  if( isShortECCKey( bignumLength ) )
593  return( CRYPT_ERROR_NOSECURE );
594  break;
595 
597  /* This changes the upper bound of the check rather than the
598  lower bound so there's no special check required */
599  break;
600 
601  default:
602  retIntError();
603  }
604  if( bignumLength < minLength || bignumLength > maxLength )
605  return( CRYPT_ERROR_BADDATA );
606 
607  /* Finally, if the caller has supplied a maximum-range bignum value,
608  make sure that the value that we've read is less than this */
609  if( maxRange != NULL && BN_cmp( bignum, maxRange ) >= 0 )
610  return( CRYPT_ERROR_BADDATA );
611 
612  return( CRYPT_OK );
613  }
614 
615 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
616 int importBignum( INOUT TYPECAST( BIGNUM * ) void *bignumPtr,
617  IN_BUFFER( length ) const void *buffer,
618  IN_LENGTH_SHORT const int length,
619  IN_LENGTH_PKC const int minLength,
620  IN_LENGTH_PKC const int maxLength,
621  IN_OPT const void *maxRangePtr,
622  IN_ENUM_OPT( KEYSIZE_CHECK ) \
623  const KEYSIZE_CHECK_TYPE checkType )
624  {
625  BIGNUM *bignum = ( BIGNUM * ) bignumPtr;
626  BIGNUM *maxRange = ( BIGNUM * ) maxRangePtr;
627 
628  assert( isWritePtr( bignum, sizeof( BIGNUM ) ) );
629  assert( isReadPtr( buffer, length ) );
630  assert( maxRange == NULL || isReadPtr( maxRange, sizeof( BIGNUM ) ) );
631 
632  REQUIRES( minLength > 0 && minLength <= maxLength && \
633  maxLength <= CRYPT_MAX_PKCSIZE + \
634  ( ( checkType == KEYSIZE_CHECK_SPECIAL ) ? \
635  DLP_OVERFLOW_SIZE : 0 ) );
636  REQUIRES( checkType >= KEYSIZE_CHECK_NONE && \
637  checkType < KEYSIZE_CHECK_LAST_SPECIAL );
638 
639  /* Make sure that we've been given valid input. This should have been
640  checked by the caller anyway using far more specific checks than the
641  very generic values that we use here, but we perform the check anyway
642  just to be sure */
643  if( length < 1 )
644  return( CRYPT_ERROR_BADDATA );
645  if( checkType == KEYSIZE_CHECK_SPECIAL )
646  {
647  if( length > CRYPT_MAX_PKCSIZE + DLP_OVERFLOW_SIZE )
648  return( CRYPT_ERROR_BADDATA );
649  }
650  else
651  {
652  if( length > CRYPT_MAX_PKCSIZE )
653  return( CRYPT_ERROR_BADDATA );
654  }
655 
656  /* Convert the byte string into a bignum */
657  if( BN_bin2bn( buffer, length, bignum ) == NULL )
658  return( CRYPT_ERROR_MEMORY );
659 
660  /* Check the value that we've just imported */
661  return( checkBignum( bignum, minLength, maxLength, maxRange,
662  checkType ) );
663  }
664 
665 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
666 int exportBignum( OUT_BUFFER( dataMaxLength, *dataLength ) void *data,
667  IN_LENGTH_SHORT_MIN( 16 ) const int dataMaxLength,
669  IN TYPECAST( BIGNUM * ) const void *bignumPtr )
670  {
671  BIGNUM *bignum = ( BIGNUM * ) bignumPtr;
672  int length, result;
673 
674  assert( isWritePtr( data, dataMaxLength ) );
675  assert( isWritePtr( dataLength, sizeof( int ) ) );
676  assert( isReadPtr( bignum, sizeof( BIGNUM ) ) );
677 
678  REQUIRES( dataMaxLength >= 16 && dataMaxLength < MAX_INTLENGTH_SHORT );
679 
680  /* Clear return values */
681  memset( data, 0, min( 16, dataMaxLength ) );
682  *dataLength = 0;
683 
684  /* Make sure that the result will fit into the output buffer */
685  length = BN_num_bytes( bignum );
686  ENSURES( length > 0 && length <= CRYPT_MAX_PKCSIZE );
687 
688  /* Export the bignum into the output buffer */
689  result = BN_bn2bin( bignum, data );
690  ENSURES( result == length );
691  *dataLength = length;
692 
693  return( CRYPT_OK );
694  }
695 
696 #if defined( USE_ECDH ) || defined( USE_ECDSA )
697 
698 /* Convert a byte string to and from an ECC point */
699 
700 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
701 int importECCPoint( INOUT TYPECAST( BIGNUM * ) void *bignumPtr1,
702  INOUT TYPECAST( BIGNUM * ) void *bignumPtr2,
703  IN_BUFFER( length ) const void *buffer,
704  IN_LENGTH_SHORT const int length,
705  IN_LENGTH_PKC const int minLength,
706  IN_LENGTH_PKC const int maxLength,
707  IN_LENGTH_PKC const int fieldSize,
708  IN_OPT const void *maxRangePtr,
709  IN_ENUM( KEYSIZE_CHECK ) \
710  const KEYSIZE_CHECK_TYPE checkType )
711  {
712  const BYTE *eccPointData = buffer;
713  BIGNUM *bignum1 = ( BIGNUM * ) bignumPtr1;
714  BIGNUM *bignum2 = ( BIGNUM * ) bignumPtr2;
715  BIGNUM *maxRange = ( BIGNUM * ) maxRangePtr;
716  int status;
717 
718  assert( isWritePtr( bignum1, sizeof( BIGNUM ) ) );
719  assert( isWritePtr( bignum2, sizeof( BIGNUM ) ) );
720  assert( isReadPtr( buffer, length ) );
721  assert( maxRange == NULL || isReadPtr( maxRange, sizeof( BIGNUM ) ) );
722 
723  REQUIRES( minLength > 0 && minLength <= maxLength && \
724  maxLength <= CRYPT_MAX_PKCSIZE_ECC );
725  REQUIRES( fieldSize >= MIN_PKCSIZE_ECC && \
726  fieldSize <= CRYPT_MAX_PKCSIZE_ECC );
727  REQUIRES( checkType >= KEYSIZE_CHECK_NONE && \
728  checkType < KEYSIZE_CHECK_LAST );
729 
730  /* Make sure that we've been given valid input. This should have been
731  checked by the caller anyway using far more specific checks than the
732  very generic values that we use here, but we perform the check anyway
733  just to be sure */
734  if( length < MIN_PKCSIZE_ECCPOINT_THRESHOLD || \
735  length > MAX_PKCSIZE_ECCPOINT )
736  return( CRYPT_ERROR_BADDATA );
737 
738  /* Decode the ECC point data. At this point we run into another
739  artefact of the chronic indecisiveness of the ECC standards authors,
740  because of the large variety of ways in which ECC data can be encoded
741  there's no single way of representing a point. The only encoding
742  that's actually of any practical use is the straight (x, y)
743  coordinate form with no special-case encoding or other tricks,
744  denoted by an 0x04 byte at the start of the data:
745 
746  +---+---------------+---------------+
747  |ID | qx | qy |
748  +---+---------------+---------------+
749  |<- fldSize --> |<- fldSize --> |
750 
751  There's also a hybrid form that combines the patent encumbrance of
752  point compression with the size of the uncompressed form that we
753  could in theory allow for, but it's unlikely that anyone's going to
754  be crazy enough to use this */
755  if( length != ( fieldSize * 2 ) + 1 )
756  return( CRYPT_ERROR_BADDATA );
757  if( eccPointData[ 0 ] != 0x04 )
758  return( CRYPT_ERROR_BADDATA );
759  status = importBignum( bignum1, eccPointData + 1, fieldSize,
760  minLength, maxLength, maxRange, checkType );
761  if( cryptStatusError( status ) )
762  return( status );
763  return( importBignum( bignum2, eccPointData + 1 + fieldSize,
764  fieldSize, minLength, maxLength, maxRange,
765  checkType ) );
766  }
767 
768 CHECK_RETVAL STDC_NONNULL_ARG( ( 3, 4, 5) ) \
769 int exportECCPoint( OUT_BUFFER_OPT( dataMaxLength, *dataLength ) void *data,
770  IN_LENGTH_SHORT_Z const int dataMaxLength,
771  OUT_LENGTH_SHORT_Z int *dataLength,
772  IN TYPECAST( BIGNUM * ) const void *bignumPtr1,
773  IN TYPECAST( BIGNUM * ) const void *bignumPtr2,
774  IN_LENGTH_PKC const int fieldSize )
775  {
776  BIGNUM *bignum1 = ( BIGNUM * ) bignumPtr1;
777  BIGNUM *bignum2 = ( BIGNUM * ) bignumPtr2;
778  BYTE *bufPtr = data;
779  int length, result;
780 
781  assert( data == NULL || isWritePtr( data, dataMaxLength ) );
782  assert( isWritePtr( dataLength, sizeof( int ) ) );
783  assert( isReadPtr( bignum1, sizeof( BIGNUM ) ) );
784  assert( isReadPtr( bignum2, sizeof( BIGNUM ) ) );
785 
786  REQUIRES( ( data == NULL && dataMaxLength == 0 ) || \
787  ( data != NULL && \
788  dataMaxLength >= 16 && \
789  dataMaxLength < MAX_INTLENGTH_SHORT ) );
790  REQUIRES( fieldSize >= MIN_PKCSIZE_ECC && \
791  fieldSize <= CRYPT_MAX_PKCSIZE_ECC );
792 
793  /* Clear return values */
794  if( data != NULL )
795  memset( data, 0, min( 16, dataMaxLength ) );
796  *dataLength = 0;
797 
798  /* If it's just an encoding-length check there's nothing to do */
799  if( data == NULL )
800  {
801  *dataLength = 1 + ( fieldSize * 2 );
802  return( CRYPT_OK );
803  }
804 
805  /* Encode the ECC point data, which consists of the Q coordinates
806  stuffed into a byte string with an encoding-specifier byte 0x04 at
807  the start:
808 
809  +---+---------------+---------------+
810  |ID | qx | qy |
811  +---+---------------+---------------+
812  |<-- fldSize -> |<- fldSize --> | */
813  if( dataMaxLength < 1 + ( fieldSize * 2 ) )
814  return( CRYPT_ERROR_OVERFLOW );
815  *bufPtr++ = 0x04;
816  memset( bufPtr, 0, fieldSize * 2 );
817  length = BN_num_bytes( bignum1 );
818  ENSURES( length > 0 && length <= fieldSize );
819  result = BN_bn2bin( bignum1, bufPtr + ( fieldSize - length ) );
820  ENSURES( result == length );
821  bufPtr += fieldSize;
822  length = BN_num_bytes( bignum2 );
823  ENSURES( length > 0 && length <= fieldSize );
824  result = BN_bn2bin( bignum2, bufPtr + ( fieldSize - length ) );
825  ENSURES( result == length );
826  *dataLength = 1 + ( fieldSize * 2 );
827 
828  return( CRYPT_OK );
829  }
830 #endif /* USE_ECDH || USE_ECDSA */
831 
832 #else
833 
834 STDC_NONNULL_ARG( ( 1 ) ) \
835 void clearTempBignums( INOUT PKC_INFO *pkcInfo )
836  {
837  }
839 int initContextBignums( INOUT PKC_INFO *pkcInfo,
840  IN_RANGE( 0, 3 ) const int sideChannelProtectionLevel )
841  {
842  }
843 STDC_NONNULL_ARG( ( 1 ) ) \
844 void freeContextBignums( INOUT PKC_INFO *pkcInfo,
845  IN_FLAGS( CONTEXT ) const int contextFlags )
846  {
847  }
848 #endif /* USE_PKC */
849 
850 /****************************************************************************
851 * *
852 * Self-test Support Functions *
853 * *
854 ****************************************************************************/
855 
856 /* Statically initialise a context for the internal self-test and a few
857  other internal-only functions such as when generating keyIDs for raw
858  encoded key data where no context is available */
859 
861 int staticInitContext( OUT CONTEXT_INFO *contextInfoPtr,
864  OUT_BUFFER_FIXED( contextDataSize ) void *contextData,
865  IN_LENGTH_SHORT_MIN( 32 ) const int contextDataSize,
866  IN_OPT void *keyData )
867  {
868  int status;
869 
870  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
871  assert( isReadPtr( capabilityInfoPtr, sizeof( CAPABILITY_INFO ) ) );
872  assert( isReadPtr( contextData, contextDataSize ) );
873 
874  REQUIRES( type > CONTEXT_NONE && type < CONTEXT_LAST );
875  REQUIRES( contextDataSize >= 32 && \
876  contextDataSize < MAX_INTLENGTH_SHORT );
877 
878  memset( contextInfoPtr, 0, sizeof( CONTEXT_INFO ) );
879  memset( contextData, 0, contextDataSize );
880  contextInfoPtr->type = type;
881  contextInfoPtr->capabilityInfo = capabilityInfoPtr;
882  contextInfoPtr->flags = CONTEXT_FLAG_STATICCONTEXT;
883  switch( type )
884  {
885  case CONTEXT_CONV:
886  contextInfoPtr->ctxConv = ( CONV_INFO * ) contextData;
887  contextInfoPtr->ctxConv->key = keyData;
888  break;
889 
890  case CONTEXT_HASH:
891  contextInfoPtr->ctxHash = ( HASH_INFO * ) contextData;
892  contextInfoPtr->ctxHash->hashInfo = keyData;
893  break;
894 
895  case CONTEXT_MAC:
896  contextInfoPtr->ctxMAC = ( MAC_INFO * ) contextData;
897  contextInfoPtr->ctxMAC->macInfo = keyData;
898  break;
899 
900  case CONTEXT_PKC:
901  /* PKC context initialisation is a bit more complex because we
902  have to set up all of the bignum values as well. Since static
903  contexts are only used for self-test operations we set the
904  side-channel protection level to zero */
905  contextInfoPtr->ctxPKC = ( PKC_INFO * ) contextData;
906  status = initContextBignums( contextData, 0,
907  isEccAlgo( capabilityInfoPtr->cryptAlgo ) );
908  if( cryptStatusError( status ) )
909  return( status );
910  initKeyID( contextInfoPtr );
911  initKeyRead( contextInfoPtr );
912  initKeyWrite( contextInfoPtr ); /* For calcKeyID() */
913  break;
914 
915  default:
916  retIntError();
917  }
918 
919  return( CRYPT_OK );
920  }
921 
922 STDC_NONNULL_ARG( ( 1 ) ) \
923 void staticDestroyContext( INOUT CONTEXT_INFO *contextInfoPtr )
924  {
925  assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );
926 
927  ENSURES_V( contextInfoPtr->flags & CONTEXT_FLAG_STATICCONTEXT );
928 
929  if( contextInfoPtr->type == CONTEXT_PKC )
930  {
931  freeContextBignums( contextInfoPtr->ctxPKC,
932  ( contextInfoPtr->capabilityInfo->cryptAlgo == \
933  CRYPT_ALGO_RSA ) ? CONTEXT_FLAG_SIDECHANNELPROTECTION : 0 );
934  }
935  memset( contextInfoPtr, 0, sizeof( CONTEXT_INFO ) );
936  }
937 
938 /* Perform a self-test of a cipher, encrypting and decrypting one block of
939  data and comparing it to a fixed test value */
940 
941 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 5, 6 ) ) \
942 int testCipher( const CAPABILITY_INFO *capabilityInfo,
943  INOUT void *keyDataStorage,
944  IN_BUFFER( keySize ) const void *key,
946  const void *plaintext,
947  const void *ciphertext )
948  {
949  CONTEXT_INFO contextInfo;
950  CONV_INFO contextData;
951  BYTE temp[ CRYPT_MAX_IVSIZE + 8 ];
952  int status;
953 
954  assert( isReadPtr( capabilityInfo, sizeof( CAPABILITY_INFO ) ) );
955  assert( isWritePtr( keyDataStorage, 16 ) );
956  assert( isReadPtr( key, keySize ) );
957  assert( isReadPtr( plaintext, capabilityInfo->blockSize ) );
958  assert( isReadPtr( ciphertext, capabilityInfo->blockSize ) );
959 
960  REQUIRES( keySize >= MIN_KEYSIZE && keySize <= CRYPT_MAX_KEYSIZE );
961 
962  memcpy( temp, plaintext, capabilityInfo->blockSize );
963 
964  status = staticInitContext( &contextInfo, CONTEXT_CONV, capabilityInfo,
965  &contextData, sizeof( CONV_INFO ),
966  keyDataStorage );
967  if( cryptStatusError( status ) )
968  return( status );
969  status = capabilityInfo->initKeyFunction( &contextInfo, key, keySize );
970  if( cryptStatusOK( status ) )
971  status = capabilityInfo->encryptFunction( &contextInfo, temp,
972  capabilityInfo->blockSize );
973  if( cryptStatusOK( status ) && \
974  memcmp( ciphertext, temp, capabilityInfo->blockSize ) )
975  status = CRYPT_ERROR_FAILED;
976  if( cryptStatusOK( status ) )
977  status = capabilityInfo->decryptFunction( &contextInfo, temp,
978  capabilityInfo->blockSize );
979  staticDestroyContext( &contextInfo );
980  if( cryptStatusError( status ) || \
981  memcmp( plaintext, temp, capabilityInfo->blockSize ) )
982  return( CRYPT_ERROR_FAILED );
983 
984  return( CRYPT_OK );
985  }
986 
987 /* Perform a self-test of a hash or MAC */
988 
990 int testHash( const CAPABILITY_INFO *capabilityInfo,
991  INOUT void *hashDataStorage,
992  IN_BUFFER_OPT( dataLength ) const void *data,
993  IN_LENGTH_SHORT_Z const int dataLength,
994  const void *hashValue )
995  {
996  CONTEXT_INFO contextInfo;
997  HASH_INFO contextData;
998  int status;
999 
1000  assert( isReadPtr( capabilityInfo, sizeof( CAPABILITY_INFO ) ) );
1001  assert( isWritePtr( hashDataStorage, 16 ) );
1002  assert( ( data == NULL && dataLength == 0 ) || \
1003  isReadPtr( data, dataLength ) );
1004  assert( isReadPtr( hashValue, capabilityInfo->blockSize ) );
1005 
1006  REQUIRES( ( data == NULL && dataLength == 0 ) || \
1007  ( data != NULL && \
1008  dataLength > 0 && dataLength < MAX_INTLENGTH_SHORT ) );
1009 
1010  status = staticInitContext( &contextInfo, CONTEXT_HASH, capabilityInfo,
1011  &contextData, sizeof( HASH_INFO ),
1012  hashDataStorage );
1013  if( cryptStatusError( status ) )
1014  return( status );
1015  if( data != NULL )
1016  {
1017  /* Some of the test vector sets start out with empty strings so we
1018  only call the hash function if we've actually been fed data to
1019  hash */
1020  status = capabilityInfo->encryptFunction( &contextInfo,
1021  ( void * ) data,
1022  dataLength );
1023  contextInfo.flags |= CONTEXT_FLAG_HASH_INITED;
1024  }
1025  if( cryptStatusOK( status ) )
1026  status = capabilityInfo->encryptFunction( &contextInfo,
1027  MKDATA( "" ), 0 );
1028  if( cryptStatusOK( status ) && \
1029  memcmp( contextInfo.ctxHash->hash, hashValue,
1030  capabilityInfo->blockSize ) )
1031  status = CRYPT_ERROR_FAILED;
1032  staticDestroyContext( &contextInfo );
1033 
1034  return( status );
1035  }
1036 
1037 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 5, 7 ) ) \
1038 int testMAC( const CAPABILITY_INFO *capabilityInfo,
1039  INOUT void *macDataStorage,
1040  IN_BUFFER( keySize ) const void *key,
1041  IN_LENGTH_SHORT_MIN( MIN_KEYSIZE ) const int keySize,
1042  IN_BUFFER( dataLength ) const void *data,
1043  IN_LENGTH_SHORT_MIN( 8 ) const int dataLength,
1044  const void *hashValue )
1045  {
1046  CONTEXT_INFO contextInfo;
1047  MAC_INFO contextData;
1048  int status;
1049 
1050  assert( isReadPtr( capabilityInfo, sizeof( CAPABILITY_INFO ) ) );
1051  assert( isWritePtr( macDataStorage, 16 ) );
1052  assert( isReadPtr( key, keySize ) );
1053  assert( isReadPtr( data, dataLength ) );
1054  assert( isReadPtr( hashValue, capabilityInfo->blockSize ) );
1055 
1056  REQUIRES( keySize >= 4 && keySize < MAX_INTLENGTH_SHORT );
1057  REQUIRES( dataLength >= 8 && dataLength < MAX_INTLENGTH_SHORT );
1058 
1059  status = staticInitContext( &contextInfo, CONTEXT_MAC, capabilityInfo,
1060  &contextData, sizeof( MAC_INFO ),
1061  macDataStorage );
1062  if( cryptStatusError( status ) )
1063  return( status );
1064  status = capabilityInfo->initKeyFunction( &contextInfo, key, keySize );
1065  if( cryptStatusOK( status ) )
1066  {
1067  status = capabilityInfo->encryptFunction( &contextInfo,
1068  ( void * ) data,
1069  dataLength );
1070  contextInfo.flags |= CONTEXT_FLAG_HASH_INITED;
1071  }
1072  if( cryptStatusOK( status ) )
1073  status = capabilityInfo->encryptFunction( &contextInfo,
1074  MKDATA( "" ), 0 );
1075  if( cryptStatusOK( status ) && \
1076  memcmp( contextInfo.ctxMAC->mac, hashValue,
1077  capabilityInfo->blockSize ) )
1078  status = CRYPT_ERROR_FAILED;
1079  staticDestroyContext( &contextInfo );
1080 
1081  return( status );
1082  }
1083 
1084 /****************************************************************************
1085 * *
1086 * Hash External Access Functions *
1087 * *
1088 ****************************************************************************/
1089 
1090 /* Determine the parameters for a particular hash algorithm */
1091 
1092 typedef struct HI {
1094  const int hashSize;
1095  const HASHFUNCTION function;
1097 
1098 typedef struct HAI {
1100  const int hashSize;
1101  const HASHFUNCTION_ATOMIC function;
1103 
1104 STDC_NONNULL_ARG( ( 3 ) ) \
1105 void getHashParameters( IN_ALGO const CRYPT_ALGO_TYPE hashAlgorithm,
1106  IN_INT_SHORT_Z const int hashParam,
1109  {
1110  static const HASHFUNCTION_INFO FAR_BSS hashFunctions[] = {
1111 #ifdef USE_MD5
1112  { CRYPT_ALGO_MD5, MD5_DIGEST_LENGTH, md5HashBuffer },
1113 #endif /* USE_MD5 */
1114 #ifdef USE_RIPEMD160
1115  { CRYPT_ALGO_RIPEMD160, RIPEMD160_DIGEST_LENGTH, ripemd160HashBuffer },
1116 #endif /* USE_RIPEMD160 */
1118 #ifdef USE_SHA2
1119  { CRYPT_ALGO_SHA2, SHA256_DIGEST_SIZE, sha2HashBuffer },
1120  #ifdef USE_SHA2_EXT
1121  /* The extended SHA2 variants are only available on systems with 64-
1122  bit data type support */
1123  #if defined( CONFIG_SUITEB )
1124  { CRYPT_ALGO_SHA2, SHA384_DIGEST_SIZE, sha2_ExtHashBuffer },
1125  #else
1126  { CRYPT_ALGO_SHA2, SHA512_DIGEST_SIZE, sha2_ExtHashBuffer },
1127  #endif /* Suite B vs. generic use */
1128  #endif /* USE_SHA2_EXT */
1129 #endif /* USE_SHA2 */
1132  };
1133  int i;
1134 
1135  assert( isHashAlgo( hashAlgorithm ) );
1136  assert( hashParam >= 0 && hashParam < MAX_INTLENGTH_SHORT );
1137  /* We don't use REQUIRES() for this for the reason given in the
1138  comments below */
1139  assert( isWritePtr( hashFunction, sizeof( HASHFUNCTION ) ) );
1140  assert( ( hashOutputSize == NULL ) || \
1141  isWritePtr( hashOutputSize, sizeof( int ) ) );
1142 
1143  /* Find the information for the requested hash algorithm */
1144  for( i = 0; hashFunctions[ i ].cryptAlgo != CRYPT_ALGO_NONE && \
1145  i < FAILSAFE_ARRAYSIZE( hashFunctions, HASHFUNCTION_INFO );
1146  i++ )
1147  {
1148  /* If this isn't the algorithm that we're looking for, continue */
1149  if( hashFunctions[ i ].cryptAlgo != hashAlgorithm )
1150  continue;
1151 
1152  /* If we're looking for a specific hash-size match and this isn't
1153  it, continue */
1154  if( hashParam != 0 && hashFunctions[ i ].hashSize != hashParam )
1155  continue;
1156 
1157  /* We've found what we're after */
1158  break;
1159  }
1160  if( i >= FAILSAFE_ARRAYSIZE( hashFunctions, HASHFUNCTION_INFO ) || \
1161  hashFunctions[ i ].cryptAlgo == CRYPT_ALGO_NONE )
1162  {
1163  /* Make sure that we always get some sort of hash function rather
1164  than just dying. This code always works because the internal
1165  self-test has confirmed the availability and functioning of SHA-1
1166  on startup */
1167  *hashFunction = shaHashBuffer;
1168  if( hashOutputSize != NULL )
1169  *hashOutputSize = SHA_DIGEST_LENGTH;
1170  retIntError_Void();
1171  }
1172 
1173  *hashFunction = hashFunctions[ i ].function;
1174  if( hashOutputSize != NULL )
1175  *hashOutputSize = hashFunctions[ i ].hashSize;
1176  }
1177 
1178 STDC_NONNULL_ARG( ( 3 ) ) \
1179 void getHashAtomicParameters( IN_ALGO const CRYPT_ALGO_TYPE hashAlgorithm,
1180  IN_INT_SHORT_Z const int hashParam,
1181  OUT_PTR HASHFUNCTION_ATOMIC *hashFunctionAtomic,
1182  OUT_OPT_LENGTH_SHORT_Z int *hashOutputSize )
1183  {
1184  static const HASHFUNCTION_ATOMIC_INFO FAR_BSS hashFunctions[] = {
1185 #ifdef USE_MD5
1186  { CRYPT_ALGO_MD5, MD5_DIGEST_LENGTH, md5HashBufferAtomic },
1187 #endif /* USE_MD5 */
1188 #ifdef USE_RIPEMD160
1189  { CRYPT_ALGO_RIPEMD160, RIPEMD160_DIGEST_LENGTH, ripemd160HashBufferAtomic },
1190 #endif /* USE_RIPEMD160 */
1192 #ifdef USE_SHA2
1193  { CRYPT_ALGO_SHA2, SHA256_DIGEST_SIZE, sha2HashBufferAtomic },
1194  #ifdef USE_SHA2_EXT
1195  /* The extended SHA2 variants are only available on systems with 64-
1196  bit data type support */
1197  #if defined( CONFIG_SUITEB )
1198  { CRYPT_ALGO_SHA2, SHA384_DIGEST_SIZE, sha2_ExtHashBufferAtomic },
1199  #else
1200  { CRYPT_ALGO_SHA2, SHA512_DIGEST_SIZE, sha2_ExtHashBufferAtomic },
1201  #endif /* Suite B vs. generic use */
1202  #endif /* USE_SHA2_EXT */
1203 #endif /* USE_SHA2 */
1206  };
1207  int i;
1208 
1209  assert( isHashAlgo( hashAlgorithm ) );
1210  assert( hashParam >= 0 && hashParam < MAX_INTLENGTH_SHORT );
1211  /* We don't use REQUIRES() for this for the reason given in the
1212  comments below */
1213  assert( isWritePtr( hashFunctionAtomic, sizeof( HASHFUNCTION_ATOMIC ) ) );
1214  assert( ( hashOutputSize == NULL ) || \
1215  isWritePtr( hashOutputSize, sizeof( int ) ) );
1216 
1217  /* Find the information for the requested hash algorithm */
1218  for( i = 0; hashFunctions[ i ].cryptAlgo != CRYPT_ALGO_NONE && \
1219  i < FAILSAFE_ARRAYSIZE( hashFunctions, HASHFUNCTION_ATOMIC_INFO );
1220  i++ )
1221  {
1222  /* If this isn't the algorithm that we're looking for, continue */
1223  if( hashFunctions[ i ].cryptAlgo != hashAlgorithm )
1224  continue;
1225 
1226  /* If we're looking for a specific hash-size match and this isn't
1227  it, continue */
1228  if( hashParam != 0 && hashFunctions[ i ].hashSize != hashParam )
1229  continue;
1230 
1231  /* We've found what we're after */
1232  break;
1233  }
1234  if( i >= FAILSAFE_ARRAYSIZE( hashFunctions, HASHFUNCTION_ATOMIC_INFO ) || \
1235  hashFunctions[ i ].cryptAlgo == CRYPT_ALGO_NONE )
1236  {
1237  /* Make sure that we always get some sort of hash function rather
1238  than just dying. This code always works because the internal
1239  self-test has confirmed the availability and functioning of SHA-1
1240  on startup */
1241  *hashFunctionAtomic = shaHashBufferAtomic;
1242  if( hashOutputSize != NULL )
1243  *hashOutputSize = SHA_DIGEST_LENGTH;
1244  retIntError_Void();
1245  }
1246 
1247  *hashFunctionAtomic = hashFunctions[ i ].function;
1248  if( hashOutputSize != NULL )
1249  *hashOutputSize = hashFunctions[ i ].hashSize;
1250  }