36 #define MAX_PKCS11_DRIVERS 5
37 #define MAX_PKCS11_SLOTS 16
53 switch( (
int ) errorCode )
119 return( defaultError );
137 sMemOpen( &stream, buffer, 32 );
138 status = writeGeneralizedTime( &stream, theTime,
DEFAULT_TAG );
140 length = stell( &stream );
141 sMemDisconnect( &stream );
144 memcpy( buffer + 2, tokenInfo->
utcTime, 14 );
145 sMemConnect( &stream, buffer, length );
147 sMemDisconnect( &stream );
170 *pkcs11InfoPtrPtr = NULL;
176 return( cryptStatus );
180 (
void ** ) &deviceInfo,
183 return( cryptStatus );
184 *iCryptDevice = iLocalDevice;
185 *pkcs11InfoPtrPtr = deviceInfo->devicePKCS11;
194 static
int checkDriverBugs(
const PKCS11_INFO *pkcs11Info )
217 status = C_CreateObject( pkcs11Info->
hSession,
221 DEBUG_DIAG((
"PKCS #11 driver bug detected, attempt to log in to "
222 "the device apparently succeeded but logged-on "
223 "operation failed with CKR_USER_NOT_LOGGED_IN" ));
227 ENSURES( hObject != CK_OBJECT_NONE );
231 status = C_EncryptInit( pkcs11Info->
hSession,
233 C_DestroyObject( pkcs11Info->
hSession, hObject );
236 DEBUG_DIAG((
"PKCS #11 driver bug detected, attempt to use object "
237 "in logged-in device failed, this can happen when "
238 "using C_InitToken() rather than the proprietary "
239 "vendor-supplied utility to initialise the device" ));
263 PKCS11_INFO *pkcs11Info = deviceInfo->devicePKCS11;
301 status = C_GetTokenInfo( pkcs11Info->
slotID, &tokenInfo );
304 status = C_GetSlotInfo( pkcs11Info->
slotID, &slotInfo );
318 if( dataLength < pkcs11Info->minPinSize || \
331 status = C_Login( pkcs11Info->
hSession,
350 cryptStatus = checkDriverBugs( pkcs11Info );
402 if( dataLength < pkcs11Info->minPinSize || \
418 status = C_SetPIN( pkcs11Info->
hSession, pkcs11Info->defaultSSOPin,
428 if( dataLength < pkcs11Info->minPinSize || \
446 if( dataLength < pkcs11Info->minPinSize || \
452 if( pkcs11Info->
hSession != CK_OBJECT_NONE )
455 C_CloseSession( pkcs11Info->
hSession );
456 pkcs11Info->
hSession = CK_OBJECT_NONE;
460 memset( label,
' ', 32 );
461 status = C_InitToken( pkcs11Info->
slotID,
468 status = C_OpenSession( pkcs11Info->
slotID,
470 NULL_PTR, NULL_PTR, &hSession );
473 ENSURES( hSession != CK_OBJECT_NONE );
493 C_CloseSession( pkcs11Info->
hSession );
494 pkcs11Info->
hSession = CK_OBJECT_NONE;
499 memcpy( pkcs11Info->defaultSSOPin, data, dataLength );
508 cryptStatus = checkDriverBugs( pkcs11Info );
510 return( cryptStatus );
518 if( type == CRYPT_IATTRIBUTE_TIME )
521 time_t *timePtr = ( time_t * ) data, theTime;
525 status = C_GetTokenInfo( pkcs11Info->
slotID, &tokenInfo );
546 static
int genericEncrypt(
const PKCS11_INFO *pkcs11Info,
564 status = C_EncryptInit( pkcs11Info->
hSession,
566 contextInfoPtr->deviceObject );
568 status = C_Encrypt( pkcs11Info->
hSession, buffer, length,
569 buffer, &resultLen );
576 static
int genericDecrypt(
const PKCS11_INFO *pkcs11Info,
592 status = C_DecryptInit( pkcs11Info->
hSession,
594 contextInfoPtr->deviceObject );
596 status = C_Decrypt( pkcs11Info->
hSession, buffer, length,
597 buffer, &resultLen );
606 int genericEndFunction(
const CONTEXT_INFO *contextInfoPtr )
622 cryptStatus = getContextDeviceInfo( contextInfoPtr->
objectHandle,
623 &iCryptDevice, &pkcs11Info );
625 return( cryptStatus );
648 C_DestroyObject( pkcs11Info->
hSession, contextInfoPtr->deviceObject );
649 if( contextInfoPtr->altDeviceObject != CK_OBJECT_NONE )
651 C_DestroyObject( pkcs11Info->
hSession,
652 contextInfoPtr->altDeviceObject );
668 typedef enum { MECH_NONE, MECH_CONV, MECH_MAC, MECH_CONV_KEYGEN,
669 MECH_MAC_KEYGEN, MECH_LAST } GETMECH_TYPE;
689 for( i = 0; i <
length; i++ )
693 ch = ( ch & 0x55 ) + ( ( ch >> 1 ) & 0x55 );
694 ch = ( ch & 0x33 ) + ( ( ch >> 2 ) & 0x33 );
695 if( !( ( ch + ( ch >> 4 ) ) & 0x01 ) )
706 IN_RANGE( 4, 10 )
const int templateCount,
712 contextInfoPtr->capabilityInfo->cryptAlgo;
717 int *contextKeyLenPtr;
720 contextInfoPtr->capabilityInfo->keySize : keyLength;
728 REQUIRES( templateCount >= 4 && templateCount <= 10 );
732 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
733 &iCryptDevice, &pkcs11Info );
735 return( cryptStatus );
740 contextKeyPtr = contextInfoPtr->ctxConv->userKey;
741 contextKeyLenPtr = &contextInfoPtr->ctxConv->userKeyLength;
747 contextKeyPtr = contextInfoPtr->ctxMAC->userKey;
748 contextKeyLenPtr = &contextInfoPtr->ctxMAC->userKeyLength;
752 if( contextKeyPtr != key )
753 memcpy( contextKeyPtr, key, keyLength );
766 keySize = contextInfoPtr->capabilityInfo->maxKeySize;
773 adjustKeyParity( contextKeyPtr, keySize );
781 keyTemplate[ 7 ].pValue = contextKeyPtr;
782 keyTemplate[ 7 ].ulValueLen =
keySize;
785 status = C_CreateObject( pkcs11Info->
hSession, keyTemplate,
786 templateCount, &hObject );
790 ENSURES( hObject != CK_OBJECT_NONE );
792 contextInfoPtr->deviceObject = hObject;
796 zeroise( contextInfoPtr->ctxConv->userKey, keyLength );
797 contextInfoPtr->ctxConv->userKeyLength = 0;
801 return( cryptStatus );
811 const CK_KEY_TYPE type = contextInfoPtr->capabilityInfo->paramKeyType;
823 {
CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize }
825 const int templateCount = \
839 return( initKey( contextInfoPtr, keyTemplate, templateCount,
850 const CK_KEY_TYPE type = contextInfoPtr->capabilityInfo->paramKeyType;
862 {
CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize }
864 const int templateCount = \
878 return( initKey( contextInfoPtr, keyTemplate, templateCount,
902 IN_RANGE( 4, 10 )
const int templateCount,
907 CK_MECHANISM mechanism = { contextInfoPtr->capabilityInfo->paramKeyGen,
917 REQUIRES( templateCount >= 4 && templateCount <= 10 );
920 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
921 &iCryptDevice, &pkcs11Info );
923 return( cryptStatus );
926 status = C_GenerateKey( pkcs11Info->
hSession, &mechanism,
927 keyTemplate, templateCount, &hObject );
931 ENSURES( hObject != CK_OBJECT_NONE );
933 contextInfoPtr->deviceObject = hObject;
937 return( cryptStatus );
944 const int keySizeBits )
948 const CK_KEY_TYPE type = contextInfoPtr->capabilityInfo->paramKeyType;
961 {
CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize }
963 const int templateCount = \
977 return( generateKey( contextInfoPtr, keyTemplate, templateCount,
FALSE ) );
984 const int keySizeBits )
988 const CK_KEY_TYPE type = contextInfoPtr->capabilityInfo->paramKeyType;
1001 {
CKA_LABEL, contextInfoPtr->label, contextInfoPtr->labelSize }
1003 const int templateCount = \
1017 return( generateKey( contextInfoPtr, keyTemplate, templateCount,
TRUE ) );
1021 #define cipherGenerateKey NULL
1022 #define hmacGenerateKey NULL
1036 INOUT void *paramData )
1038 const int ivSize = contextInfoPtr->capabilityInfo->blockSize;
1041 assert(
isWritePtr( paramData,
sizeof(
int ) ) );
1044 if( contextInfoPtr->capabilityInfo->cryptAlgo ==
CRYPT_ALGO_RC2 )
1057 rc2params->ulEffectiveBits = 128;
1058 memcpy( rc2params->iv, contextInfoPtr->ctxConv->currentIV, ivSize );
1062 if( contextInfoPtr->capabilityInfo->cryptAlgo ==
CRYPT_ALGO_RC5 )
1068 rc5params->ulWordsize = 4;
1069 rc5params->ulRounds = 12;
1076 rc5params->ulWordsize = 4;
1077 rc5params->ulRounds = 12;
1078 rc5params->pIv = contextInfoPtr->ctxConv->currentIV;
1079 rc5params->ulIvLen = ivSize;
1095 CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
1098 BYTE paramDataBuffer[ 64 + 8 ];
1099 const int ivSize = contextInfoPtr->capabilityInfo->blockSize;
1100 int paramSize, cryptStatus;
1108 paramSize = initCryptParams( contextInfoPtr, ¶mDataBuffer );
1118 if(
needsIV( contextInfoPtr->ctxConv->mode ) && \
1121 mechanism.
pParameter = contextInfoPtr->ctxConv->currentIV;
1127 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1128 &iCryptDevice, &pkcs11Info );
1130 return( cryptStatus );
1132 cryptStatus = genericEncrypt( pkcs11Info, contextInfoPtr, &mechanism, buffer,
1136 if(
needsIV( contextInfoPtr->ctxConv->mode ) && \
1143 memcpy( contextInfoPtr->ctxConv->currentIV, \
1144 (
BYTE * ) buffer + length - ivSize, ivSize );
1149 return( cryptStatus );
1158 CK_MECHANISM mechanism = { mechanismType, NULL_PTR, 0 };
1162 const int ivSize = contextInfoPtr->capabilityInfo->blockSize;
1163 int paramSize, cryptStatus;
1171 paramSize = initCryptParams( contextInfoPtr, ¶mDataBuffer );
1182 if(
needsIV( contextInfoPtr->ctxConv->mode ) && \
1185 mechanism.
pParameter = contextInfoPtr->ctxConv->currentIV;
1188 if(
needsIV( contextInfoPtr->ctxConv->mode ) && \
1190 memcpy( ivBuffer, (
BYTE * ) buffer + length - ivSize, ivSize );
1193 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1194 &iCryptDevice, &pkcs11Info );
1196 return( cryptStatus );
1198 cryptStatus = genericDecrypt( pkcs11Info, contextInfoPtr, &mechanism, buffer,
1202 if(
needsIV( contextInfoPtr->ctxConv->mode ) && \
1209 memcpy( contextInfoPtr->ctxConv->currentIV, ivBuffer, ivSize );
1213 return( cryptStatus );
1230 return( cipherEncrypt( contextInfoPtr, buffer, length,
CKM_DES3_ECB ) );
1231 if( contextInfoPtr->capabilityInfo->cryptAlgo ==
CRYPT_ALGO_AES )
1232 return( cipherEncrypt( contextInfoPtr, buffer, length,
CKM_AES_ECB ) );
1233 return( cipherEncrypt( contextInfoPtr, buffer, length,
1234 getMechanism( MECH_CONV, contextInfoPtr->capabilityInfo->cryptAlgo,
1247 return( cipherEncrypt( contextInfoPtr, buffer, length,
1248 contextInfoPtr->capabilityInfo->paramDefaultMech ) );
1250 #if defined( USE_RC4 )
1261 if( contextInfoPtr->capabilityInfo->cryptAlgo ==
CRYPT_ALGO_RC4 )
1262 return( cipherEncrypt( contextInfoPtr, buffer, length,
CKM_RC4 ) );
1263 return( cipherEncrypt( contextInfoPtr, buffer, length,
1264 getMechanism( MECH_CONV, contextInfoPtr->capabilityInfo->cryptAlgo,
1279 return( cipherDecrypt( contextInfoPtr, buffer, length,
CKM_DES3_ECB ) );
1280 if( contextInfoPtr->capabilityInfo->cryptAlgo ==
CRYPT_ALGO_AES )
1281 return( cipherDecrypt( contextInfoPtr, buffer, length,
CKM_AES_ECB ) );
1282 return( cipherDecrypt( contextInfoPtr, buffer, length,
1283 getMechanism( MECH_CONV, contextInfoPtr->capabilityInfo->cryptAlgo,
1296 return( cipherDecrypt( contextInfoPtr, buffer, length,
1297 contextInfoPtr->capabilityInfo->paramDefaultMech ) );
1299 #if defined( USE_RC4 )
1310 if( contextInfoPtr->capabilityInfo->cryptAlgo ==
CRYPT_ALGO_RC4 )
1311 return( cipherDecrypt( contextInfoPtr, buffer, length,
CKM_RC4 ) );
1312 return( cipherDecrypt( contextInfoPtr, buffer, length,
1313 getMechanism( MECH_CONV, contextInfoPtr->capabilityInfo->cryptAlgo,
1337 CK_MECHANISM mechanism = { contextInfoPtr->capabilityInfo->paramDefaultMech,
1345 assert( ( length == 0 ) ||
isWritePtr( buffer, length ) );
1350 cryptStatus = getContextDeviceInfo( contextInfoPtr->objectHandle,
1351 &iCryptDevice, &pkcs11Info );
1353 return( cryptStatus );
1368 status = C_SignInit( pkcs11Info->
hSession, &mechanism,
1369 contextInfoPtr->deviceObject );
1377 status = C_SignUpdate( pkcs11Info->
hSession, buffer, length );
1382 status = C_SignFinal( pkcs11Info->
hSession,
1383 contextInfoPtr->ctxMAC->mac, &dummy );
1390 return( cryptStatus );
1401 static const PKCS11_MECHANISM_INFO mechanismInfoConv[] = {
1404 genericEndFunction, cipherInitKey, cipherGenerateKey,
1405 cipherEncryptECB, cipherDecryptECB, NULL, NULL },
1407 genericEndFunction, cipherInitKey, cipherGenerateKey,
1408 cipherEncryptCBC, cipherDecryptCBC, NULL, NULL },
1410 genericEndFunction, cipherInitKey, cipherGenerateKey,
1411 cipherEncryptECB, cipherDecryptECB, NULL, NULL },
1413 genericEndFunction, cipherInitKey, cipherGenerateKey,
1414 cipherEncryptCBC, cipherDecryptCBC, NULL, NULL },
1417 genericEndFunction, cipherInitKey, cipherGenerateKey,
1418 cipherEncryptECB, cipherDecryptECB, NULL, NULL },
1420 genericEndFunction, cipherInitKey, cipherGenerateKey,
1421 cipherEncryptCBC, cipherDecryptCBC, NULL, NULL },
1425 genericEndFunction, cipherInitKey, cipherGenerateKey,
1426 cipherEncryptOFB, cipherDecryptOFB, NULL, NULL },
1430 genericEndFunction, cipherInitKey, cipherGenerateKey,
1431 cipherEncryptECB, cipherDecryptECB, NULL, NULL },
1433 genericEndFunction, cipherInitKey, cipherGenerateKey,
1434 cipherEncryptCBC, cipherDecryptCBC, NULL, NULL },
1437 genericEndFunction, cipherInitKey, cipherGenerateKey,
1438 cipherEncryptECB, cipherDecryptECB, NULL, NULL },
1440 genericEndFunction, cipherInitKey, cipherGenerateKey,
1441 cipherEncryptCBC, cipherDecryptCBC, NULL, NULL },
1444 genericEndFunction, cipherInitKey, cipherGenerateKey,
1445 cipherEncryptCBC, cipherDecryptCBC, NULL, NULL },
1463 genericEndFunction, hmacInitKey, hmacGenerateKey,
1464 hmac, hmac, NULL, NULL },
1467 genericEndFunction, hmacInitKey, hmacGenerateKey,
1468 hmac, hmac, NULL, NULL },
1469 #ifdef USE_HMAC_RIPEMD160
1471 genericEndFunction, hmacInitKey, hmacGenerateKey,
1472 hmac, hmac, NULL, NULL },
1474 #ifdef USE_HMAC_SHA2
1476 genericEndFunction, hmacInitKey, hmacGenerateKey,
1477 hmac, hmac, NULL, NULL },
1480 { CKM_NONE, CKM_NONE, CKM_NONE,
CRYPT_ERROR, CRYPT_ERROR },
1481 { CKM_NONE, CKM_NONE, CKM_NONE,
CRYPT_ERROR, CRYPT_ERROR }
1485 const PKCS11_MECHANISM_INFO *getMechanismInfoConv(
OUT_LENGTH_SHORT int *mechanismInfoSize )
1487 assert(
isWritePtr( mechanismInfoSize,
sizeof(
int ) ) );
1490 PKCS11_MECHANISM_INFO );
1491 return( mechanismInfoConv );
1507 ( mechType == MECH_CONV_KEYGEN && \
1510 ( ( mechType == MECH_MAC || \
1511 mechType == MECH_MAC_KEYGEN ) && \
1517 for( i = 0; mechanismInfoConv[ i ].cryptAlgo != cryptAlgo && \
1518 mechanismInfoConv[ i ].cryptAlgo !=
CRYPT_ERROR && \
1523 ENSURES_EXT( ( i <
sizeof( mechanismInfoConv ) /
sizeof( PKCS11_MECHANISM_INFO ) && \
1524 mechanismInfoConv[ i ].cryptAlgo !=
CRYPT_ERROR ), CKM_NONE );
1525 if( mechType == MECH_MAC )
1526 return( mechanismInfoConv[ i ].mechanism );
1527 if( mechType == MECH_CONV_KEYGEN || mechType == MECH_MAC_KEYGEN )
1528 return( mechanismInfoConv[ i ].keygenMechanism );
1533 while( mechanismInfoConv[ i ].cryptMode != cryptMode && \
1534 mechanismInfoConv[ i ].cryptAlgo !=
CRYPT_ERROR && \
1539 ENSURES_EXT( ( i <
sizeof( mechanismInfoConv ) /
sizeof( PKCS11_MECHANISM_INFO ) && \
1540 mechanismInfoConv[ i ].cryptAlgo !=
CRYPT_ERROR ), CKM_NONE );
1542 return( mechanismInfoConv[ i ].mechanism );
1601 assert(
isReadPtr( name, nameLength ) );
1605 status = initPKCS11Init( deviceInfo, name, nameLength );
1608 deviceInfo->controlFunction = controlFunction;
1609 initPKCS11Read( deviceInfo );
1610 initPKCS11Write( deviceInfo );
1611 deviceInfo->mechanismFunctions = mechanismFunctions;
1612 deviceInfo->mechanismFunctionCount = \