32 #ifdef CONFIG_SLOW_CPU
33 #define MIN_KEYING_ITERATIONS 800
35 #define MIN_KEYING_ITERATIONS 5000
49 const void *newPrivKeyData,
55 assert(
isReadPtr( newPrivKeyData, newPrivKeyDataSize ) );
60 newPrivKeyOffset < newPrivKeyDataSize && \
66 if( newPrivKeyData != pkcs15infoPtr->privKeyData )
68 if( pkcs15infoPtr->privKeyData != NULL )
70 zeroise( pkcs15infoPtr->privKeyData,
71 pkcs15infoPtr->privKeyDataSize );
72 clFree(
"replacePrivkeyData", pkcs15infoPtr->privKeyData );
74 pkcs15infoPtr->privKeyData = (
void * ) newPrivKeyData;
79 pkcs15infoPtr->privKeyOffset = newPrivKeyOffset;
89 void **newPrivKeyDataPtr,
92 const void *origPrivKeyData,
100 assert(
isWritePtr( newPrivKeyDataPtr,
sizeof(
void * ) ) );
101 assert(
isWritePtr( newPrivKeyDataSize,
sizeof(
int ) ) );
102 assert( ( origPrivKeyData == NULL && origPrivKeyDataSize == 0 ) || \
103 isReadPtr( origPrivKeyData, origPrivKeyDataSize ) );
105 REQUIRES( ( origPrivKeyData == NULL && origPrivKeyDataSize == 0 ) || \
106 ( origPrivKeyData != NULL && origPrivKeyDataSize > 0 && \
109 REQUIRES( privKeyAttributeSize > 0 && \
114 *newPrivKeyDataPtr = NULL;
115 *newPrivKeyDataSize = 0;
118 *newPrivKeyDataSize = sizeofObject( privKeyAttributeSize + \
120 sizeofObject( privKeySize ) + \
122 ENSURES( *newPrivKeyDataSize > 0 && \
126 if( *newPrivKeyDataSize <= origPrivKeyDataSize )
128 *newPrivKeyDataPtr = (
void * ) origPrivKeyData;
134 newPrivKeyData =
clAlloc(
"calculatePrivkeyStorage", *newPrivKeyDataSize );
135 if( newPrivKeyData == NULL )
137 *newPrivKeyDataPtr = newPrivKeyData;
149 void *newPrivKeyData,
151 const int newPrivKeyDataSize,
163 assert(
isWritePtr( newPrivKeyData, newPrivKeyDataSize ) );
164 assert(
isReadPtr( privKeyAttributes, privKeyAttributeSize ) );
179 pkcs15infoPtr->privKeyDataSize ) );
180 memcpy( keyBuffer, (
BYTE * ) pkcs15infoPtr->privKeyData +
181 pkcs15infoPtr->privKeyOffset,
187 sMemOpen( &stream, newPrivKeyData, newPrivKeyDataSize );
188 writeConstructed( &stream, privKeyAttributeSize + \
190 sizeofObject( privKeyInfoSize ) ),
192 swrite( &stream, privKeyAttributes, privKeyAttributeSize );
193 writeConstructed( &stream, (
int ) sizeofObject( privKeyInfoSize ),
195 status = writeSequence( &stream, privKeyInfoSize );
198 newPrivKeyOffset = stell( &stream );
199 status = swrite( &stream, keyBuffer, privKeyInfoSize );
201 sMemDisconnect( &stream );
205 newPrivKeyDataSize ) ) );
208 replacePrivkeyData( pkcs15infoPtr, newPrivKeyData, newPrivKeyDataSize,
289 *iCryptContext = iLocalContext;
305 "authentication", 14 );
314 *iCryptContext = iLocalContext;
334 REQUIRES( attribute == CRYPT_IATTRIBUTE_ENCPARAMS || \
335 attribute == CRYPT_IATTRIBUTE_MACPARAMS );
340 if( attribute == CRYPT_IATTRIBUTE_ENCPARAMS )
341 status = writeCryptContextAlgoID( &stream, iCryptContext );
343 status = writeContextAlgoID( &stream, iCryptContext,
346 algorithmParamDataSize = stell( &stream );
347 sMemDisconnect( &stream );
353 setMessageData( &msgData, algorithmParamData, algorithmParamDataSize );
355 &msgData, attribute ) );
377 *iGenericSecret = *iCryptContext = *iMacContext =
CRYPT_ERROR;
397 status = createStrongAlgorithmContext( iCryptContext, iCryptOwner,
398 *iGenericSecret,
TRUE );
404 status = createStrongAlgorithmContext( iMacContext, iCryptOwner,
405 *iGenericSecret,
FALSE );
415 status = setAlgoParams( *iGenericSecret, *iCryptContext,
416 CRYPT_IATTRIBUTE_ENCPARAMS );
418 status = setAlgoParams( *iGenericSecret, *iMacContext,
419 CRYPT_IATTRIBUTE_MACPARAMS );
440 static
int writeWrappedSessionKey(
INOUT STREAM *stream,
452 assert(
isReadPtr( password, passwordLength ) );
468 status = createStrongAlgorithmContext( &iCryptContext, iCryptOwner,
492 iSessionKeyContext, iCryptContext );
498 writeSet( stream, exportedKeySize );
499 status = sMemGetDataBlockRemaining( stream, &dataPtr, &length );
502 status = iCryptExportKey( dataPtr, length, &exportedKeySize,
507 status = sSkip( stream, exportedKeySize );
518 static
int writeWrappedPrivateKey(
OUT_BUFFER( wrappedKeyMaxLength, \
519 *wrappedKeyLength ) \
522 const int wrappedKeyMaxLength,
533 assert(
isWritePtr( wrappedKey, wrappedKeyMaxLength ) );
534 assert(
isWritePtr( wrappedKeyLength,
sizeof(
int ) ) );
536 REQUIRES( wrappedKeyMaxLength >= 16 && \
545 memset( wrappedKey, 0,
min( 16, wrappedKeyMaxLength ) );
546 *wrappedKeyLength = 0;
550 NULL, 0, iPrivKeyContext, iCryptContext );
558 *wrappedKeyLength =
length;
564 wrappedKey, length );
589 sMemConnect( &encDataStream, wrappedKey, *wrappedKeyLength );
590 status = readSequence( &encDataStream, &length );
593 sMemDisconnect( &encDataStream );
601 sMemDisconnect( &encDataStream );
611 sMemDisconnect( &encDataStream );
617 zeroise( wrappedKey, wrappedKeyMaxLength );
618 DEBUG_DIAG((
"Private key data wasn't encrypted" ));
643 #ifdef USE_RSA_EXTRAPARAM
647 } PRIVKEY_WRITE_PARAMS;
649 #define initPrivKeyParams( params, genericCtx, cryptCtx, macCtx, keyAttr, keyAttrSize, pkcAlgo, modSize, keyTag ) \
650 memset( params, 0, sizeof( PRIVKEY_WRITE_PARAMS ) ); \
651 ( params )->iGenericContext = genericCtx; \
652 ( params )->iCryptContext = cryptCtx; \
653 ( params )->iMacContext = macCtx; \
654 ( params )->privKeyAttributes = keyAttr; \
655 ( params )->privKeyAttributeSize = keyAttrSize; \
656 ( params )->pkcCryptAlgo = pkcAlgo; \
657 ( params )->keyTypeTag = keyTag;
658 #ifdef USE_RSA_EXTRAPARAM
669 const PRIVKEY_WRITE_PARAMS *privKeyParams )
674 void *newPrivKeyData = pkcs15infoPtr->privKeyData;
675 const int privKeySize = sizeofObject(
KEYID_SIZE );
677 int extraDataSize = 0;
681 assert(
isReadPtr( privKeyParams,
sizeof( PRIVKEY_WRITE_PARAMS ) ) );
688 REQUIRES( privKeyParams->privKeyAttributeSize > 0 && \
691 #ifdef USE_RSA_EXTRAPARAM
695 ( !
isEccAlgo( privKeyParams->pkcCryptAlgo ) && \
697 privKeyParams->modulusSize <= CRYPT_MAX_PKCSIZE ) );
700 ( privKeyParams->keyTypeTag >= 0 && \
707 &msgData, CRYPT_IATTRIBUTE_DEVICESTORAGEID );
712 #ifdef USE_RSA_EXTRAPARAM
720 status = calculatePrivkeyStorage( &newPrivKeyData, &newPrivKeyDataSize,
721 pkcs15infoPtr->privKeyData,
722 pkcs15infoPtr->privKeyDataSize,
723 sizeofObject( privKeySize ),
724 privKeyParams->privKeyAttributeSize,
729 sMemOpen( &stream, newPrivKeyData, newPrivKeyDataSize );
732 writeConstructed( &stream, privKeyParams->privKeyAttributeSize + \
735 sizeofObject( privKeySize ) + \
737 privKeyParams->keyTypeTag );
738 swrite( &stream, privKeyParams->privKeyAttributes,
739 privKeyParams->privKeyAttributeSize );
740 writeConstructed( &stream,
742 sizeofObject( privKeySize + extraDataSize ) ),
744 status = writeSequence( &stream,
745 sizeofObject( privKeySize + extraDataSize ) );
747 newPrivKeyOffset = stell( &stream );
750 writeSequence( &stream, privKeySize );
751 status = writeOctetString( &stream, storageID,
KEYID_SIZE,
753 #ifdef USE_RSA_EXTRAPARAM
759 status = writeShortInteger( &stream,
767 sMemClose( &stream );
770 assert( newPrivKeyDataSize == stell( &stream ) );
771 sMemDisconnect( &stream );
773 newPrivKeyDataSize ) ) );
776 replacePrivkeyData( pkcs15infoPtr, newPrivKeyData,
777 newPrivKeyDataSize, newPrivKeyOffset );
786 IN_BUFFER( passwordLength )
const char *password,
788 const PRIVKEY_WRITE_PARAMS *privKeyParams,
790 const void *origPrivKeyData,
793 void **newPrivKeyData,
803 int privKeySize =
DUMMY_INIT, extraDataSize = 0, macSize;
804 int envelopeHeaderSize, envelopeContentSize;
806 int encryptedKeyDataLength,
status;
808 assert(
isReadPtr( password, passwordLength ) );
809 assert(
isReadPtr( privKeyParams,
sizeof( PRIVKEY_WRITE_PARAMS ) ) );
810 assert( ( origPrivKeyData == NULL && origPrivKeyDataSize == 0 ) || \
811 isReadPtr( origPrivKeyData, origPrivKeyDataSize ) );
812 assert(
isWritePtr( newPrivKeyData,
sizeof(
void * ) ) );
813 assert(
isWritePtr( newPrivKeyDataSize,
sizeof(
int ) ) );
814 assert(
isWritePtr( newPrivKeyOffset,
sizeof(
int ) ) );
821 REQUIRES( ( origPrivKeyData == NULL && origPrivKeyDataSize == 0 ) || \
822 ( origPrivKeyData != NULL && origPrivKeyDataSize > 0 && \
828 REQUIRES( privKeyParams->privKeyAttributeSize > 0 && \
831 #ifdef USE_RSA_EXTRAPARAM
835 ( !
isEccAlgo( privKeyParams->pkcCryptAlgo ) && \
837 privKeyParams->modulusSize <= CRYPT_MAX_PKCSIZE ) );
840 ( privKeyParams->keyTypeTag >= 0 && \
844 *newPrivKeyData = NULL;
845 *newPrivKeyDataSize = *newPrivKeyOffset = 0;
849 privKeyParams->iCryptContext );
857 ENSURES( privKeySize >= 16 && privKeySize <= 256 + MAX_PRIVATE_KEYSIZE );
865 macSize = sizeofObject( macSize );
872 sMemOpen( &stream, envelopeHeaderBuffer, 256 );
874 status = writeWrappedSessionKey( &stream, privKeyParams->iGenericContext,
875 iCryptOwner, password, passwordLength );
878 macDataOffset = stell( &stream );
881 privKeyParams->iGenericContext );
885 sMemClose( &stream );
888 "Couldn't write envelope header for wrapping private "
891 envelopeHeaderSize = stell( &stream );
892 envelopeContentSize = envelopeHeaderSize + privKeySize + macSize;
893 sMemDisconnect( &stream );
898 privKeySize = ( int ) sizeofObject( envelopeContentSize );
901 #ifdef USE_RSA_EXTRAPARAM
908 status = calculatePrivkeyStorage( newPrivKeyData, newPrivKeyDataSize,
909 origPrivKeyData, origPrivKeyDataSize,
911 privKeyParams->privKeyAttributeSize,
920 sMemConnect( &stream, envelopeHeaderBuffer + macDataOffset,
921 envelopeHeaderSize - macDataOffset );
922 readSequenceI( &stream, NULL );
923 status = readUniversal( &stream );
925 status = getStreamObjectLength( &stream, &macDataLength );
928 status = sMemGetDataBlock( &stream, &macDataPtr,
937 sMemDisconnect( &stream );
940 if( newPrivKeyData != origPrivKeyData )
941 clFree(
"writePrivateKey", newPrivKeyData );
944 "Couldn't MAC encryption attributes" ) );
947 sMemOpen( &stream, *newPrivKeyData, *newPrivKeyDataSize );
950 writeConstructed( &stream, privKeyParams->privKeyAttributeSize + \
951 sizeofObject( sizeofObject( privKeySize ) + \
953 privKeyParams->keyTypeTag );
954 swrite( &stream, privKeyParams->privKeyAttributes,
955 privKeyParams->privKeyAttributeSize );
956 writeConstructed( &stream,
957 sizeofObject( privKeySize + extraDataSize ),
959 status = writeSequence( &stream, privKeySize + extraDataSize );
961 *newPrivKeyOffset = stell( &stream );
964 sMemClose( &stream );
965 if( newPrivKeyData != origPrivKeyData )
966 clFree(
"writePrivateKey", newPrivKeyData );
969 "Couldn't write private key attributes" ) );
975 writeConstructed( &stream, envelopeContentSize,
977 status = swrite( &stream, envelopeHeaderBuffer, envelopeHeaderSize );
983 status = sMemGetDataBlockRemaining( &stream, &encryptedKeyDataPtr,
984 &encryptedKeyDataLength );
987 status = writeWrappedPrivateKey( encryptedKeyDataPtr,
988 encryptedKeyDataLength, &privKeySize,
990 privKeyParams->iCryptContext,
991 privKeyParams->iMacContext,
992 privKeyParams->pkcCryptAlgo );
995 status = sSkip( &stream, privKeySize );
998 sMemClose( &stream );
999 if( newPrivKeyData != origPrivKeyData )
1000 clFree(
"writePrivateKey", newPrivKeyData );
1002 ( status, errorInfo,
1003 "Couldn't write wrapped private key" ) );
1012 status = writeOctetString( &stream, macValue, msgData.
length,
1016 sMemClose( &stream );
1017 if( newPrivKeyData != origPrivKeyData )
1018 clFree(
"writePrivateKey", newPrivKeyData );
1020 ( status, errorInfo,
1021 "Couldn't write integrity check value for wrapped private "
1025 #ifdef USE_RSA_EXTRAPARAM
1030 status = writeShortInteger( &stream, privKeyParams->modulusSize,
1034 sMemClose( &stream );
1039 assert( *newPrivKeyDataSize == stell( &stream ) );
1040 sMemDisconnect( &stream );
1042 *newPrivKeyDataSize ) ) );
1058 const void *privKeyAttributes,
1066 PRIVKEY_WRITE_PARAMS privKeyParams;
1067 void *newPrivKeyData;
1071 assert( ( isStorageObject && password == NULL && passwordLength == 0 ) || \
1072 ( !isStorageObject &&
isReadPtr( password, passwordLength ) ) );
1073 assert(
isReadPtr( privKeyAttributes, privKeyAttributeSize ) );
1078 REQUIRES( ( isStorageObject && password == NULL && \
1079 passwordLength == 0 ) || \
1080 ( !isStorageObject && password != NULL && \
1083 REQUIRES( privKeyAttributeSize > 0 && \
1091 modulusSize <= CRYPT_MAX_PKCSIZE ) );
1095 status = getKeyTypeTag(
CRYPT_UNUSED, pkcCryptAlgo, &keyTypeTag );
1103 if( isStorageObject )
1107 privKeyAttributeSize, pkcCryptAlgo, modulusSize,
1109 status = addPrivateKeyMetadata( pkcs15infoPtr, iPrivKeyContext,
1114 ( status, errorInfo,
1115 "Couldn't write private key metadata" ) );
1122 status = createContexts( &iGenericContext, &iCryptContext, &iMacContext,
1127 ( status, errorInfo,
1128 "Couldn't create encryption contexts to protect the "
1133 initPrivKeyParams( &privKeyParams, iGenericContext, iCryptContext,
1134 iMacContext, privKeyAttributes,
1135 privKeyAttributeSize, pkcCryptAlgo, modulusSize,
1137 status = writePrivateKey( iPrivKeyContext, iCryptOwner, password,
1138 passwordLength, &privKeyParams,
1139 pkcs15infoPtr->privKeyData,
1140 pkcs15infoPtr->privKeyDataSize,
1141 &newPrivKeyData, &newPrivKeyDataSize,
1142 &newPrivKeyOffset, errorInfo );
1150 replacePrivkeyData( pkcs15infoPtr, newPrivKeyData,
1151 newPrivKeyDataSize, newPrivKeyOffset );
1162 IN_BUFFER( passwordLength )
const char *password,
1165 const void *privKeyAttributes,
1169 const BOOLEAN isStorageObject,
1175 BYTE envelopeHeaderBuffer[ 256 + 8 ];
1176 void *newPrivKeyData = pkcs15infoPtr->privKeyData;
1178 int privKeySize =
DUMMY_INIT, extraDataSize = 0;
1182 assert( ( isStorageObject && password == NULL && passwordLength == 0 ) || \
1183 ( !isStorageObject &&
isReadPtr( password, passwordLength ) ) );
1184 assert(
isReadPtr( privKeyAttributes, privKeyAttributeSize ) );
1189 REQUIRES( ( isStorageObject && password == NULL && \
1190 passwordLength == 0 ) || \
1191 ( !isStorageObject && password != NULL && \
1194 REQUIRES( privKeyAttributeSize > 0 && \
1202 modulusSize <= CRYPT_MAX_PKCSIZE ) );
1206 status = getKeyTypeTag(
CRYPT_UNUSED, pkcCryptAlgo, &keyTypeTag );
1214 if( isStorageObject )
1216 status = addPrivateKeyMetadata( pkcs15infoPtr, iCryptContext,
1217 privKeyAttributes, privKeyAttributeSize,
1218 pkcCryptAlgo, modulusSize, keyTypeTag );
1222 ( status, errorInfo,
1223 "Couldn't write private key metadata" ) );
1233 status = createStrongEncryptionContext( &iSessionKeyContext, iCryptOwner );
1243 ( status, errorInfo,
1244 "Couldn't create session key to wrap private key" ) );
1249 iSessionKeyContext );
1260 ENSURES( privKeySize <= 256 + MAX_PRIVATE_KEYSIZE );
1267 sMemOpen( &stream, envelopeHeaderBuffer, 256 );
1269 status = writeWrappedSessionKey( &stream, iSessionKeyContext,
1270 iCryptOwner, password, passwordLength );
1274 iSessionKeyContext );
1277 sMemClose( &stream );
1280 ( status, errorInfo,
1281 "Couldn't write envelope header for wrapping private "
1284 envelopeHeaderSize = stell( &stream );
1285 envelopeContentSize = envelopeHeaderSize +
privKeySize;
1286 sMemDisconnect( &stream );
1291 privKeySize = ( int ) sizeofObject( privKeySize + envelopeHeaderSize );
1294 #ifdef USE_RSA_EXTRAPARAM
1301 status = calculatePrivkeyStorage( pkcs15infoPtr, &newPrivKeyData,
1302 &newPrivKeyDataSize, privKeySize,
1303 privKeyAttributeSize,
1311 sMemOpen( &stream, newPrivKeyData, newPrivKeyDataSize );
1314 writeConstructed( &stream, privKeyAttributeSize + \
1315 sizeofObject( sizeofObject( privKeySize ) + \
1318 swrite( &stream, privKeyAttributes, privKeyAttributeSize );
1319 writeConstructed( &stream, sizeofObject( privKeySize + extraDataSize ),
1321 status = writeSequence( &stream, privKeySize + extraDataSize );
1323 newPrivKeyOffset = stell( &stream );
1326 sMemClose( &stream );
1328 if( newPrivKeyData != pkcs15infoPtr->privKeyData )
1329 clFree(
"addPrivateKey", newPrivKeyData );
1331 ( status, errorInfo,
1332 "Couldn't write private key attributes" ) );
1340 status = swrite( &stream, envelopeHeaderBuffer, envelopeHeaderSize );
1346 status = sMemGetDataBlockRemaining( &stream, &dataPtr, &length );
1348 status = writeWrappedPrivateKey( dataPtr, length, &privKeySize,
1349 iCryptContext, iSessionKeyContext,
1353 status = sSkip( &stream, privKeySize );
1354 #ifdef USE_RSA_EXTRAPARAM
1359 status = writeShortInteger( &stream, modulusSize,
DEFAULT_TAG );
1365 sMemClose( &stream );
1367 ( status, errorInfo,
1368 "Couldn't wrap private key using session key" ) );
1370 assert( newPrivKeyDataSize == stell( &stream ) );
1371 sMemDisconnect( &stream );
1373 newPrivKeyDataSize ) ) );
1376 replacePrivkeyData( pkcs15infoPtr, newPrivKeyData,
1377 newPrivKeyDataSize, newPrivKeyOffset );