cryptlib  3.4.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros
mech_drv.c
Go to the documentation of this file.
1 /****************************************************************************
2 * *
3 * cryptlib Key Derivation Mechanism Routines *
4 * Copyright Peter Gutmann 1992-2009 *
5 * *
6 ****************************************************************************/
7 
8 #ifdef INC_ALL
9  #include "crypt.h"
10  #include "asn1.h"
11  #include "mech_int.h"
12  #include "pgp.h"
13 #else
14  #include "crypt.h"
15  #include "enc_dec/asn1.h"
16  #include "mechs/mech_int.h"
17  #include "misc/pgp.h"
18 #endif /* Compiler-specific includes */
19 
20 /****************************************************************************
21 * *
22 * PRF Building Blocks *
23 * *
24 ****************************************************************************/
25 
26 /* HMAC-based PRF used for PKCS #5 v2 and TLS */
27 
28 #define HMAC_DATASIZE 64
29 
30 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 5, 7, 8 ) ) \
31 static int prfInit( IN const HASHFUNCTION hashFunction,
32  IN const HASHFUNCTION_ATOMIC hashFunctionAtomic,
33  INOUT TYPECAST( HASHINFO ) void *hashState,
34  IN_LENGTH_HASH const int hashSize,
35  OUT_BUFFER( processedKeyMaxLength, *processedKeyLength ) \
36  void *processedKey,
38  const int processedKeyMaxLength,
39  OUT_RANGE( 0, HMAC_DATASIZE ) int *processedKeyLength,
40  IN_BUFFER( keyLength ) const void *key,
41  IN_LENGTH_SHORT const int keyLength )
42  {
43  BYTE hashBuffer[ HMAC_DATASIZE + 8 ], *keyPtr = processedKey;
44  int i;
45 
46  assert( isWritePtr( hashState, sizeof( HASHINFO ) ) );
47  assert( isWritePtr( processedKey, processedKeyMaxLength ) );
48  assert( isWritePtr( processedKeyLength, sizeof( int ) ) );
49  assert( isReadPtr( key, keyLength ) );
50 
51  REQUIRES( hashFunction != NULL && hashFunctionAtomic != NULL );
52  REQUIRES( hashSize >= 16 && hashSize <= CRYPT_MAX_HASHSIZE );
53  REQUIRES( processedKeyMaxLength == HMAC_DATASIZE );
54  REQUIRES( keyLength > 0 && keyLength < MAX_INTLENGTH_SHORT );
55 
56  /* Clear return values */
57  memset( processedKey, 0, min( 16, processedKeyMaxLength ) );
58  *processedKeyLength = 0;
59 
60  /* If the key size is larger than the hash data size reduce it to the
61  hash size before processing it (yuck. You're required to do this
62  though) */
63  if( keyLength > HMAC_DATASIZE )
64  {
65  /* Hash the user key down to the hash size and use the hashed form of
66  the key */
67  hashFunctionAtomic( processedKey, processedKeyMaxLength, key,
68  keyLength );
69  *processedKeyLength = hashSize;
70  }
71  else
72  {
73  /* Copy the key to internal storage */
74  memcpy( processedKey, key, keyLength );
75  *processedKeyLength = keyLength;
76  }
77 
78  /* Perform the start of the inner hash using the zero-padded key XORed
79  with the ipad value */
80  memset( hashBuffer, HMAC_IPAD, HMAC_DATASIZE );
81  for( i = 0; i < *processedKeyLength; i++ )
82  hashBuffer[ i ] ^= *keyPtr++;
83  hashFunction( hashState, NULL, 0, hashBuffer, HMAC_DATASIZE,
85  zeroise( hashBuffer, HMAC_DATASIZE );
86 
87  return( CRYPT_OK );
88  }
89 
90 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4, 6 ) ) \
91 static int prfEnd( IN const HASHFUNCTION hashFunction,
92  INOUT TYPECAST( HASHINFO ) void *hashState,
93  IN_LENGTH_HASH const int hashSize,
94  OUT_BUFFER_FIXED( hashMaxSize ) void *hash,
95  IN_LENGTH_HASH const int hashMaxSize,
96  IN_BUFFER( processedKeyLength ) const void *processedKey,
97  IN_RANGE( 1, HMAC_DATASIZE ) const int processedKeyLength )
98  {
99  BYTE hashBuffer[ HMAC_DATASIZE + 8 ];
100  BYTE digestBuffer[ CRYPT_MAX_HASHSIZE + 8 ];
101  int i;
102 
103  assert( isWritePtr( hashState, sizeof( HASHINFO ) ) );
104  assert( isWritePtr( hash, hashMaxSize ) );
105  assert( isReadPtr( processedKey, processedKeyLength ) );
106 
107  REQUIRES( hashFunction != NULL );
108  REQUIRES( hashSize >= 16 && hashSize <= CRYPT_MAX_HASHSIZE );
109  REQUIRES( hashMaxSize >= 16 && hashMaxSize <= CRYPT_MAX_HASHSIZE );
110  REQUIRES( processedKeyLength >= 1 && \
111  processedKeyLength <= HMAC_DATASIZE );
112 
113  /* Complete the inner hash and extract the digest */
114  hashFunction( hashState, digestBuffer, CRYPT_MAX_HASHSIZE, NULL, 0,
115  HASH_STATE_END );
116 
117  /* Perform the outer hash using the zero-padded key XORed with the opad
118  value followed by the digest from the inner hash */
119  memset( hashBuffer, HMAC_OPAD, HMAC_DATASIZE );
120  memcpy( hashBuffer, processedKey, processedKeyLength );
121  for( i = 0; i < processedKeyLength; i++ )
122  hashBuffer[ i ] ^= HMAC_OPAD;
123  hashFunction( hashState, NULL, 0, hashBuffer, HMAC_DATASIZE,
125  zeroise( hashBuffer, HMAC_DATASIZE );
126  hashFunction( hashState, hash, hashMaxSize, digestBuffer, hashSize,
127  HASH_STATE_END );
128  zeroise( digestBuffer, CRYPT_MAX_HASHSIZE );
129 
130  return( CRYPT_OK );
131  }
132 
133 /****************************************************************************
134 * *
135 * PKCS #5v2 Key Derivation *
136 * *
137 ****************************************************************************/
138 
139 /* Implement one round of the PKCS #5v2 PRF */
140 
141 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 6, 8 ) ) \
142 static int pbkdf2Hash( OUT_BUFFER_FIXED( outLength ) BYTE *out,
143  IN_RANGE( 1, CRYPT_MAX_HASHSIZE ) const int outLength,
144  IN const HASHFUNCTION hashFunction,
145  INOUT TYPECAST( HASHINFO ) void *initialHashState,
146  IN_LENGTH_HASH const int hashSize,
147  IN_BUFFER( keyLength ) const void *key,
148  IN_RANGE( 1, HMAC_DATASIZE ) const int keyLength,
149  IN_BUFFER( saltLength ) const void *salt,
150  IN_RANGE( 4, 512 ) const int saltLength,
151  IN_INT const int iterations,
152  IN_RANGE( 1, 1000 ) const int blockCount )
153  {
154  HASHINFO hashInfo;
155  BYTE block[ CRYPT_MAX_HASHSIZE + 8 ], countBuffer[ 4 + 8 ];
156  int i, status;
157 
158  assert( isWritePtr( out, outLength ) );
159  assert( isWritePtr( initialHashState, sizeof( HASHINFO ) ) );
160  assert( isReadPtr( key, keyLength ) );
161  assert( isReadPtr( salt, saltLength ) );
162 
163  REQUIRES( hashFunction != NULL );
164  REQUIRES( outLength > 0 && outLength <= hashSize && \
165  outLength <= CRYPT_MAX_HASHSIZE );
166  REQUIRES( hashSize >= 16 && hashSize <= CRYPT_MAX_HASHSIZE );
167  REQUIRES( keyLength >= 1 && keyLength <= HMAC_DATASIZE );
168  REQUIRES( saltLength >= 4 && saltLength <= 512 );
169  REQUIRES( iterations > 0 && iterations < MAX_INTLENGTH );
170  REQUIRES( blockCount > 0 && blockCount <= 1000 );
171 
172  /* Clear return value */
173  memset( out, 0, outLength );
174 
175  /* Set up the block counter buffer. This will never have more than the
176  last few bits set (8 bits = 5100 bytes of key) so we only change the
177  last byte */
178  memset( countBuffer, 0, 4 );
179  countBuffer[ 3 ] = ( BYTE ) blockCount;
180 
181  /* Calculate HMAC( salt || counter ) */
182  memcpy( hashInfo, initialHashState, sizeof( HASHINFO ) );
183  hashFunction( hashInfo, NULL, 0, salt, saltLength, HASH_STATE_CONTINUE );
184  hashFunction( hashInfo, NULL, 0, countBuffer, 4, HASH_STATE_CONTINUE );
185  status = prfEnd( hashFunction, hashInfo, hashSize, block,
186  CRYPT_MAX_HASHSIZE, key, keyLength );
187  if( cryptStatusError( status ) )
188  {
189  zeroise( hashInfo, sizeof( HASHINFO ) );
190  return( status );
191  }
192  memcpy( out, block, outLength );
193 
194  /* Calculate HMAC( T1 ) ^ HMAC( T2 ) ^ ... HMAC( Tc ) */
195  for( i = 0; i < iterations - 1 && i < FAILSAFE_ITERATIONS_MAX; i++ )
196  {
197  int j;
198 
199  /* Generate the PRF output for the current iteration */
200  memcpy( hashInfo, initialHashState, sizeof( HASHINFO ) );
201  hashFunction( hashInfo, NULL, 0, block, hashSize, HASH_STATE_CONTINUE );
202  status = prfEnd( hashFunction, hashInfo, hashSize, block,
203  CRYPT_MAX_HASHSIZE, key, keyLength );
204  if( cryptStatusError( status ) )
205  {
206  zeroise( hashInfo, sizeof( HASHINFO ) );
207  zeroise( block, CRYPT_MAX_HASHSIZE );
208  return( status );
209  }
210 
211  /* XOR the new PRF output into the existing PRF output */
212  for( j = 0; j < outLength; j++ )
213  out[ j ] ^= block[ j ];
214  }
215  ENSURES( i < FAILSAFE_ITERATIONS_MAX );
216 
217  zeroise( hashInfo, sizeof( HASHINFO ) );
218  zeroise( block, CRYPT_MAX_HASHSIZE );
219 
220  return( CRYPT_OK );
221  }
222 
223 /* Perform PKCS #5v2 derivation */
224 
226 int derivePKCS5( STDC_UNUSED void *dummy,
228  {
230  HASHFUNCTION_ATOMIC hashFunctionAtomic;
232  HASHINFO initialHashInfo;
233  BYTE processedKey[ HMAC_DATASIZE + 8 ];
234  BYTE *dataOutPtr = mechanismInfo->dataOut;
235  static const MAP_TABLE mapTbl[] = {
242  };
243  int hashSize, keyIndex, processedKeyLength, blockCount = 1;
244  int value, iterationCount, status;
245 
246  UNUSED_ARG( dummy );
247  assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_DERIVE_INFO ) ) );
248 
249  /* Clear return value */
250  memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
251 
252  /* Convert the HMAC algorithm into the equivalent hash algorithm for use
253  with the PRF */
254  status = mapValue( mechanismInfo->hashAlgo, &value, mapTbl,
255  FAILSAFE_ARRAYSIZE( mapTbl, MAP_TABLE ) );
256  if( cryptStatusError( status ) )
257  return( status );
258  hashAlgo = value;
259  if( !algoAvailable( hashAlgo ) )
260  return( CRYPT_ERROR_NOTAVAIL );
261 
262  /* Initialise the HMAC information with the user key. Although the user
263  has specified the algorithm in terms of an HMAC we're synthesising it
264  from the underlying hash algorithm since this allows us to perform the
265  PRF setup once and reuse the initial value for any future hashing */
266  getHashAtomicParameters( hashAlgo, mechanismInfo->hashParam,
267  &hashFunctionAtomic, &hashSize );
268  getHashParameters( hashAlgo, mechanismInfo->hashParam, &hashFunction,
269  NULL );
270  status = prfInit( hashFunction, hashFunctionAtomic, initialHashInfo,
271  hashSize, processedKey, HMAC_DATASIZE,
272  &processedKeyLength, mechanismInfo->dataIn,
273  mechanismInfo->dataInLength );
274  if( cryptStatusError( status ) )
275  return( status );
276 
277  /* Produce enough blocks of output to fill the key (nil sine magno
278  labore) */
279  for( keyIndex = 0, iterationCount = 0;
280  keyIndex < mechanismInfo->dataOutLength && \
281  iterationCount < FAILSAFE_ITERATIONS_MED;
282  keyIndex += hashSize, dataOutPtr += hashSize, iterationCount++ )
283  {
284  const int noKeyBytes = \
285  ( mechanismInfo->dataOutLength - keyIndex > hashSize ) ? \
286  hashSize : mechanismInfo->dataOutLength - keyIndex;
287 
288  status = pbkdf2Hash( dataOutPtr, noKeyBytes,
289  hashFunction, initialHashInfo, hashSize,
290  processedKey, processedKeyLength,
291  mechanismInfo->salt, mechanismInfo->saltLength,
292  mechanismInfo->iterations, blockCount++ );
293  if( cryptStatusError( status ) )
294  break;
295  }
296  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
297  zeroise( initialHashInfo, sizeof( HASHINFO ) );
298  zeroise( processedKey, HMAC_DATASIZE );
299  if( cryptStatusError( status ) )
300  {
301  zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
302  return( status );
303  }
304 
305  return( CRYPT_OK );
306  }
307 
308 /* Apply PKCS #5v2 as a pure (single-round) KDF */
309 
311 int kdfPKCS5( STDC_UNUSED void *dummy,
313  {
314  MECHANISM_DERIVE_INFO mechanismDeriveInfo;
316  BYTE masterSecretBuffer[ CRYPT_MAX_KEYSIZE + 8 ];
317  BYTE keyBuffer[ CRYPT_MAX_KEYSIZE + 8 ];
318  int masterSecretSize, keySize = DUMMY_INIT, status;
319 
320  UNUSED_ARG( dummy );
321  assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_DERIVE_INFO ) ) );
322 
323  /* Get the key payload details from the key contexts */
324  status = krnlSendMessage( mechanismInfo->masterKeyContext,
325  IMESSAGE_GETATTRIBUTE, &masterSecretSize,
327  if( cryptStatusOK( status ) )
328  {
329  status = krnlSendMessage( mechanismInfo->keyContext,
330  IMESSAGE_GETATTRIBUTE, &keySize,
332  }
333  if( cryptStatusError( status ) )
334  return( status );
335  ENSURES( masterSecretSize > 0 && \
336  masterSecretSize <= CRYPT_MAX_KEYSIZE );
337 
338  /* Extract the master secret value from the generic-secret context and
339  derive the key from it using PBKDF2 as the KDF */
340  status = extractKeyData( mechanismInfo->masterKeyContext,
341  masterSecretBuffer, CRYPT_MAX_KEYSIZE,
342  "keydata", 7 );
343  if( cryptStatusError( status ) )
344  return( status );
345  setMechanismDeriveInfo( &mechanismDeriveInfo, keyBuffer, keySize,
346  masterSecretBuffer, masterSecretSize,
347  mechanismInfo->hashAlgo, mechanismInfo->salt,
348  mechanismInfo->saltLength, 1 );
349  mechanismDeriveInfo.hashParam = mechanismInfo->hashParam;
350  status = derivePKCS5( NULL, &mechanismDeriveInfo );
351  zeroise( masterSecretBuffer, CRYPT_MAX_KEYSIZE );
352  if( cryptStatusError( status ) )
353  {
354  zeroise( keyBuffer, CRYPT_MAX_KEYSIZE );
355  return( status );
356  }
357 
358  /* Load the derived key into the context */
359  setMessageData( &msgData, keyBuffer, keySize );
360  status = krnlSendMessage( mechanismInfo->keyContext,
361  IMESSAGE_SETATTRIBUTE_S, &msgData,
363  zeroise( keyBuffer, CRYPT_MAX_KEYSIZE );
364 
365  return( status );
366  }
367 
368 /****************************************************************************
369 * *
370 * PKCS #12 Key Derivation *
371 * *
372 ****************************************************************************/
373 
374 #ifdef USE_PKCS12
375 
376 /* The nominal block size for PKCS #12 derivation, based on the MD5/SHA-1
377  input size of 512 bits */
378 
379 #define P12_BLOCKSIZE 64
380 
381 /* The maximum size of the expanded diversifier, salt, and password (DSP),
382  one block for the expanded diversifier, one block for the expanded salt,
383  and up to three blocks for the password converted to Unicode with a
384  terminating \x00 appended, which for a maximum password length of
385  CRYPT_MAX_TEXTSIZE can be ( 64 + 1 ) * 2, rounded up to a multiple of
386  P12_BLOCKSIZE */
387 
388 #define P12_DSPSIZE ( P12_BLOCKSIZE + P12_BLOCKSIZE + \
389  ( P12_BLOCKSIZE * 3 ) )
390 
391 /* Add two P12_BLOCKSIZE-byte blocks as 64-byte big-endian values:
392 
393  dest = (dest + src + 1) mod 2^P12_BLOCKSIZE */
394 
395 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
396 static int add64( INOUT_BUFFER_FIXED( destLen ) BYTE *dest,
397  IN_LENGTH_FIXED( P12_BLOCKSIZE ) const int destLen,
398  IN_BUFFER( srcLen ) const BYTE *src,
399  IN_LENGTH_FIXED( P12_BLOCKSIZE ) const int srcLen )
400  {
401  int destIndex, srcIndex, carry = 1;
402 
403  assert( isWritePtr( dest, destLen ) );
404  assert( isReadPtr( src, srcLen ) );
405 
406  REQUIRES( destLen == P12_BLOCKSIZE );
407  REQUIRES( srcLen == P12_BLOCKSIZE );
408 
409  /* dest = (dest + src + 1) mod 2^P12_BLOCKSIZE */
410  for( destIndex = P12_BLOCKSIZE - 1, srcIndex = P12_BLOCKSIZE - 1;
411  destIndex >= 0; destIndex--, srcIndex-- )
412  {
413  const int value = dest[ destIndex ] + src[ srcIndex ] + carry;
414  dest[ destIndex ] = intToByte( value & 0xFF );
415  carry = value >> 8;
416  }
417 
418  return( CRYPT_OK );
419  }
420 
421 /* Concantenate enough copies of the input data together to fill an output
422  buffer */
423 
424 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \
425 static int expandData( OUT_BUFFER_FIXED( destLen ) BYTE *dest,
426  IN_LENGTH_SHORT const int destLen,
427  IN_BUFFER( srcLen ) const BYTE *src,
428  IN_LENGTH_SHORT const int srcLen )
429  {
430  int index, iterationCount;
431 
432  assert( isWritePtr( dest, destLen ) );
433  assert( isReadPtr( src, srcLen ) );
434 
435  REQUIRES( destLen > 0 && destLen < MAX_INTLENGTH_SHORT );
436  REQUIRES( srcLen > 0 && srcLen < MAX_INTLENGTH_SHORT );
437 
438  /* Clear return value */
439  memset( dest, 0, min( 16, destLen ) );
440 
441  for( index = 0, iterationCount = 0;
442  index < destLen && iterationCount < FAILSAFE_ITERATIONS_MED;
443  iterationCount++ )
444  {
445  const int bytesToCopy = min( srcLen, destLen - index );
446 
447  memcpy( dest, src, bytesToCopy );
448  dest += bytesToCopy;
449  index += bytesToCopy;
450  }
451  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
452 
453  return( CRYPT_OK );
454  }
455 
456 /* Build the diversifier/salt/password (DSP) string to use as the initial
457  input to the hash function:
458 
459  <---- 64 bytes ----><------- 64 bytes -------><-- Mult.64 bytes ->
460  [ ID | ID | ID ... ][ salt | salt | salt ... ][ pw | pw | pw ... ] */
461 
462 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 6 ) ) \
463 static int initDSP( OUT_BUFFER( dspMaxLen, *dspLen ) BYTE *dsp,
464  IN_RANGE( P12_DSPSIZE, 512 ) const int dspMaxLen,
465  OUT_RANGE( 0, 512 ) int *dspLen,
466  IN_BUFFER( keyLength ) const BYTE *key,
467  IN_LENGTH_NAME const int keyLength,
468  IN_BUFFER( saltLength ) const BYTE *salt,
469  IN_RANGE( 1, P12_BLOCKSIZE ) const int saltLength,
470  IN_RANGE( 1, 3 ) const int diversifier )
471  {
472  BYTE bmpString[ ( ( CRYPT_MAX_TEXTSIZE + 1 ) * 2 ) + 8 ];
473  BYTE *dspPtr = dsp;
474  int keyIndex, bmpIndex, i, status;
475 
476  assert( isWritePtr( dsp, dspMaxLen ) );
477  assert( isWritePtr( dspLen, sizeof( int ) ) );
478  assert( isReadPtr( key, keyLength ) );
479  assert( isReadPtr( salt, saltLength ) );
480 
481  REQUIRES( dspMaxLen >= P12_DSPSIZE && dspMaxLen <= 512 );
482  REQUIRES( diversifier >= 1 && diversifier <= 3 );
483  REQUIRES( saltLength >= 1 && saltLength <= P12_BLOCKSIZE );
484  REQUIRES( keyLength >= MIN_NAME_LENGTH && \
485  keyLength <= CRYPT_MAX_TEXTSIZE );
486 
487  /* Clear return values */
488  memset( dsp, 0, min( 16, dspMaxLen ) );
489  *dspLen = 0;
490 
491  /* Set up the diversifier in the first P12_BLOCKSIZE bytes */
492  for( i = 0; i < P12_BLOCKSIZE; i++ )
493  dsp[ i ] = intToByte( diversifier );
494  dspPtr += P12_BLOCKSIZE;
495 
496  /* Set up the salt in the next P12_BLOCKSIZE bytes */
497  status = expandData( dspPtr, P12_BLOCKSIZE, salt, saltLength );
498  if( cryptStatusError( status ) )
499  return( status );
500  dspPtr += P12_BLOCKSIZE;
501 
502  /* Convert the password to a null-terminated Unicode string, a Microsoft
503  bug that was made part of the standard */
504  for( keyIndex = 0, bmpIndex = 0;
505  keyIndex < keyLength && keyIndex < CRYPT_MAX_TEXTSIZE;
506  keyIndex++, bmpIndex += 2 )
507  {
508  bmpString[ bmpIndex ] = '\0';
509  bmpString[ bmpIndex + 1 ] = key[ keyIndex ];
510  }
511  ENSURES( keyIndex < CRYPT_MAX_TEXTSIZE );
512  bmpString[ bmpIndex++ ] = '\0';
513  bmpString[ bmpIndex++ ] = '\0';
514  ENSURES( dspMaxLen >= P12_BLOCKSIZE + P12_BLOCKSIZE + \
515  roundUp( bmpIndex, P12_BLOCKSIZE ) );
516 
517  /* Set up the Unicode password string as the remaining bytes */
518  status = expandData( dspPtr, roundUp( bmpIndex, P12_BLOCKSIZE ),
519  bmpString, bmpIndex );
520  zeroise( bmpString, ( CRYPT_MAX_TEXTSIZE + 1 ) * 2 );
521  if( cryptStatusError( status ) )
522  {
523  zeroise( dsp, dspMaxLen );
524  return( status );
525  }
526  *dspLen = P12_BLOCKSIZE + P12_BLOCKSIZE + \
527  roundUp( bmpIndex, P12_BLOCKSIZE );
528 
529  return( CRYPT_OK );
530  }
531 
532 /* Perform PKCS #12 derivation */
533 
535 int derivePKCS12( STDC_UNUSED void *dummy,
536  INOUT MECHANISM_DERIVE_INFO *mechanismInfo )
537  {
538  HASHFUNCTION_ATOMIC hashFunctionAtomic;
539  BYTE p12_DSP[ P12_DSPSIZE + 8 ];
540  BYTE p12_Ai[ CRYPT_MAX_HASHSIZE + 8 ], p12_B[ P12_BLOCKSIZE + 8 ];
541  BYTE *dataOutPtr = mechanismInfo->dataOut;
542  const BYTE *saltPtr = mechanismInfo->salt;
543  int dspLen, hashSize, keyIndex, i, iterationCount, status;
544 
545  UNUSED_ARG( dummy );
546  assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_DERIVE_INFO ) ) );
547 
548  /* Clear return value */
549  memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
550 
551  getHashAtomicParameters( mechanismInfo->hashAlgo, 0, &hashFunctionAtomic,
552  &hashSize );
553 
554  /* Set up the diversifier/salt/password (DSP) string. The first byte of
555  the PKCS #12 salt acts as a diversifier so we separate this out from
556  the rest of the salt data */
557  status = initDSP( p12_DSP, P12_DSPSIZE, &dspLen, mechanismInfo->dataIn,
558  mechanismInfo->dataInLength, saltPtr + 1,
559  mechanismInfo->saltLength - 1, byteToInt( *saltPtr ) );
560  if( cryptStatusError( status ) )
561  return( status );
562 
563  /* Produce enough blocks of output to fill the key */
564  for( keyIndex = 0, iterationCount = 0;
565  keyIndex < mechanismInfo->dataOutLength && \
566  iterationCount < FAILSAFE_ITERATIONS_MED;
567  keyIndex += hashSize, iterationCount++ )
568  {
569  const int noKeyBytes = \
570  ( mechanismInfo->dataOutLength - keyIndex > hashSize ) ? \
571  hashSize : mechanismInfo->dataOutLength - keyIndex;
572  int dspIndex;
573 
574  /* Hash the keying material the required number of times to obtain the
575  output value */
576  hashFunctionAtomic( p12_Ai, CRYPT_MAX_HASHSIZE, p12_DSP, dspLen );
577  for( i = 1; i < mechanismInfo->iterations && \
578  i < FAILSAFE_ITERATIONS_MAX; i++ )
579  {
581  p12_Ai, hashSize );
582  }
583  ENSURES( i < FAILSAFE_ITERATIONS_MAX );
584  memcpy( dataOutPtr + keyIndex, p12_Ai, noKeyBytes );
585 
586  /* Update the input keying material for the next iteration by
587  adding the output value expanded to P12_BLOCKSIZE, to
588  P12_BLOCKSIZE-sized blocks of the salt/password portion of the
589  DSP string */
590  status = expandData( p12_B, P12_BLOCKSIZE, p12_Ai, hashSize );
591  if( cryptStatusError( status ) )
592  break;
593  for( dspIndex = P12_BLOCKSIZE; dspIndex < dspLen;
594  dspIndex += P12_BLOCKSIZE )
595  {
596  status = add64( p12_DSP + dspIndex, P12_BLOCKSIZE,
597  p12_B, P12_BLOCKSIZE );
598  if( cryptStatusError( status ) )
599  break;
600  }
601  }
602  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
603  zeroise( p12_DSP, P12_DSPSIZE );
604  zeroise( p12_Ai, CRYPT_MAX_HASHSIZE );
605  zeroise( p12_B, P12_BLOCKSIZE );
606  if( cryptStatusError( status ) )
607  {
608  zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
609  return( status );
610  }
611 
612  return( CRYPT_OK );
613  }
614 #endif /* USE_PKCS12 */
615 
616 /****************************************************************************
617 * *
618 * SSL/TLS Key Derivation *
619 * *
620 ****************************************************************************/
621 
622 #ifdef USE_SSL
623 
624 /* Structure used to store TLS PRF state information */
625 
626 typedef struct {
627  /* The hash functions and hash info */
628  HASHFUNCTION_ATOMIC hashFunctionAtomic;
630  int hashSize;
631 
632  /* The initial hash state from prfInit() and the current hash state */
633  HASHINFO initialHashInfo, hashInfo;
634 
635  /* The HMAC processed key and intermediate data value */
636  BUFFER( HMAC_DATASIZE, processedKeyLength ) \
637  BYTE processedKey[ HMAC_DATASIZE + 8 ];
638  BUFFER( HMAC_DATASIZE, hashSize ) \
639  BYTE hashA[ CRYPT_MAX_HASHSIZE + 8 ];
640  int processedKeyLength;
641  } TLS_PRF_INFO;
642 
643 /* Perform SSL key derivation */
644 
646 int deriveSSL( STDC_UNUSED void *dummy,
647  INOUT MECHANISM_DERIVE_INFO *mechanismInfo )
648  {
649  HASHFUNCTION md5HashFunction, shaHashFunction;
650  HASHINFO hashInfo;
651  BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ], counterData[ 16 + 8 ];
652  BYTE *dataOutPtr = mechanismInfo->dataOut;
653  int md5HashSize, shaHashSize, counter = 0, keyIndex, iterationCount;
654 
655  UNUSED_ARG( dummy );
656  assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_DERIVE_INFO ) ) );
657 
658  /* Clear return value */
659  memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
660 
661  getHashParameters( CRYPT_ALGO_MD5, 0, &md5HashFunction, &md5HashSize );
662  getHashParameters( CRYPT_ALGO_SHA1, 0, &shaHashFunction, &shaHashSize );
663 
664  /* Produce enough blocks of output to fill the key */
665  for( keyIndex = 0, iterationCount = 0;
666  keyIndex < mechanismInfo->dataOutLength && \
667  iterationCount < FAILSAFE_ITERATIONS_MED;
668  keyIndex += md5HashSize, iterationCount++ )
669  {
670  const int noKeyBytes = \
671  ( mechanismInfo->dataOutLength - keyIndex > md5HashSize ) ? \
672  md5HashSize : mechanismInfo->dataOutLength - keyIndex;
673  int i;
674 
675  /* Set up the counter data */
676  for( i = 0; i <= counter && i < 16; i++ )
677  counterData[ i ] = intToByte( 'A' + counter );
678  ENSURES( i < 16 );
679  counter++;
680 
681  /* Calculate SHA1( 'A'/'BB'/'CCC'/... || keyData || salt ) */
682  shaHashFunction( hashInfo, NULL, 0, counterData, counter,
684  shaHashFunction( hashInfo, NULL, 0, mechanismInfo->dataIn,
685  mechanismInfo->dataInLength, HASH_STATE_CONTINUE );
686  shaHashFunction( hashInfo, hash, CRYPT_MAX_HASHSIZE,
687  mechanismInfo->salt, mechanismInfo->saltLength,
688  HASH_STATE_END );
689 
690  /* Calculate MD5( keyData || SHA1-hash ) */
691  md5HashFunction( hashInfo, NULL, 0, mechanismInfo->dataIn,
692  mechanismInfo->dataInLength, HASH_STATE_START );
693  md5HashFunction( hashInfo, hash, CRYPT_MAX_HASHSIZE,
694  hash, shaHashSize, HASH_STATE_END );
695 
696  /* Copy the result to the output */
697  memcpy( dataOutPtr + keyIndex, hash, noKeyBytes );
698  }
699  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
700  zeroise( hashInfo, sizeof( HASHINFO ) );
701  zeroise( hash, CRYPT_MAX_HASHSIZE );
702 
703  return( CRYPT_OK );
704  }
705 
706 /* Initialise the TLS PRF */
707 
708 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
709 static int tlsPrfInit( INOUT TLS_PRF_INFO *prfInfo,
710  IN_BUFFER( keyLength ) const void *key,
711  IN_LENGTH_SHORT const int keyLength,
712  IN_BUFFER( saltLength ) const void *salt,
713  IN_LENGTH_SHORT const int saltLength )
714  {
715  int status;
716 
717  assert( isWritePtr( prfInfo, sizeof( TLS_PRF_INFO ) ) );
718  assert( isReadPtr( key, keyLength ) );
719  assert( isReadPtr( salt, saltLength ) );
720 
721  REQUIRES( keyLength > 0 && keyLength < MAX_INTLENGTH_SHORT );
722  REQUIRES( saltLength > 0 && saltLength < MAX_INTLENGTH_SHORT );
723 
724  /* Initialise the hash information with the keying info. This is
725  reused for any future hashing since it's constant */
726  status = prfInit( prfInfo->hashFunction, prfInfo->hashFunctionAtomic,
727  prfInfo->initialHashInfo, prfInfo->hashSize,
728  prfInfo->processedKey, HMAC_DATASIZE,
729  &prfInfo->processedKeyLength, key, keyLength );
730  if( cryptStatusError( status ) )
731  return( status );
732 
733  /* Calculate A1 = HMAC( salt ) */
734  memcpy( prfInfo->hashInfo, prfInfo->initialHashInfo, sizeof( HASHINFO ) );
735  prfInfo->hashFunction( prfInfo->hashInfo, NULL, 0, salt, saltLength,
737  return( prfEnd( prfInfo->hashFunction, prfInfo->hashInfo,
738  prfInfo->hashSize, prfInfo->hashA,
739  CRYPT_MAX_HASHSIZE, prfInfo->processedKey,
740  prfInfo->processedKeyLength ) );
741  }
742 
743 /* Implement one round of the TLS PRF */
744 
745 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4 ) ) \
746 static int tlsPrfHash( OUT_BUFFER_FIXED( outLength ) BYTE *out,
747  IN_LENGTH_SHORT const int outLength,
748  INOUT TLS_PRF_INFO *prfInfo,
749  IN_BUFFER( saltLength ) const void *salt,
750  IN_LENGTH_SHORT const int saltLength )
751  {
752  HASHINFO hashInfo, AnHashInfo;
753  BYTE hash[ CRYPT_MAX_HASHSIZE + 8 ];
754  int i, status;
755 
756  assert( isWritePtr( out, outLength ) );
757  assert( isWritePtr( prfInfo, sizeof( TLS_PRF_INFO ) ) );
758  assert( isReadPtr( salt, saltLength ) );
759 
760  REQUIRES( outLength > 0 && outLength <= prfInfo->hashSize && \
761  outLength <= CRYPT_MAX_HASHSIZE );
762  REQUIRES( saltLength >= 13 && saltLength <= 512 );
763 
764  /* The result of the hashing is XORd to the output so we don't clear the
765  return value like usual */
766 
767  /* Calculate HMAC( An || salt ) */
768  memcpy( hashInfo, prfInfo->initialHashInfo, sizeof( HASHINFO ) );
769  prfInfo->hashFunction( hashInfo, NULL, 0, prfInfo->hashA,
770  prfInfo->hashSize, HASH_STATE_CONTINUE );
771  memcpy( AnHashInfo, hashInfo, sizeof( HASHINFO ) );
772  prfInfo->hashFunction( hashInfo, NULL, 0, salt, saltLength,
774  status = prfEnd( prfInfo->hashFunction, hashInfo, prfInfo->hashSize,
775  hash, CRYPT_MAX_HASHSIZE, prfInfo->processedKey,
776  prfInfo->processedKeyLength );
777  if( cryptStatusError( status ) )
778  {
779  zeroise( AnHashInfo, sizeof( HASHINFO ) );
780  zeroise( hashInfo, sizeof( HASHINFO ) );
781  zeroise( hash, CRYPT_MAX_HASHSIZE );
782  return( status );
783  }
784 
785  /* Calculate An+1 = HMAC( An ) */
786  memcpy( hashInfo, AnHashInfo, sizeof( HASHINFO ) );
787  status = prfEnd( prfInfo->hashFunction, hashInfo, prfInfo->hashSize,
788  prfInfo->hashA, prfInfo->hashSize,
789  prfInfo->processedKey, prfInfo->processedKeyLength );
790  if( cryptStatusError( status ) )
791  {
792  zeroise( AnHashInfo, sizeof( HASHINFO ) );
793  zeroise( hashInfo, sizeof( HASHINFO ) );
794  zeroise( hash, CRYPT_MAX_HASHSIZE );
795  return( status );
796  }
797 
798  /* Copy the result to the output */
799  for( i = 0; i < outLength; i++ )
800  out[ i ] ^= hash[ i ];
801 
802  zeroise( AnHashInfo, sizeof( HASHINFO ) );
803  zeroise( hashInfo, sizeof( HASHINFO ) );
804  zeroise( hash, CRYPT_MAX_HASHSIZE );
805 
806  return( CRYPT_OK );
807  }
808 
809 /* Perform TLS key derivation. This implements the function described as
810  'PRF()' in the TLS spec */
811 
813 int deriveTLS( STDC_UNUSED void *dummy,
814  INOUT MECHANISM_DERIVE_INFO *mechanismInfo )
815  {
816  TLS_PRF_INFO md5Info, shaInfo;
817  BYTE *dataOutPtr = mechanismInfo->dataOut;
818  const void *s1, *s2;
819  const int dataOutLength = mechanismInfo->dataOutLength;
820  const int sLen = ( mechanismInfo->dataInLength + 1 ) / 2;
821  int md5Index, shaIndex, iterationCount, status;
822 
823  UNUSED_ARG( dummy );
824  assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_DERIVE_INFO ) ) );
825 
826  /* Clear return value */
827  memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
828 
829  memset( &md5Info, 0, sizeof( TLS_PRF_INFO ) );
830  getHashAtomicParameters( CRYPT_ALGO_MD5, 0, &md5Info.hashFunctionAtomic,
831  &md5Info.hashSize );
832  getHashParameters( CRYPT_ALGO_MD5, 0, &md5Info.hashFunction, NULL );
833  memset( &shaInfo, 0, sizeof( TLS_PRF_INFO ) );
834  getHashAtomicParameters( CRYPT_ALGO_SHA1, 0, &shaInfo.hashFunctionAtomic,
835  &shaInfo.hashSize );
836  getHashParameters( CRYPT_ALGO_SHA1, 0, &shaInfo.hashFunction, NULL );
837 
838  /* Find the start of the two halves of the keying info used for the
839  HMACing. The size of each half is given by ceil( dataInLength / 2 )
840  so there's a one-byte overlap if the input is an odd number of bytes
841  long */
842  s1 = mechanismInfo->dataIn;
843  s2 = ( BYTE * ) mechanismInfo->dataIn + \
844  ( mechanismInfo->dataInLength - sLen );
845 
846  /* The two hash functions have different block sizes that would require
847  complex buffering to handle leftover bytes from SHA-1, a simpler
848  method is to zero the output data block and XOR in the values from
849  each hash mechanism using separate output location indices for MD5 and
850  SHA-1 */
851  memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
852 
853  /* Initialise the TLS PRF and calculate A1 = HMAC( salt ) */
854  status = tlsPrfInit( &md5Info, s1, sLen, mechanismInfo->salt,
855  mechanismInfo->saltLength );
856  if( cryptStatusOK( status ) )
857  status = tlsPrfInit( &shaInfo, s2, sLen, mechanismInfo->salt,
858  mechanismInfo->saltLength );
859  if( cryptStatusError( status ) )
860  {
861  zeroise( &md5Info, sizeof( TLS_PRF_INFO ) );
862  zeroise( &shaInfo, sizeof( TLS_PRF_INFO ) );
863  return( status );
864  }
865 
866  /* Produce enough blocks of output to fill the key. We use the MD5 hash
867  size as the loop increment since this produces the smaller output
868  block */
869  for( md5Index = shaIndex = 0, iterationCount = 0;
870  md5Index < dataOutLength && iterationCount < FAILSAFE_ITERATIONS_MED;
871  iterationCount++ )
872  {
873  const int md5NoKeyBytes = min( dataOutLength - md5Index, \
874  md5Info.hashSize );
875  const int shaNoKeyBytes = min( dataOutLength - shaIndex, \
876  shaInfo.hashSize );
877 
878  status = tlsPrfHash( dataOutPtr + md5Index, md5NoKeyBytes,
879  &md5Info, mechanismInfo->salt,
880  mechanismInfo->saltLength );
881  if( cryptStatusError( status ) )
882  break;
883  if( shaNoKeyBytes > 0 )
884  {
885  /* Since the SHA-1 counter advances faster than the MD5 one we
886  can end up with zero bytes left to process for SHA-1 when MD5
887  is processing it's last block */
888  status = tlsPrfHash( dataOutPtr + shaIndex, shaNoKeyBytes,
889  &shaInfo, mechanismInfo->salt,
890  mechanismInfo->saltLength );
891  if( cryptStatusError( status ) )
892  break;
893  }
894 
895  md5Index += md5NoKeyBytes;
896  shaIndex += shaNoKeyBytes;
897  }
898  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
899  zeroise( &md5Info, sizeof( TLS_PRF_INFO ) );
900  zeroise( &shaInfo, sizeof( TLS_PRF_INFO ) );
901  if( cryptStatusError( status ) )
902  {
903  zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
904  return( status );
905  }
906 
907  return( CRYPT_OK );
908  }
909 
910 /* Perform TLS 1.2 key derivation using a gratuitously incompatible PRF
911  invented for TLS 1.2 */
912 
914 int deriveTLS12( STDC_UNUSED void *dummy,
915  INOUT MECHANISM_DERIVE_INFO *mechanismInfo )
916  {
917  TLS_PRF_INFO shaInfo;
918  BYTE *dataOutPtr = mechanismInfo->dataOut;
919  const int dataOutLength = mechanismInfo->dataOutLength;
920  int keyIndex, iterationCount, status;
921 
922  UNUSED_ARG( dummy );
923  assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_DERIVE_INFO ) ) );
924 
925  /* Clear return value */
926  memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
927 
928  memset( &shaInfo, 0, sizeof( TLS_PRF_INFO ) );
929  getHashAtomicParameters( mechanismInfo->hashAlgo,
930  mechanismInfo->hashParam,
931  &shaInfo.hashFunctionAtomic,
932  &shaInfo.hashSize );
933  getHashParameters( mechanismInfo->hashAlgo, mechanismInfo->hashParam,
934  &shaInfo.hashFunction, NULL );
935 
936  /* Initialise the TLS PRF and calculate A1 = HMAC( salt ) */
937  status = tlsPrfInit( &shaInfo, mechanismInfo->dataIn,
938  mechanismInfo->dataInLength, mechanismInfo->salt,
939  mechanismInfo->saltLength );
940  if( cryptStatusError( status ) )
941  {
942  zeroise( &shaInfo, sizeof( TLS_PRF_INFO ) );
943  return( status );
944  }
945 
946  /* Produce enough blocks of output to fill the key */
947  for( keyIndex = 0, iterationCount = 0;
948  keyIndex < dataOutLength && \
949  iterationCount < FAILSAFE_ITERATIONS_MED;
950  keyIndex += shaInfo.hashSize, iterationCount++ )
951  {
952  const int noKeyBytes = min( dataOutLength - keyIndex, \
953  shaInfo.hashSize );
954 
955  status = tlsPrfHash( dataOutPtr + keyIndex, noKeyBytes, &shaInfo,
956  mechanismInfo->salt, mechanismInfo->saltLength );
957  if( cryptStatusError( status ) )
958  break;
959  }
960  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
961  zeroise( &shaInfo, sizeof( TLS_PRF_INFO ) );
962  if( cryptStatusError( status ) )
963  {
964  zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
965  return( status );
966  }
967 
968  return( CRYPT_OK );
969  }
970 #endif /* USE_SSL */
971 
972 /****************************************************************************
973 * *
974 * PGP Key Derivation *
975 * *
976 ****************************************************************************/
977 
978 #if defined( USE_PGP ) || defined( USE_PGPKEYS )
979 
980 /* Implement one round of the OpenPGP PRF */
981 
982 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3, 4, 6, 8, 10 ) ) \
983 static int pgpPrfHash( OUT_BUFFER_FIXED( outLength ) BYTE *out,
984  IN_LENGTH_HASH const int outLength,
985  IN const HASHFUNCTION hashFunction,
986  INOUT TYPECAST( HASHINFO ) void *hashInfo,
987  IN_LENGTH_HASH const int hashSize,
988  IN_BUFFER( keyLength ) const void *key,
989  IN_LENGTH_SHORT_MIN( 2 ) const int keyLength,
990  IN_BUFFER( saltLength ) const void *salt,
991  IN_LENGTH_FIXED( PGP_SALTSIZE ) const int saltLength,
992  INOUT_LENGTH_Z long *byteCount,
993  IN_RANGE( CRYPT_UNUSED, 1 ) const int preloadLength )
994  {
995  long count = *byteCount;
996 
997  assert( isWritePtr( out, outLength ) );
998  assert( isWritePtr( hashInfo, sizeof( HASHINFO ) ) );
999  assert( isReadPtr( key, keyLength ) );
1000  assert( isReadPtr( salt, saltLength ) );
1001  assert( isWritePtr( byteCount, sizeof( int ) ) );
1002 
1003  REQUIRES( hashFunction != NULL );
1004  REQUIRES( outLength == hashSize );
1005  REQUIRES( hashSize >= 16 && hashSize <= CRYPT_MAX_HASHSIZE );
1006  REQUIRES( keyLength >= 2 && keyLength <= MAX_INTLENGTH_SHORT );
1007  REQUIRES( saltLength == PGP_SALTSIZE );
1008  REQUIRES( preloadLength == CRYPT_UNUSED || \
1009  ( preloadLength >= 0 && preloadLength <= 1 ) );
1010  REQUIRES( count > 0 && count < MAX_INTLENGTH );
1011 
1012  /* Clear return value */
1013  memset( out, 0, outLength );
1014 
1015  /* If it's a subsequent round of hashing, preload the hash with zero
1016  bytes. If it's the first round (preloadLength == 0) it's handled
1017  specially below */
1018  if( preloadLength > 0 )
1019  {
1020  hashFunction( hashInfo, NULL, 0, ( const BYTE * ) "\x00\x00\x00\x00",
1021  preloadLength, HASH_STATE_START );
1022  }
1023 
1024  /* Hash the next round of salt || password. Since we're being asked to
1025  stop once we've processed 'count' input bytes we implement an early-
1026  out mechanism that exits if the length of the item being hashed is
1027  sufficient to reach 'count' */
1028  if( count <= saltLength )
1029  {
1030  hashFunction( hashInfo, out, outLength, salt, count,
1031  HASH_STATE_END );
1032  *byteCount = 0;
1033 
1034  return( CRYPT_OK );
1035  }
1036  hashFunction( hashInfo, NULL, 0, salt, saltLength,
1037  ( preloadLength == 0 ) ? HASH_STATE_START : \
1039  count -= saltLength;
1040  if( count <= keyLength )
1041  {
1042  hashFunction( hashInfo, out, outLength, key, count, HASH_STATE_END );
1043  *byteCount = 0;
1044 
1045  return( CRYPT_OK );
1046  }
1047  hashFunction( hashInfo, NULL, 0, key, keyLength, HASH_STATE_CONTINUE );
1048  count -= keyLength;
1049  ENSURES( count > 0 && count < MAX_INTLENGTH );
1050 
1051  *byteCount = count;
1052  return( CRYPT_OK );
1053  }
1054 
1055 /* Perform OpenPGP S2K key derivation */
1056 
1057 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
1058 int derivePGP( STDC_UNUSED void *dummy,
1059  INOUT MECHANISM_DERIVE_INFO *mechanismInfo )
1060  {
1062  HASHINFO hashInfo;
1063  long byteCount = ( long ) mechanismInfo->iterations << 6;
1064  long secondByteCount = 0;
1065  int hashSize, i, iterationCount, status = CRYPT_OK;
1066 
1067  assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_DERIVE_INFO ) ) );
1068 
1069  REQUIRES( mechanismInfo->iterations >= 0 && \
1070  mechanismInfo->iterations < ( MAX_INTLENGTH >> 6 ) );
1071  REQUIRES( byteCount >= 0 && byteCount < MAX_INTLENGTH );
1072 
1073  /* Clear return value */
1074  memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
1075 
1076  getHashParameters( mechanismInfo->hashAlgo, 0, &hashFunction,
1077  &hashSize );
1078 
1079  REQUIRES( mechanismInfo->dataOutLength < 2 * hashSize );
1080 
1081  /* If it's a non-iterated hash or the count won't allow even a single
1082  pass over the 8-byte salt and password, adjust it to make sure that
1083  we run at least one full iteration */
1084  if( byteCount < PGP_SALTSIZE + mechanismInfo->dataInLength )
1085  byteCount = PGP_SALTSIZE + mechanismInfo->dataInLength;
1086 
1087  /* If the hash output size is less than the required key size we run a
1088  second round of hashing after the first one to provide the total
1089  required amount of keying material */
1090  if( hashSize < mechanismInfo->dataOutLength )
1091  secondByteCount = byteCount;
1092 
1093  /* Repeatedly hash the salt and password until we've met the byte count.
1094  In effect this hashes:
1095 
1096  salt || password || salt || password || ...
1097 
1098  until we've processed 'byteCount' bytes of data */
1099  for( i = 0, iterationCount = 0;
1100  byteCount > 0 && cryptStatusOK( status ) && \
1101  iterationCount < FAILSAFE_ITERATIONS_MAX;
1102  i++, iterationCount++ )
1103  {
1104  status = pgpPrfHash( mechanismInfo->dataOut,
1105  hashSize, hashFunction, hashInfo, hashSize,
1106  mechanismInfo->dataIn,
1107  mechanismInfo->dataInLength,
1108  mechanismInfo->salt,
1109  mechanismInfo->saltLength, &byteCount,
1110  ( i <= 0 ) ? 0 : CRYPT_UNUSED );
1111  }
1112  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
1113  if( cryptStatusOK( status ) && secondByteCount > 0 )
1114  {
1115  for( i = 0, iterationCount = 0;
1116  secondByteCount > 0 && cryptStatusOK( status ) && \
1117  iterationCount < FAILSAFE_ITERATIONS_MAX;
1118  i++, iterationCount++ )
1119  {
1120  status = pgpPrfHash( ( BYTE * ) mechanismInfo->dataOut + hashSize,
1121  hashSize, hashFunction, hashInfo, hashSize,
1122  mechanismInfo->dataIn,
1123  mechanismInfo->dataInLength,
1124  mechanismInfo->salt,
1125  mechanismInfo->saltLength, &secondByteCount,
1126  ( i <= 0 ) ? 1 : CRYPT_UNUSED );
1127  }
1128  ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
1129  }
1130  zeroise( hashInfo, sizeof( HASHINFO ) );
1131  if( cryptStatusError( status ) )
1132  {
1133  zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
1134  return( status );
1135  }
1136 
1137  return( CRYPT_OK );
1138  }
1139 #endif /* USE_PGP || USE_PGPKEYS */
1140 
1141 /****************************************************************************
1142 * *
1143 * Misc Key Derivation *
1144 * *
1145 ****************************************************************************/
1146 
1147 #ifdef USE_CMP
1148 
1149 /* Perform CMP/Entrust key derivation */
1150 
1151 CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
1152 int deriveCMP( STDC_UNUSED void *dummy,
1153  INOUT MECHANISM_DERIVE_INFO *mechanismInfo )
1154  {
1155  HASHFUNCTION_ATOMIC hashFunctionAtomic;
1157  HASHINFO hashInfo;
1158  int hashSize, iterations;
1159 
1160  UNUSED_ARG( dummy );
1161  assert( isWritePtr( mechanismInfo, sizeof( MECHANISM_DERIVE_INFO ) ) );
1162 
1163  /* Clear return value */
1164  memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
1165 
1166  /* Calculate SHA1( password || salt ) */
1167  getHashAtomicParameters( mechanismInfo->hashAlgo, 0,
1168  &hashFunctionAtomic, &hashSize );
1169  getHashParameters( mechanismInfo->hashAlgo, 0, &hashFunction, NULL );
1170  hashFunction( hashInfo, NULL, 0, mechanismInfo->dataIn,
1171  mechanismInfo->dataInLength, HASH_STATE_START );
1172  hashFunction( hashInfo, mechanismInfo->dataOut,
1173  mechanismInfo->dataOutLength, mechanismInfo->salt,
1174  mechanismInfo->saltLength, HASH_STATE_END );
1175 
1176  /* Iterate the hashing the remaining number of times. We start the
1177  count at one since the first iteration has already been performed */
1178  for( iterations = 1; iterations < mechanismInfo->iterations && \
1179  iterations < FAILSAFE_ITERATIONS_MAX; iterations++ )
1180  {
1181  hashFunctionAtomic( mechanismInfo->dataOut,
1182  mechanismInfo->dataOutLength,
1183  mechanismInfo->dataOut, hashSize );
1184  }
1185  ENSURES( iterations < FAILSAFE_ITERATIONS_MAX );
1186  zeroise( hashInfo, sizeof( HASHINFO ) );
1187 
1188  return( CRYPT_OK );
1189  }
1190 #endif /* USE_CMP */