28 #define HMAC_DATASIZE 64
35 OUT_BUFFER( processedKeyMaxLength, *processedKeyLength ) \
38 const int processedKeyMaxLength,
47 assert(
isWritePtr( processedKey, processedKeyMaxLength ) );
48 assert(
isWritePtr( processedKeyLength,
sizeof(
int ) ) );
51 REQUIRES( hashFunction != NULL && hashFunctionAtomic != NULL );
57 memset( processedKey, 0,
min( 16, processedKeyMaxLength ) );
58 *processedKeyLength = 0;
74 memcpy( processedKey, key, keyLength );
81 for( i = 0; i < *processedKeyLength; i++ )
82 hashBuffer[ i ] ^= *keyPtr++;
96 IN_BUFFER( processedKeyLength )
const void *processedKey,
105 assert(
isReadPtr( processedKey, processedKeyLength ) );
110 REQUIRES( processedKeyLength >= 1 && \
120 memcpy( hashBuffer, processedKey, processedKeyLength );
121 for( i = 0; i < processedKeyLength; i++ )
126 hashFunction( hashState, hash, hashMaxSize, digestBuffer, hashSize,
152 IN_RANGE( 1, 1000 )
const int blockCount )
164 REQUIRES( outLength > 0 && outLength <= hashSize && \
168 REQUIRES( saltLength >= 4 && saltLength <= 512 );
170 REQUIRES( blockCount > 0 && blockCount <= 1000 );
173 memset( out, 0, outLength );
178 memset( countBuffer, 0, 4 );
179 countBuffer[ 3 ] = (
BYTE ) blockCount;
182 memcpy( hashInfo, initialHashState,
sizeof(
HASHINFO ) );
185 status = prfEnd( hashFunction, hashInfo, hashSize, block,
192 memcpy( out, block, outLength );
200 memcpy( hashInfo, initialHashState,
sizeof(
HASHINFO ) );
202 status = prfEnd( hashFunction, hashInfo, hashSize, block,
213 out[ j ] ^= block[ j ];
215 ENSURES( i < FAILSAFE_ITERATIONS_MAX );
234 BYTE *dataOutPtr = mechanismInfo->dataOut;
243 int hashSize, keyIndex, processedKeyLength, blockCount = 1;
250 memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
254 status = mapValue( mechanismInfo->hashAlgo, &value, mapTbl,
266 getHashAtomicParameters( hashAlgo, mechanismInfo->hashParam,
267 &hashFunctionAtomic, &hashSize );
268 getHashParameters( hashAlgo, mechanismInfo->hashParam, &hashFunction,
270 status = prfInit( hashFunction, hashFunctionAtomic, initialHashInfo,
272 &processedKeyLength, mechanismInfo->dataIn,
273 mechanismInfo->dataInLength );
279 for( keyIndex = 0, iterationCount = 0;
280 keyIndex < mechanismInfo->dataOutLength && \
284 const int noKeyBytes = \
285 ( mechanismInfo->dataOutLength - keyIndex >
hashSize ) ? \
286 hashSize : mechanismInfo->dataOutLength - keyIndex;
288 status = pbkdf2Hash( dataOutPtr, noKeyBytes,
289 hashFunction, initialHashInfo, hashSize,
290 processedKey, processedKeyLength,
291 mechanismInfo->salt, mechanismInfo->saltLength,
292 mechanismInfo->iterations, blockCount++ );
296 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
301 zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
335 ENSURES( masterSecretSize > 0 && \
340 status = extractKeyData( mechanismInfo->masterKeyContext,
346 masterSecretBuffer, masterSecretSize,
347 mechanismInfo->
hashAlgo, mechanismInfo->salt,
348 mechanismInfo->saltLength, 1 );
349 mechanismDeriveInfo.
hashParam = mechanismInfo->hashParam;
350 status = derivePKCS5( NULL, &mechanismDeriveInfo );
379 #define P12_BLOCKSIZE 64
388 #define P12_DSPSIZE ( P12_BLOCKSIZE + P12_BLOCKSIZE + \
389 ( P12_BLOCKSIZE * 3 ) )
401 int destIndex, srcIndex, carry = 1;
406 REQUIRES( destLen == P12_BLOCKSIZE );
407 REQUIRES( srcLen == P12_BLOCKSIZE );
410 for( destIndex = P12_BLOCKSIZE - 1, srcIndex = P12_BLOCKSIZE - 1;
411 destIndex >= 0; destIndex--, srcIndex-- )
413 const int value = dest[ destIndex ] + src[ srcIndex ] + carry;
414 dest[ destIndex ] =
intToByte( value & 0xFF );
430 int index, iterationCount;
439 memset( dest, 0,
min( 16, destLen ) );
441 for( index = 0, iterationCount = 0;
445 const int bytesToCopy =
min( srcLen, destLen - index );
447 memcpy( dest, src, bytesToCopy );
449 index += bytesToCopy;
451 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
464 IN_RANGE( P12_DSPSIZE, 512 )
const int dspMaxLen,
469 IN_RANGE( 1, P12_BLOCKSIZE )
const int saltLength,
470 IN_RANGE( 1, 3 )
const int diversifier )
474 int keyIndex, bmpIndex, i,
status;
477 assert(
isWritePtr( dspLen,
sizeof(
int ) ) );
481 REQUIRES( dspMaxLen >= P12_DSPSIZE && dspMaxLen <= 512 );
482 REQUIRES( diversifier >= 1 && diversifier <= 3 );
483 REQUIRES( saltLength >= 1 && saltLength <= P12_BLOCKSIZE );
488 memset( dsp, 0,
min( 16, dspMaxLen ) );
492 for( i = 0; i < P12_BLOCKSIZE; i++ )
494 dspPtr += P12_BLOCKSIZE;
497 status = expandData( dspPtr, P12_BLOCKSIZE, salt, saltLength );
500 dspPtr += P12_BLOCKSIZE;
504 for( keyIndex = 0, bmpIndex = 0;
506 keyIndex++, bmpIndex += 2 )
508 bmpString[ bmpIndex ] =
'\0';
509 bmpString[ bmpIndex + 1 ] = key[ keyIndex ];
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 ) );
518 status = expandData( dspPtr,
roundUp( bmpIndex, P12_BLOCKSIZE ),
519 bmpString, bmpIndex );
520 zeroise( bmpString, ( CRYPT_MAX_TEXTSIZE + 1 ) * 2 );
526 *dspLen = P12_BLOCKSIZE + P12_BLOCKSIZE + \
527 roundUp( bmpIndex, P12_BLOCKSIZE );
539 BYTE p12_DSP[ P12_DSPSIZE + 8 ];
541 BYTE *dataOutPtr = mechanismInfo->dataOut;
542 const BYTE *saltPtr = mechanismInfo->salt;
549 memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
551 getHashAtomicParameters( mechanismInfo->hashAlgo, 0, &hashFunctionAtomic,
557 status = initDSP( p12_DSP, P12_DSPSIZE, &dspLen, mechanismInfo->dataIn,
558 mechanismInfo->dataInLength, saltPtr + 1,
559 mechanismInfo->saltLength - 1,
byteToInt( *saltPtr ) );
564 for( keyIndex = 0, iterationCount = 0;
565 keyIndex < mechanismInfo->dataOutLength && \
567 keyIndex +=
hashSize, iterationCount++ )
569 const int noKeyBytes = \
570 ( mechanismInfo->dataOutLength - keyIndex >
hashSize ) ? \
571 hashSize : mechanismInfo->dataOutLength - keyIndex;
577 for( i = 1; i < mechanismInfo->iterations && \
583 ENSURES( i < FAILSAFE_ITERATIONS_MAX );
584 memcpy( dataOutPtr + keyIndex, p12_Ai, noKeyBytes );
590 status = expandData( p12_B, P12_BLOCKSIZE, p12_Ai, hashSize );
593 for( dspIndex = P12_BLOCKSIZE; dspIndex < dspLen;
594 dspIndex += P12_BLOCKSIZE )
596 status = add64( p12_DSP + dspIndex, P12_BLOCKSIZE,
597 p12_B, P12_BLOCKSIZE );
602 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
603 zeroise( p12_DSP, P12_DSPSIZE );
605 zeroise( p12_B, P12_BLOCKSIZE );
608 zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
640 int processedKeyLength;
652 BYTE *dataOutPtr = mechanismInfo->dataOut;
653 int md5HashSize, shaHashSize, counter = 0, keyIndex, iterationCount;
659 memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
661 getHashParameters(
CRYPT_ALGO_MD5, 0, &md5HashFunction, &md5HashSize );
662 getHashParameters(
CRYPT_ALGO_SHA1, 0, &shaHashFunction, &shaHashSize );
665 for( keyIndex = 0, iterationCount = 0;
666 keyIndex < mechanismInfo->dataOutLength && \
668 keyIndex += md5HashSize, iterationCount++ )
670 const int noKeyBytes = \
671 ( mechanismInfo->dataOutLength - keyIndex > md5HashSize ) ? \
672 md5HashSize : mechanismInfo->dataOutLength - keyIndex;
676 for( i = 0; i <= counter && i < 16; i++ )
677 counterData[ i ] =
intToByte(
'A' + counter );
682 shaHashFunction( hashInfo, NULL, 0, counterData, counter,
684 shaHashFunction( hashInfo, NULL, 0, mechanismInfo->dataIn,
687 mechanismInfo->salt, mechanismInfo->saltLength,
691 md5HashFunction( hashInfo, NULL, 0, mechanismInfo->dataIn,
697 memcpy( dataOutPtr + keyIndex, hash, noKeyBytes );
699 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
709 static
int tlsPrfInit(
INOUT TLS_PRF_INFO *prfInfo,
712 IN_BUFFER( saltLength )
const void *salt,
717 assert(
isWritePtr( prfInfo,
sizeof( TLS_PRF_INFO ) ) );
726 status = prfInit( prfInfo->hashFunction, prfInfo->hashFunctionAtomic,
727 prfInfo->initialHashInfo, prfInfo->hashSize,
729 &prfInfo->processedKeyLength, key, keyLength );
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,
740 prfInfo->processedKeyLength ) );
748 INOUT TLS_PRF_INFO *prfInfo,
749 IN_BUFFER( saltLength )
const void *salt,
757 assert(
isWritePtr( prfInfo,
sizeof( TLS_PRF_INFO ) ) );
760 REQUIRES( outLength > 0 && outLength <= prfInfo->hashSize && \
762 REQUIRES( saltLength >= 13 && saltLength <= 512 );
768 memcpy( hashInfo, prfInfo->initialHashInfo,
sizeof(
HASHINFO ) );
769 prfInfo->hashFunction( hashInfo, NULL, 0, prfInfo->hashA,
771 memcpy( AnHashInfo, hashInfo,
sizeof(
HASHINFO ) );
772 prfInfo->hashFunction( hashInfo, NULL, 0, salt, saltLength,
774 status = prfEnd( prfInfo->hashFunction, hashInfo, prfInfo->hashSize,
776 prfInfo->processedKeyLength );
786 memcpy( hashInfo, AnHashInfo,
sizeof(
HASHINFO ) );
787 status = prfEnd( prfInfo->hashFunction, hashInfo, prfInfo->hashSize,
788 prfInfo->hashA, prfInfo->hashSize,
789 prfInfo->processedKey, prfInfo->processedKeyLength );
800 out[ i ] ^= hash[ i ];
816 TLS_PRF_INFO md5Info, shaInfo;
817 BYTE *dataOutPtr = mechanismInfo->dataOut;
819 const int dataOutLength = mechanismInfo->dataOutLength;
820 const int sLen = ( mechanismInfo->dataInLength + 1 ) / 2;
821 int md5Index, shaIndex, iterationCount,
status;
827 memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
829 memset( &md5Info, 0,
sizeof( TLS_PRF_INFO ) );
830 getHashAtomicParameters(
CRYPT_ALGO_MD5, 0, &md5Info.hashFunctionAtomic,
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,
842 s1 = mechanismInfo->dataIn;
843 s2 = (
BYTE * ) mechanismInfo->dataIn + \
844 ( mechanismInfo->dataInLength - sLen );
851 memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
854 status = tlsPrfInit( &md5Info, s1, sLen, mechanismInfo->salt,
855 mechanismInfo->saltLength );
857 status = tlsPrfInit( &shaInfo, s2, sLen, mechanismInfo->salt,
858 mechanismInfo->saltLength );
861 zeroise( &md5Info,
sizeof( TLS_PRF_INFO ) );
862 zeroise( &shaInfo,
sizeof( TLS_PRF_INFO ) );
869 for( md5Index = shaIndex = 0, iterationCount = 0;
873 const int md5NoKeyBytes =
min( dataOutLength - md5Index, \
875 const int shaNoKeyBytes =
min( dataOutLength - shaIndex, \
878 status = tlsPrfHash( dataOutPtr + md5Index, md5NoKeyBytes,
879 &md5Info, mechanismInfo->salt,
880 mechanismInfo->saltLength );
883 if( shaNoKeyBytes > 0 )
888 status = tlsPrfHash( dataOutPtr + shaIndex, shaNoKeyBytes,
889 &shaInfo, mechanismInfo->salt,
890 mechanismInfo->saltLength );
895 md5Index += md5NoKeyBytes;
896 shaIndex += shaNoKeyBytes;
898 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
899 zeroise( &md5Info,
sizeof( TLS_PRF_INFO ) );
900 zeroise( &shaInfo,
sizeof( TLS_PRF_INFO ) );
903 zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
917 TLS_PRF_INFO shaInfo;
918 BYTE *dataOutPtr = mechanismInfo->dataOut;
919 const int dataOutLength = mechanismInfo->dataOutLength;
920 int keyIndex, iterationCount,
status;
926 memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
928 memset( &shaInfo, 0,
sizeof( TLS_PRF_INFO ) );
929 getHashAtomicParameters( mechanismInfo->hashAlgo,
930 mechanismInfo->hashParam,
931 &shaInfo.hashFunctionAtomic,
933 getHashParameters( mechanismInfo->hashAlgo, mechanismInfo->hashParam,
934 &shaInfo.hashFunction, NULL );
937 status = tlsPrfInit( &shaInfo, mechanismInfo->dataIn,
938 mechanismInfo->dataInLength, mechanismInfo->salt,
939 mechanismInfo->saltLength );
942 zeroise( &shaInfo,
sizeof( TLS_PRF_INFO ) );
947 for( keyIndex = 0, iterationCount = 0;
948 keyIndex < dataOutLength && \
950 keyIndex += shaInfo.hashSize, iterationCount++ )
952 const int noKeyBytes =
min( dataOutLength - keyIndex, \
955 status = tlsPrfHash( dataOutPtr + keyIndex, noKeyBytes, &shaInfo,
956 mechanismInfo->salt, mechanismInfo->saltLength );
960 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
961 zeroise( &shaInfo,
sizeof( TLS_PRF_INFO ) );
964 zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
978 #if defined( USE_PGP ) || defined( USE_PGPKEYS )
990 IN_BUFFER( saltLength )
const void *salt,
995 long count = *byteCount;
1000 assert(
isReadPtr( salt, saltLength ) );
1001 assert(
isWritePtr( byteCount,
sizeof(
int ) ) );
1009 ( preloadLength >= 0 && preloadLength <= 1 ) );
1013 memset( out, 0, outLength );
1018 if( preloadLength > 0 )
1028 if( count <= saltLength )
1040 if( count <= keyLength )
1063 long byteCount = ( long ) mechanismInfo->iterations << 6;
1064 long secondByteCount = 0;
1065 int hashSize, i, iterationCount, status =
CRYPT_OK;
1069 REQUIRES( mechanismInfo->iterations >= 0 && \
1074 memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
1076 getHashParameters( mechanismInfo->hashAlgo, 0, &hashFunction,
1079 REQUIRES( mechanismInfo->dataOutLength < 2 * hashSize );
1084 if( byteCount < PGP_SALTSIZE + mechanismInfo->dataInLength )
1085 byteCount =
PGP_SALTSIZE + mechanismInfo->dataInLength;
1090 if( hashSize < mechanismInfo->dataOutLength )
1091 secondByteCount = byteCount;
1099 for( i = 0, iterationCount = 0;
1102 i++, iterationCount++ )
1104 status = pgpPrfHash( mechanismInfo->dataOut,
1105 hashSize, hashFunction, hashInfo, hashSize,
1106 mechanismInfo->dataIn,
1107 mechanismInfo->dataInLength,
1108 mechanismInfo->salt,
1109 mechanismInfo->saltLength, &byteCount,
1112 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
1115 for( i = 0, iterationCount = 0;
1118 i++, iterationCount++ )
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,
1128 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MAX );
1133 zeroise( mechanismInfo->dataOut, mechanismInfo->dataOutLength );
1164 memset( mechanismInfo->dataOut, 0, mechanismInfo->dataOutLength );
1167 getHashAtomicParameters( mechanismInfo->hashAlgo, 0,
1168 &hashFunctionAtomic, &hashSize );
1169 getHashParameters( mechanismInfo->hashAlgo, 0, &hashFunction, NULL );
1170 hashFunction( hashInfo, NULL, 0, mechanismInfo->dataIn,
1173 mechanismInfo->dataOutLength, mechanismInfo->salt,
1178 for( iterations = 1; iterations < mechanismInfo->iterations && \
1182 mechanismInfo->dataOutLength,
1183 mechanismInfo->dataOut, hashSize );
1185 ENSURES( iterations < FAILSAFE_ITERATIONS_MAX );