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