28 #if defined( USE_PGP ) || defined( USE_PGPKEYS )
43 int checksum = 0, i,
status;
53 checksum += dataPtr[ i ];
56 sMemOpen( &stream, dataPtr + keyDataLength, dataLength - keyDataLength );
57 status = writeUint16( &stream, checksum );
58 sMemDisconnect( &stream );
66 const int dataLength )
69 int checksum = 0, storedChecksum, i;
80 sMemConnect( &stream, data, dataLength );
83 const int ch = sgetc( &stream );
86 sMemDisconnect( &stream );
91 storedChecksum = readUint16( &stream );
92 sMemDisconnect( &stream );
94 return( storedChecksum == checksum );
132 if( !pgpVerifyChecksum( data + 1, dataLength - 1 ) )
174 BYTE dataSample[ 16 + 8 ];
175 const void *samplePtr = wrappedData + ( wrappedDataLength / 2 );
179 assert(
isWritePtr( wrappedData, wrappedDataLength ) );
183 REQUIRES( wrappedData[ 0 ] == 0x00 && \
184 ( wrappedData[ 1 ] == 0x01 || wrappedData[ 1 ] == 0x02 ) );
187 memcpy( dataSample, samplePtr, 16 );
195 setDLPParams( &dlpParams, wrappedData, wrappedDataLength,
196 wrappedData, mechanismInfo->wrappedDataLength );
203 mechanismInfo->wrappedDataLength = dlpParams.
outLen;
211 mechanismInfo->wrappedDataLength = wrappedDataLength;
213 if(
cryptStatusOK( status ) && !memcmp( dataSample, samplePtr, 16 ) )
226 zeroise( wrappedData, wrappedDataLength );
240 const int dataInLength,
248 assert(
isWritePtr( dataOutLength,
sizeof(
int ) ) );
253 dataInLength <= dataMaxLength && \
257 memset( data, 0,
min( 16, dataMaxLength ) );
274 *dataOutLength = dlpParams.
outLen;
280 status = adjustPKCS1Data( data, dataMaxLength,
281 mechanismInfo->wrappedData,
290 *dataOutLength = dataInLength;
296 zeroise( data, dataMaxLength );
315 const int messageLen )
318 const int padSize = dataMaxLen - ( messageLen + 3 );
322 assert(
isWritePtr( dataLength,
sizeof(
int ) ) );
329 memset( data, 0,
min( 16, dataMaxLen ) );
336 if( messageLen > dataMaxLen - 11 )
339 ENSURES( padSize >= 8 && messageLen + padSize + 3 <= dataMaxLen );
353 CRYPT_IATTRIBUTE_RANDOM_NZ );
359 data[ 2 + padSize ] = 0;
360 *dataLength = 2 + padSize + 1;
369 const int dataLength,
375 assert(
isWritePtr( padSize,
sizeof(
int ) ) );
404 if( data[ 0 ] != 0x00 || data[ 1 ] != 0x02 )
406 for( length = 2, ch = 0xFF;
408 ( ch =
byteToInt( data[ length ] ) ) != 0x00;
410 if( ch != 0x00 || length < 11 )
417 assert( checkEntropy( data + 2, length - 1 ) );
440 BYTE *wrappedData = mechanismInfo->wrappedData, *dataPtr;
451 if( mechanismInfo->wrappedData != NULL )
453 memset( mechanismInfo->wrappedData, 0,
454 mechanismInfo->wrappedDataLength );
458 status = getPkcAlgoParams( mechanismInfo->wrapContext, &cryptAlgo,
465 if( mechanismInfo->wrappedData == NULL )
475 mechanismInfo->wrappedDataLength = \
477 10 + ( 2 * ( length + 1 ) ) : length;
482 if( length > mechanismInfo->wrappedDataLength )
488 payloadSize = mechanismInfo->keyDataLength;
509 status = cryptlibToPgpAlgo( sessionKeyAlgo, &pgpAlgoID );
519 if( payloadSize >= length )
523 status = generatePkcs1DataBlock( wrappedData, length, &dataBlockSize,
527 zeroise( wrappedData, length );
530 ENSURES( dataBlockSize + payloadSize == length );
533 dataPtr = wrappedData + dataBlockSize;
537 status = extractKeyData( mechanismInfo->keyContext, dataPtr,
538 payloadSize,
"keydata", 7 );
542 memcpy( dataPtr, mechanismInfo->keyData, payloadSize );
548 status = extractKeyData( mechanismInfo->keyContext, dataPtr,
549 payloadSize - 3,
"keydata", 7 );
552 status = pgpGenerateChecksum( dataPtr, payloadSize - 1,
553 payloadSize - ( 1 + UINT16_SIZE ) );
563 zeroise( wrappedData, length );
568 return( pkcWrapData( mechanismInfo, wrappedData, length,
580 const BYTE *payloadPtr;
589 memset( mechanismInfo->keyData, 0, mechanismInfo->keyDataLength );
592 status = getPkcAlgoParams( mechanismInfo->wrapContext, &cryptAlgo,
607 status = recoverPkcs1DataBlock( decryptedData, length, &dataBlockSize );
613 payloadPtr = decryptedData + dataBlockSize;
614 length -= dataBlockSize;
623 status = pgpExtractKey( &mechanismInfo->keyContext, payloadPtr,
651 if( length > mechanismInfo->keyDataLength )
655 memcpy( mechanismInfo->keyData, payloadPtr, length );
656 mechanismInfo->keyDataLength =
length;
676 return( pkcs1Wrap( mechanismInfo,
689 return( pkcs1Unwrap( mechanismInfo,
690 ( mechanismInfo->keyData != NULL ) ? \
739 static const LHASH_INFO
FAR_BSS lHashInfo[] = {
741 "\xDA\x39\xA3\xEE\x5E\x6B\x4B\x0D\x32\x55\xBF\xEF\x95\x60\x18\x90"
742 "\xAF\xD8\x07\x09", 20 },
744 "\xE3\xB0\xC4\x42\x98\xFC\x1C\x14\x9A\xFB\xF4\xC8\x99\x6F\xB9\x24"
745 "\x27\xAE\x41\xE4\x64\x9B\x93\x4C\xA4\x95\x99\x1B\x78\x52\xB8\x55", 32 },
749 "\xCF\x83\xE1\x35\x7E\xEF\xB8\xBD\xF1\x54\x28\x50\xD6\x6D\x80\x07"
750 "\xD6\x20\xE4\x05\x0B\x57\x15\xDC\x83\xF4\xA9\x21\xD3\x6C\xE9\xCE"
751 "\x47\xD0\xD1\x3C\x5D\x85\xF2\xB0\xFF\x83\x18\xD2\x87\x7E\xEC\x2F"
752 "\x63\xB9\x31\xBD\x47\x41\x7A\x81\xA5\x38\x32\x7A\xF9\x27\xDA\x3E", 64 },
758 static
int getOaepHash(
OUT_BUFFER_OPT( lHashMaxLen, *lHashLen )
void *lHash,
766 assert( ( lHash == NULL && lHashMaxLen == 0 ) || \
769 REQUIRES( ( lHash == NULL && lHashMaxLen == 0 ) || \
782 if( lHashInfo[ i ].hashAlgo != hashAlgo )
784 if( hashParam != 0 && lHashInfo[ i ].lHashSize != hashParam )
787 memcpy( lHash, lHashInfo[ i ].lHash, lHashInfo[ i ].lHashSize );
788 *lHashLen = lHashInfo[ i ].lHashSize;
799 #define getOaepHashSize( hashLen, hashAlgo, hashParam ) \
800 getOaepHash( NULL, 0, hashLen, hashAlgo, hashParam )
815 BYTE *maskOutPtr = mask;
816 int hashSize, maskIndex, blockCount = 0, iterationCount;
826 getHashParameters( hashAlgo, hashParam, &hashFunction, &hashSize );
831 memset( countBuffer, 0, 4 );
834 for( maskIndex = 0, iterationCount = 0;
838 const int noMaskBytes = ( maskLen - maskIndex >
hashSize ) ? \
839 hashSize : maskLen - maskIndex;
842 countBuffer[ 3 ] = (
BYTE ) blockCount++;
844 hashFunction( hashInfo, maskBuffer, hashSize, countBuffer, 4,
846 memcpy( maskOutPtr, maskBuffer, noMaskBytes );
848 ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );
891 const int messageLen,
898 BYTE *maskedSeed, *db;
902 assert(
isReadPtr( message, messageLen ) );
908 REQUIRES( seedLen >= 16 && seedLen <= dataMaxLen && \
911 getOaepHashSize( &i, hashAlgo, hashParam ) ) && seedLen == i );
926 if( 1 + seedLen + seedLen + 1 + 1 + messageLen > dataMaxLen )
930 maskedSeed = data + 1;
931 db = maskedSeed + seedLen;
932 dbLen = dataMaxLen - ( 1 + seedLen );
934 ENSURES( dbLen >= 16 && dbLen >= messageLen + 1 && \
935 1 + seedLen + dbLen <= dataMaxLen );
938 memset( db, 0, dbLen );
943 db[ dbLen - messageLen - 1 ] = 0x01;
944 memcpy( db + dbLen - messageLen, message, messageLen );
949 status = mgf1( dbMask, dbLen, seed, seedLen, hashAlgo, hashParam );
953 for( i = 0; i < dbLen; i++ )
954 db[ i ] ^= dbMask[ i ];
957 status = mgf1( seedMask, seedLen, db, dbLen, hashAlgo, hashParam );
961 for( i = 0; i < seedLen; i++ )
964 intToByte( ( (
const BYTE * ) seed )[ i ] ^ seedMask[ i ] );
977 static
int recoverOaepDataBlock(
OUT_BUFFER( messageMaxLen, *messageLen ) \
991 assert(
isWritePtr( message, messageMaxLen ) );
992 assert(
isWritePtr( messageLen,
sizeof(
int ) ) );
1002 memset( message, 0,
min( 16, messageMaxLen ) );
1009 status = getOaepHashSize( &seedLen, hashAlgo, hashParam );
1015 memcpy( dataBuffer, data, dataLen );
1018 seed = dataBuffer + 1;
1019 db = seed + seedLen;
1020 dbLen = dataLen - ( 1 + seedLen );
1022 ENSURES( dbLen >= 16 && 1 + seedLen + dbLen <= dataLen );
1025 status = mgf1( seedMask, seedLen, db, dbLen, hashAlgo, hashParam );
1029 for( i = 0; i < seedLen; i++ )
1030 seed[ i ] ^= seedMask[ i ];
1033 status = mgf1( dbMask, dbLen, seed, seedLen, hashAlgo, hashParam );
1037 for( i = 0; i < dbLen; i++ )
1038 db[ i ] ^= dbMask[ i ];
1061 if( 1 + seedLen + seedLen + 1 + 1 +
MIN_KEYSIZE > dataLen )
1075 if( dataBuffer[ 0 ] != 0x00 || \
1076 !compareDataConstTime( db, dbMask, seedLen ) )
1078 for( i = seedLen; i < dbLen && db[ i ] == 0x00; i++ );
1079 if( i <= seedLen || i >= dbLen || db[ i++ ] != 0x01 )
1084 if( length > messageMaxLen )
1088 memcpy( message, db + i, length );
1112 if( mechanismInfo->wrappedData != NULL )
1114 memset( mechanismInfo->wrappedData, 0,
1115 mechanismInfo->wrappedDataLength );
1119 status = getOaepHashSize( &seedLen, mechanismInfo->auxInfo, 0 );
1124 status = getPkcAlgoParams( mechanismInfo->wrapContext, &cryptAlgo,
1131 if( mechanismInfo->wrappedData == NULL )
1141 mechanismInfo->wrappedDataLength = \
1143 10 + ( 2 * ( length + 1 ) ) : length;
1160 CRYPT_IATTRIBUTE_RANDOM );
1166 status = extractKeyData( mechanismInfo->keyContext, payload, payloadSize,
1170 status = generateOaepDataBlock( mechanismInfo->wrappedData, length,
1171 payload, payloadSize, seed, seedLen,
1172 mechanismInfo->auxInfo, 0 );
1180 return( pkcWrapData( mechanismInfo, mechanismInfo->wrappedData, length,
1199 status = getPkcAlgoParams( mechanismInfo->wrapContext, &cryptAlgo,
1211 status = getOaepHashSize( &length, mechanismInfo->auxInfo, 0 );
1217 &length, length, FALSE,
1224 decryptedData, length,
1225 mechanismInfo->auxInfo, 0 );
1251 void testOAEP(
void )
1253 const BYTE seed[] = { 0xaa, 0xfd, 0x12, 0xf6, 0x59, 0xca, 0xe6, 0x34,
1254 0x89, 0xb4, 0x79, 0xe5, 0x07, 0x6d, 0xde, 0xc2,
1255 0xf0, 0x6c, 0xb5, 0x8f };
1256 const BYTE message[] = { 0xd4, 0x36, 0xe9, 0x95, 0x69, 0xfd, 0x32, 0xa7,
1257 0xc8, 0xa0, 0x5b, 0xbc, 0x90, 0xd3, 0x2c, 0x49 };
1259 int seedLen, outLen,
status;
1263 memset( buffer,
'*', 1024 );
1265 status = generateOaepDataBlock( buffer, 128, message, 16, seed, seedLen,
1267 status = recoverOaepDataBlock( outMessage, 128, &outLen, buffer, 128,
1269 if( outLen != 16 || memcmp( message, outMessage, outLen ) )