1 /**************************************************************************** 2 * * 3 * cryptlib PKCS #11 API Interface * 4 * Copyright Peter Gutmann 1998-2006 * 5 * * 6 ****************************************************************************/ 7 8 #ifdef USE_PKCS11 9 10 /* Before we can include the PKCS #11 headers we need to define a few OS- 11 specific things that are required by the headers */ 12 13 #ifdef __WINDOWS__ 14 #ifdef __WIN16__ 15 #pragma pack( 1 ) /* Struct packing */ 16 #define CK_PTR far * /* Pointer type */ 17 #define CK_DEFINE_FUNCTION( returnType, name ) \ 18 returnType __export _far _pascal name 19 #define CK_DECLARE_FUNCTION( returnType, name ) \ 20 returnType __export _far _pascal name 21 #define CK_DECLARE_FUNCTION_POINTER( returnType, name ) \ 22 returnType __export _far _pascal (* name) 23 #define CK_CALLBACK_FUNCTION( returnType, name ) \ 24 returnType (_far _pascal * name) 25 #else 26 #pragma pack( push, cryptoki, 1 ) /* Struct packing */ 27 #define CK_PTR * /* Pointer type */ 28 #define CK_DEFINE_FUNCTION( returnType, name ) \ 29 returnType __declspec( dllexport ) name 30 #define CK_DECLARE_FUNCTION( returnType, name ) \ 31 returnType __declspec( dllimport ) name 32 #define CK_DECLARE_FUNCTION_POINTER( returnType, name ) \ 33 returnType __declspec( dllimport ) (* name) 34 #define CK_CALLBACK_FUNCTION( returnType, name ) \ 35 returnType (* name) 36 #endif /* Win16 vs.Win32 */ 37 #else 38 #define CK_PTR * /* Pointer type */ 39 #define CK_DEFINE_FUNCTION( returnType, name ) \ 40 returnType name 41 #define CK_DECLARE_FUNCTION( returnType, name ) \ 42 returnType name 43 #define CK_DECLARE_FUNCTION_POINTER( returnType, name ) \ 44 returnType (* name) 45 #define CK_CALLBACK_FUNCTION( returnType, name ) \ 46 returnType (* name) 47 #endif /* __WINDOWS__ */ 48 #ifndef NULL_PTR 49 #define NULL_PTR NULL 50 #endif /* NULL_PTR */ 51 52 /* Pull in the PKCS #11 headers */ 53 54 #if defined( INC_ALL ) 55 #include "pkcs11.h" 56 #else 57 #include "device/pkcs11.h" 58 #endif /* Compiler-specific includes */ 59 60 /* The use of dynamically bound function pointers vs.statically linked 61 functions requires a bit of sleight of hand since we can't give the 62 pointers the same names as prototyped functions. To get around this we 63 redefine the actual function names to the names of the pointers */ 64 65 #define C_CloseSession ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_CloseSession 66 #define C_CreateObject ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_CreateObject 67 #define C_Decrypt ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_Decrypt 68 #define C_DecryptInit ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_DecryptInit 69 #define C_DeriveKey ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_DeriveKey 70 #define C_DestroyObject ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_DestroyObject 71 #define C_Digest ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_Digest 72 #define C_DigestInit ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_DigestInit 73 #define C_Encrypt ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_Encrypt 74 #define C_EncryptInit ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_EncryptInit 75 #define C_Finalize ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_Finalize 76 #define C_FindObjects ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_FindObjects 77 #define C_FindObjectsFinal ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_FindObjectsFinal 78 #define C_FindObjectsInit ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_FindObjectsInit 79 #define C_GenerateKey ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_GenerateKey 80 #define C_GenerateKeyPair ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_GenerateKeyPair 81 #define C_GenerateRandom ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_GenerateRandom 82 #define C_GetAttributeValue ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_GetAttributeValue 83 #define C_GetMechanismInfo ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_GetMechanismInfo 84 #define C_GetInfo ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_GetInfo 85 #define C_GetSlotInfo ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_GetSlotInfo 86 #define C_GetSlotList ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_GetSlotList 87 #define C_GetTokenInfo ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_GetTokenInfo 88 #define C_Initialize ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_Initialize 89 #define C_InitPIN ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_InitPIN 90 #define C_InitToken ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_InitToken 91 #define C_Login ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_Login 92 #define C_Logout ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_Logout 93 #define C_OpenSession ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_OpenSession 94 #define C_SetAttributeValue ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_SetAttributeValue 95 #define C_SetPIN ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_SetPIN 96 #define C_Sign ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_Sign 97 #define C_SignFinal ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_SignFinal 98 #define C_SignInit ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_SignInit 99 #define C_SignUpdate ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_SignUpdate 100 #define C_Verify ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_Verify 101 #define C_VerifyInit ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_VerifyInit 102 #define C_WrapKey ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_WrapKey 103 #define C_UnwrapKey ( ( CK_FUNCTION_LIST_PTR )( pkcs11Info->functionListPtr ) )->C_UnwrapKey 104 105 /* Mapping of PKCS #11 device capabilities to cryptlib capabilities. We 106 don't use the hash functions because they're always *much* faster in 107 software on the host system (as are the symmetric ciphers in most 108 cases) */ 109 110 typedef RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 111 int ( *P11_END_FUNCTION )( INOUT CONTEXT_INFO *contextInfoPtr ); 112 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 113 int ( *P11_INITKEY_FUNCTION )( INOUT CONTEXT_INFO *contextInfoPtr, 114 IN_BUFFER( keyLength ) const void *key, 115 IN_LENGTH_SHORT const int keyLength ); 116 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 117 int ( *P11_GENERATEKEY_FUNCTION )( INOUT CONTEXT_INFO *contextInfoPtr, \ 118 IN_LENGTH_SHORT const int keySizeBits ); 119 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 120 int ( *P11_ENCRYPT_FUNCTION )( INOUT CONTEXT_INFO *contextInfoPtr, 121 INOUT_BUFFER_FIXED( length ) BYTE *buffer, 122 IN_LENGTH_Z int length ); 123 /* Length may be zero for hash functions */ 124 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 125 int ( *P11_DECRYPT_FUNCTION )( INOUT CONTEXT_INFO *contextInfoPtr, 126 INOUT_BUFFER_FIXED( length ) BYTE *buffer, 127 IN_LENGTH int length ); 128 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 129 int ( *P11_SIGN_FUNCTION )( INOUT CONTEXT_INFO *contextInfoPtr, 130 INOUT_BUFFER_FIXED( length ) BYTE *buffer, 131 IN_LENGTH_SHORT_MIN( MIN_PKCSIZE ) int length ); 132 133 typedef struct { 134 /* Mapping information. The mechanism type is the specific mechanism for 135 this algorithm and mode, for example CKM_DES_CFB64 (= { CRYPT_ALGO_DES, 136 CRYPT_MODE_CFB }, the default mechanism is the default mechanism for 137 the algorithm (without taking the mode into account), for example 138 CKM_DES_CBC. The reason why we specify both is that cryptlib records 139 a single capability for each algorithm while PKCS #11 has distinct 140 parameters for each mode of an algorithm. By recording the most common 141 algorithm+mode combination (CBC mode), we can short-circuit having to 142 search the PKCS #11 mechanism table for the common case where that mode 143 is being used */ 144 const CK_MECHANISM_TYPE mechanism; /* Mechanism type for this algo/mode */ 145 const CK_MECHANISM_TYPE keygenMechanism; /* Supplementary keygen mechanism */ 146 const CK_MECHANISM_TYPE defaultMechanism;/* Default mechanism for this algo */ 147 const CK_FLAGS requiredFlags; /* Required flags for this mechanism */ 148 const CRYPT_ALGO_TYPE cryptAlgo; /* cryptlib algo and mode */ 149 const CRYPT_MODE_TYPE cryptMode; 150 151 /* Equivalent PKCS #11 parameters */ 152 const CK_KEY_TYPE keyType; /* PKCS #11 key type */ 153 154 /* Function pointers */ 155 P11_END_FUNCTION endFunction; 156 P11_INITKEY_FUNCTION initKeyFunction; 157 P11_GENERATEKEY_FUNCTION generateKeyFunction; 158 P11_ENCRYPT_FUNCTION encryptFunction; 159 P11_DECRYPT_FUNCTION decryptFunction; 160 P11_SIGN_FUNCTION signFunction, sigCheckFunction; 161 } PKCS11_MECHANISM_INFO; 162 163 /* Encryption contexts can store extra implementation-dependant parameters. 164 The following macro maps these generic parameter names to the PKCS #11 165 values */ 166 167 #define paramKeyType param1 168 #define paramKeyGen param2 169 #define paramDefaultMech param3 170 171 /* Special non-mechanism/object types used as an EOF markers. Unfortunately 172 PKCS #11 uses all mechanisms down to 0 and it's an unsigned value so 173 there's no facility for a CKM_NONE value along the lines of CRYPT_ERROR, 174 and similarly object handles can also take any value, the best that we 175 can do is use CRYPT_ERROR (all ones) and hope that nothing decides to 176 return an object handle with this value. With mechanisms we're a bit 177 safer, it'd have to be some weird vendor-defined value to match 178 CKM_NONE */ 179 180 #define CKM_NONE ( ( CK_MECHANISM_TYPE ) CRYPT_ERROR ) 181 #define CK_OBJECT_NONE ( ( CK_OBJECT_HANDLE ) CRYPT_ERROR ) 182 #define CKA_NONE ( ( CK_ATTRIBUTE_TYPE ) CRYPT_ERROR ) 183 #define CKF_NONE 0 184 185 /* The HMAC mechanisms in PKCS #11 don't work because they have to be keyed 186 with generic secret keys (rather than specific HMAC keys) but generic 187 secret keys can't be used with HMAC operations. There are two possible 188 workarounds for this, either ignore the restrictions on generic secret 189 keys so that they can be used with HMAC objects or define vendor-specific 190 HMAC mechanisms and keys. The latter approach is used by nCipher, who 191 define their own CKA/CKM/CKK values based around a custom magic ID 192 value */ 193 194 #define VENDOR_NCIPHER 0xDE436972UL 195 #define CKA_NCIPHER ( CKA_VENDOR_DEFINED | VENDOR_NCIPHER ) 196 #define CKM_NCIPHER ( CKM_VENDOR_DEFINED | VENDOR_NCIPHER ) 197 #define CKK_NCIPHER ( CKK_VENDOR_DEFINED | VENDOR_NCIPHER ) 198 199 #ifdef NCIPHER_PKCS11 200 #define CKK_MD5_HMAC ( CKK_NCIPHER + 2 ) 201 #define CKK_SHA_1_HMAC ( CKK_NCIPHER + 1 ) 202 #define CKK_RIPEMD160_HMAC CKK_GENERIC_SECRET 203 #define CKK_SHA256_HMAC CKK_GENERIC_SECRET 204 #define CKM_MD5_HMAC_KEY_GEN ( CKM_NCIPHER + 6 ) 205 #define CKM_SHA_1_HMAC_KEY_GEN ( CKM_NCIPHER + 3 ) 206 #define CKM_RIPEMD160_HMAC_KEY_GEN CKK_GENERIC_SECRET 207 #define CKM_SHA256_HMAC_KEY_GEN CKK_GENERIC_SECRET 208 #else 209 #define CKK_MD5_HMAC CKK_GENERIC_SECRET 210 #define CKK_SHA_1_HMAC CKK_GENERIC_SECRET 211 #define CKK_RIPEMD160_HMAC CKK_GENERIC_SECRET 212 #define CKK_SHA256_HMAC CKK_GENERIC_SECRET 213 #define CKM_MD5_HMAC_KEY_GEN CKM_GENERIC_SECRET_KEY_GEN 214 #define CKM_SHA_1_HMAC_KEY_GEN CKM_GENERIC_SECRET_KEY_GEN 215 #define CKM_RIPEMD160_HMAC_KEY_GEN CKK_GENERIC_SECRET 216 #define CKM_SHA256_HMAC_KEY_GEN CKM_GENERIC_SECRET_KEY_GEN 217 #endif /* NCIPHER_PKCS11 */ 218 219 /* Prototypes for functions in pkcs11.c */ 220 221 CHECK_RETVAL \ 222 int pkcs11MapError( const CK_RV errorCode, 223 IN_STATUS const int defaultError ); 224 CHECK_RETVAL STDC_NONNULL_ARG( ( 2, 3 ) ) \ 225 int getContextDeviceInfo( IN_HANDLE const CRYPT_HANDLE iCryptContext, 226 OUT_HANDLE_OPT CRYPT_DEVICE *iCryptDevice, 227 OUT_PTR_COND PKCS11_INFO **pkcs11InfoPtrPtr ); 228 STDC_NONNULL_ARG( ( 1 ) ) \ 229 time_t getTokenTime( const CK_TOKEN_INFO *tokenInfo ); 230 CHECK_RETVAL_PTR_NONNULL STDC_NONNULL_ARG( ( 1 ) ) \ 231 const PKCS11_MECHANISM_INFO *getMechanismInfoConv( OUT_LENGTH_SHORT int *mechanismInfoSize ); 232 RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 233 int genericEndFunction( INOUT CONTEXT_INFO *contextInfoPtr ); 234 235 /* Prototypes for functions in pkcs11_init.c */ 236 237 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 238 int initPKCS11Init( INOUT DEVICE_INFO *deviceInfo, 239 IN_BUFFER( nameLength ) const char *name, 240 IN_LENGTH_SHORT const int nameLength ); 241 242 /* Prototypes for functions in pkcs11_pkc.c */ 243 244 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 245 int rsaSetPublicComponents( INOUT PKCS11_INFO *pkcs11Info, 246 IN_HANDLE const CRYPT_CONTEXT iCryptContext, 247 const CK_OBJECT_HANDLE hRsaKey, 248 const BOOLEAN nativeContext ); 249 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 250 int dsaSetPublicComponents( INOUT PKCS11_INFO *pkcs11Info, 251 IN_HANDLE const CRYPT_CONTEXT iCryptContext, 252 const CK_OBJECT_HANDLE hDsaKey, 253 const BOOLEAN nativeContext ); 254 #if defined( USE_ECDSA ) 255 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \ 256 int ecdsaSetPublicComponents( INOUT PKCS11_INFO *pkcs11Info, 257 IN_HANDLE const CRYPT_CONTEXT iCryptContext, 258 const CK_OBJECT_HANDLE hEcdsaKey, 259 const BOOLEAN nativeContext ); 260 #endif /* USE_ECDSA */ 261 CHECK_RETVAL_PTR_NONNULL STDC_NONNULL_ARG( ( 1 ) ) \ 262 const PKCS11_MECHANISM_INFO *getMechanismInfoPKC( OUT int *mechanismInfoSize ); 263 264 /* Prototypes for functions in pkcs11_rd/wr.c */ 265 266 CHECK_RETVAL_RANGE( ACTION_PERM_FLAG_NONE, ACTION_PERM_FLAG_MAX ) STDC_NONNULL_ARG( ( 1 ) ) \ 267 int getActionFlags( INOUT PKCS11_INFO *pkcs11Info, 268 const CK_OBJECT_HANDLE hObject, 269 IN_ENUM( KEYMGMT_ITEM ) const KEYMGMT_ITEM_TYPE itemType, 270 IN_ALGO const CRYPT_ALGO_TYPE cryptAlgo ); 271 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \ 272 int addIAndSToTemplate( INOUT_ARRAY_C( 2 ) CK_ATTRIBUTE *certTemplate, 273 IN_BUFFER( iAndSLength ) const void *iAndSPtr, 274 IN_LENGTH_SHORT const int iAndSLength ); 275 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 3 ) ) \ 276 int getEccCurveType( INOUT PKCS11_INFO *pkcs11Info, 277 const CK_OBJECT_HANDLE hObject, 278 OUT_ENUM_OPT( CRYPT_ECCCURVE ) \ 279 CRYPT_ECCCURVE_TYPE *curveType ); 280 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \ 281 int findObject( INOUT PKCS11_INFO *pkcs11Info, 282 OUT CK_OBJECT_HANDLE *hObject, 283 IN_ARRAY( templateCount ) \ 284 const CK_ATTRIBUTE *objectTemplate, 285 IN_RANGE( 1, 64 ) const CK_ULONG templateCount ); 286 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \ 287 int findObjectEx( INOUT PKCS11_INFO *pkcs11Info, 288 OUT CK_OBJECT_HANDLE *hObject, 289 IN_ARRAY( templateCount ) \ 290 const CK_ATTRIBUTE *objectTemplate, 291 IN_RANGE( 1, 64 ) const CK_ULONG templateCount ); 292 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \ 293 int findObjectFromObject( INOUT PKCS11_INFO *pkcs11Info, 294 const CK_OBJECT_HANDLE hSourceObject, 295 const CK_OBJECT_CLASS objectClass, 296 OUT CK_OBJECT_HANDLE *hObject ); 297 void initPKCS11Read( INOUT DEVICE_INFO *deviceInfo ) \ 298 STDC_NONNULL_ARG( ( 1 ) ); 299 void initPKCS11Write( INOUT DEVICE_INFO *deviceInfo ) \ 300 STDC_NONNULL_ARG( ( 1 ) ); 301 302 #endif /* USE_PKCS11 */ 303