1 /****************************************************************************
2 *																			*
3 *					  cryptlib Device Interface Header File 				*
4 *						Copyright Peter Gutmann 1998-2008					*
5 *																			*
6 ****************************************************************************/
7 
8 #ifndef _DEVICE_DEFINED
9 
10 #define _DEVICE_DEFINED
11 
12 /* The maximum length of error message we can store */
13 
14 #define MAX_ERRMSG_SIZE		512
15 
16 /* Device information flags.  The "needs login" flag is a general device
17    flag which indicates that this type of device needs a user login before
18    it can be used and is set when the device is first opened, the "logged in"
19    flag is an ephemeral flag which indicates whether the user is currently
20    logged in.  The "device active" flag indicates that a session with the
21    device is currently active and needs to be shut down when the device
22    object is destroyed */
23 
24 #define DEVICE_NEEDSLOGIN	0x0001	/* User must log in to use dev.*/
25 #define DEVICE_READONLY		0x0002	/* Device can't be written to */
26 #define DEVICE_REMOVABLE	0x0004	/* Device is removable */
27 #define DEVICE_ACTIVE		0x0008	/* Device is currently active */
28 #define DEVICE_LOGGEDIN		0x0010	/* User is logged into device */
29 #define DEVICE_TIME			0x0020	/* Device has on-board time source */
30 
31 /* Devices implement mechanisms in the same way that contexts implement
32    actions.  Since the mechanism space is sparse, dispatching is handled by
33    looking up the required mechanism in a table of (action, mechanism,
34    function) triples.  The table is sorted by order of most-frequently-used
35    mechanisms to speed things up, although the overhead is vanishingly small
36    anyway */
37 
38 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 2 ) ) \
39 		int ( *MECHANISM_FUNCTION )( IN_OPT void *deviceInfoPtr,
40 									 INOUT void *mechanismInfo );
41 typedef struct {
42 	const MESSAGE_TYPE action;
43 	const MECHANISM_TYPE mechanism;
44 	const MECHANISM_FUNCTION function;
45 	} MECHANISM_FUNCTION_INFO;
46 
47 /* Devices can also be used to create further objects.  Most can only create
48    contexts, but the system object can create any kind of object */
49 
50 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
51 		int ( *CREATEOBJECT_FUNCTION )( INOUT \
52 										MESSAGE_CREATEOBJECT_INFO *objectInfo,
53 										const void *auxDataPtr,
54 										const int auxValue );
55 typedef struct {
56 	const OBJECT_TYPE type;
57 	const CREATEOBJECT_FUNCTION function;
58 	} CREATEOBJECT_FUNCTION_INFO;
59 
60 /****************************************************************************
61 *																			*
62 *								Data Structures								*
63 *																			*
64 ****************************************************************************/
65 
66 /* The internal fields in a deviec that hold data for the various keyset
67    types.   These are implemented as a union to conserve memory with some of
68    the more data-intensive types.  In addition the structures provide a
69    convenient way to group the device type-specific parameters */
70 
71 typedef struct {
72 	/* Nonce PRNG information */
73 	BUFFER_FIXED( CRYPT_MAX_HASHSIZE ) \
74 	BYTE nonceData[ ( CRYPT_MAX_HASHSIZE + 8 ) + 8 ];/* Nonce RNG state */
75 	HASH_FUNCTION_ATOMIC hashFunctionAtomic;		/* Nonce hash function */
76 	int hashSize;
77 	BOOLEAN nonceDataInitialised;	/* Whether nonce RNG initialised */
78 	} SYSTEMDEV_INFO;
79 
80 typedef struct {
81 	/* General device information */
82 	int minPinSize, maxPinSize;		/* Minimum, maximum PIN lengths */
83 	BUFFER( CRYPT_MAX_TEXTSIZE, labelLen ) \
84 	char label[ CRYPT_MAX_TEXTSIZE + 8 ];	/* Device label */
85 	int labelLen;
86 
87 	/* Device type-specific information */
88 	unsigned long hSession;			/* Session handle */
89 	long slotID;					/* Slot ID for multi-slot device */
90 	int deviceNo;					/* Index into PKCS #11 token table */
91 	void *functionListPtr;			/* PKCS #11 driver function list pointer */
92 	BUFFER( CRYPT_MAX_TEXTSIZE, defaultSSOPinLen ) \
93 	char defaultSSOPin[ CRYPT_MAX_TEXTSIZE + 8 ];	/* SSO PIN from dev.init */
94 	int defaultSSOPinLen;
95 
96 	/* Device state information.  This records the active object for multi-
97 	   part operations where we can only perform one per hSession.  Because
98 	   we have to set this to CRYPT_ERROR if there's none active, we make
99 	   it a signed long rather than the unsigned long that's usually used
100 	   for PKCS #11 handles */
101 	long hActiveSignObject;			/* Currently active sig.object */
102 
103 	/* Last-error information returned from lower-level code */
104 	ERROR_INFO errorInfo;
105 	} PKCS11_INFO;
106 
107 #if defined( __WIN32__ ) && VC_GE_2005( _MSC_VER )
108   #define CAPI_HANDLE ULONG_PTR		/* May be 64 bits on Win64 */
109 #else
110   #define CAPI_HANDLE unsigned long	/* Always 32 bits on Win32 */
111 #endif /* Older vs.newer CryptoAPI types */
112 
113 typedef struct {
114 	/* General device information */
115 	BUFFER( CRYPT_MAX_TEXTSIZE, labelLen ) \
116 	char label[ CRYPT_MAX_TEXTSIZE + 8 ];	/* Device label */
117 	int labelLen;
118 
119 	/* Device type-specific information */
120 	CAPI_HANDLE hProv;				/* CryptoAPI provider handle */
121 	void *hCertStore;				/* Cert store for key/cert storage */
122 	CAPI_HANDLE hPrivateKey;		/* Key for session key import/export */
123 	int privateKeySize;				/* Size of import/export key */
124 	const void *hCertChain;			/* Cached copy of current cert chain */
125 
126 	/* Last-error information returned from lower-level code */
127 	ERROR_INFO errorInfo;
128 	} CRYPTOAPI_INFO;
129 
130 typedef struct {
131 	/* General device information */
132 	BUFFER( CRYPT_MAX_TEXTSIZE, labelLen ) \
133 	char label[ CRYPT_MAX_TEXTSIZE + 8 ];	/* Device label */
134 	int labelLen;
135 
136 	/* Device type-specific information */
137 	CRYPT_KEYSET iCryptKeyset;			/* Key storage */
138 
139 	/* Last-error information returned from lower-level code */
140 	ERROR_INFO errorInfo;
141 	} HARDWARE_INFO;
142 
143 /* Defines to make access to the union fields less messy */
144 
145 #define deviceSystem	deviceInfo.systemInfo
146 #define devicePKCS11	deviceInfo.pkcs11Info
147 #define deviceCryptoAPI	deviceInfo.cryptoapiInfo
148 #define deviceHardware	deviceInfo.hardwareInfo
149 
150 /* The structure which stores information on a device */
151 
152 struct DI;
153 
154 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
155 		int ( *DEV_INITFUNCTION )( INOUT struct DI *deviceInfo,
156 								   IN_BUFFER_OPT( nameLength ) \
157 										const char *name,
158 								   IN_LENGTH_TEXT_Z const int nameLength );
159 typedef STDC_NONNULL_ARG( ( 1 ) ) \
160 		void ( *DEV_SHUTDOWNFUNCTION )( INOUT struct DI *deviceInfo );
161 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
162 		int ( *DEV_CONTROLFUNCTION )( INOUT struct DI *deviceInfo,
163 									  IN_ATTRIBUTE \
164 										const CRYPT_ATTRIBUTE_TYPE type,
165 									  IN_BUFFER_OPT( dataLength ) void *data,
166 									  IN_LENGTH_SHORT_Z const int dataLength,
167 									  INOUT_OPT \
168 										MESSAGE_FUNCTION_EXTINFO *messageExtInfo );
169 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
170 		int ( *DEV_SELFTESTFUNCTION )( INOUT struct DI *deviceInfo,
171 									   INOUT \
172 										MESSAGE_FUNCTION_EXTINFO *messageExtInfo );
173 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
174 		int ( *DEV_GETITEMFUNCTION )( INOUT struct DI *deviceInfo,
175 									  OUT_HANDLE_OPT \
176 										CRYPT_CONTEXT *iCryptContext,
177 									  IN_ENUM( KEYMGMT_ITEM ) \
178 										const KEYMGMT_ITEM_TYPE itemType,
179 									  IN_KEYID const CRYPT_KEYID_TYPE keyIDtype,
180 									  IN_BUFFER( keyIDlength ) \
181 										const void *keyID,
182 									  IN_LENGTH_KEYID const int keyIDlength,
183 									  IN_BUFFER_OPT( *auxInfoLength ) \
184 										void *auxInfo,
185 									  INOUT_LENGTH_SHORT_Z int *auxInfoLength,
186 									  IN_FLAGS_Z( KEYMGMT ) const int flags );
187 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
188 		int ( *DEV_SETITEMFUNCTION )( INOUT struct DI *deviceInfo,
189 									  IN_HANDLE \
190 										const CRYPT_HANDLE iCryptHandle );
191 typedef RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
192 		int ( *DEV_DELETEITEMFUNCTION )( INOUT struct DI *deviceInfo,
193 										 IN_ENUM( KEYMGMT_ITEM ) \
194 											const KEYMGMT_ITEM_TYPE itemType,
195 										 IN_KEYID \
196 											const CRYPT_KEYID_TYPE keyIDtype,
197 										 IN_BUFFER( keyIDlength ) \
198 											const void *keyID,
199 										 IN_LENGTH_KEYID \
200 											const int keyIDlength );
201 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3, 5 ) ) \
202 		int ( *DEV_GETFIRSTITEMFUNCTION )( INOUT struct DI *deviceInfo,
203 										   OUT_HANDLE_OPT \
204 											CRYPT_CERTIFICATE *iCertificate,
205 										   OUT int *stateInfo,
206 										   IN_KEYID \
207 											const CRYPT_KEYID_TYPE keyIDtype,
208 										   IN_BUFFER( keyIDlength ) \
209 											const void *keyID,
210 										   IN_LENGTH_KEYID const int keyIDlength,
211 										   IN_ENUM( KEYMGMT_ITEM ) \
212 											const KEYMGMT_ITEM_TYPE itemType,
213 										   IN_FLAGS_Z( KEYMGMT ) \
214 											const int options );
215 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 3 ) ) \
216 		int ( *DEV_GETNEXTITEMFUNCTION )( INOUT struct DI *deviceInfo,
217 										  OUT_HANDLE_OPT \
218 											CRYPT_CERTIFICATE *iCertificate,
219 										  INOUT int *stateInfo,
220 										  IN_FLAGS_Z( KEYMGMT ) \
221 											const int options );
222 typedef CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
223 		int ( *DEV_GETRANDOMFUNCTION )( INOUT struct DI *deviceInfo,
224 										OUT_BUFFER_FIXED( length ) void *buffer,
225 										IN_LENGTH_SHORT const int length,
226 										INOUT_OPT \
227 											MESSAGE_FUNCTION_EXTINFO *messageExtInfo );
228 
229 typedef struct DI {
230 	/* General device information.  Alongside various handles used to access
231 	   the device we also record whether the user has authenticated
232 	   themselves to the device since some devices have multiple user-access
233 	   states and the user needs to be logged out of one state before they
234 	   can log in to another state.  In addition we also record the device
235 	   label which the caller can query for use in prompts displayed to the
236 	   user */
237 	CRYPT_DEVICE_TYPE type;			/* Device type */
238 	int flags;						/* Device information flags */
239 	BUFFER_FIXED( labelLen ) \
240 	char *label;					/* Device label */
241 	int labelLen;
242 
243 	/* Each device provides various capabilities which are held in the
244 	   following list.  When we need to create an object via the device, we
245 	   look up the requirements in the capability info and feed it to
246 	   createObjectFromCapability() */
247 	const void *capabilityInfoList;
248 
249 	/* Device type-specific information */
250 	union {
251 		SYSTEMDEV_INFO *systemInfo;
252 		PKCS11_INFO *pkcs11Info;
253 		CRYPTOAPI_INFO *cryptoapiInfo;
254 		HARDWARE_INFO *hardwareInfo;
255 		} deviceInfo;
256 
257 	/* Pointers to device access methods */
258 	DEV_INITFUNCTION initFunction;
259 	DEV_SHUTDOWNFUNCTION shutdownFunction;
260 	DEV_CONTROLFUNCTION controlFunction;
261 	DEV_SELFTESTFUNCTION selftestFunction;
262 	DEV_GETITEMFUNCTION getItemFunction;
263 	DEV_SETITEMFUNCTION setItemFunction;
264 	DEV_DELETEITEMFUNCTION deleteItemFunction;
265 	DEV_GETFIRSTITEMFUNCTION getFirstItemFunction;
266 	DEV_GETNEXTITEMFUNCTION getNextItemFunction;
267 	DEV_GETRANDOMFUNCTION getRandomFunction;
268 
269 	/* Information for the system device */
270 	const MECHANISM_FUNCTION_INFO *mechanismFunctions;
271 	const CREATEOBJECT_FUNCTION_INFO *createObjectFunctions;
272 	void *randomInfo;
273 	int mechanismFunctionCount, createObjectFunctionCount;
274 
275 	/* Error information */
276 	CRYPT_ATTRIBUTE_TYPE errorLocus;/* Error locus */
277 	CRYPT_ERRTYPE_TYPE errorType;	/* Error type */
278 
279 	/* The object's handle and the handle of the user who owns this object.
280 	   The former is used when sending messages to the object when only the
281 	   xxx_INFO is available, the latter is used to avoid having to fetch the
282 	   same information from the system object table */
283 	CRYPT_HANDLE objectHandle;
284 	CRYPT_USER ownerHandle;
285 
286 	/* Variable-length storage for the type-specific data */
287 	DECLARE_VARSTRUCT_VARS;
288 	} DEVICE_INFO;
289 
290 /****************************************************************************
291 *																			*
292 *								Internal API Functions						*
293 *																			*
294 ****************************************************************************/
295 
296 /* Device attribute handling functions */
297 
298 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
299 int getDeviceAttribute( INOUT DEVICE_INFO *deviceInfoPtr,
300 						OUT_INT_Z int *valuePtr,
301 						IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute,
302 						INOUT MESSAGE_FUNCTION_EXTINFO *messageExtInfo );
303 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 4 ) ) \
304 int getDeviceAttributeS( INOUT DEVICE_INFO *deviceInfoPtr,
305 						 INOUT MESSAGE_DATA *msgData,
306 						 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute,
307 						 MESSAGE_FUNCTION_EXTINFO *messageExtInfo );
308 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 4 ) ) \
309 int setDeviceAttribute( INOUT DEVICE_INFO *deviceInfoPtr,
310 						IN_INT_Z const int value,
311 						IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute,
312 						MESSAGE_FUNCTION_EXTINFO *messageExtInfo );
313 CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2, 5 ) ) \
314 int setDeviceAttributeS( INOUT DEVICE_INFO *deviceInfoPtr,
315 						 IN_BUFFER( dataLength ) const void *data,
316 						 IN_LENGTH const int dataLength,
317 						 IN_ATTRIBUTE const CRYPT_ATTRIBUTE_TYPE attribute,
318 						 MESSAGE_FUNCTION_EXTINFO *messageExtInfo );
319 
320 /* Prototypes for device mapping functions */
321 
322 #ifdef USE_PKCS11
323   CHECK_RETVAL \
324   int deviceInitPKCS11( void );
325   void deviceEndPKCS11( void );
326   CHECK_RETVAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
327   int setDevicePKCS11( INOUT DEVICE_INFO *deviceInfo,
328 					   IN_BUFFER( nameLength ) const char *name,
329 					   IN_LENGTH_ATTRIBUTE const int nameLength );
330 #else
331   #define deviceInitPKCS11()			CRYPT_OK
332   #define deviceEndPKCS11()
333   #define setDevicePKCS11( x, y, z )	CRYPT_ARGERROR_NUM1
334 #endif /* USE_PKCS11 */
335 #ifdef USE_CRYPTOAPI
336   CHECK_RETVAL \
337   int deviceInitCryptoAPI( void );
338   void deviceEndCryptoAPI( void );
339   CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
340   int setDeviceCryptoAPI( INOUT DEVICE_INFO *deviceInfo );
341 #else
342   #define deviceInitCryptoAPI()			CRYPT_OK
343   #define deviceEndCryptoAPI()
344   #define setDeviceCryptoAPI( x )		CRYPT_ARGERROR_NUM1
345 #endif /* USE_CRYPTOAPI */
346 #ifdef USE_HARDWARE
347   CHECK_RETVAL \
348   int deviceInitHardware( void );
349   void deviceEndHardware( void );
350   CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
351   int setDeviceHardware( INOUT DEVICE_INFO *deviceInfo );
352 #else
353   #define deviceInitHardware()			CRYPT_OK
354   #define deviceEndHardware()
355   #define setDeviceHardware( x )		CRYPT_ARGERROR_NUM1
356 #endif /* USE_HARDWARE */
357 CHECK_RETVAL STDC_NONNULL_ARG( ( 1 ) ) \
358 int setDeviceSystem( INOUT DEVICE_INFO *deviceInfo );
359 
360 #endif /* _DEVICE_DEFINED */
361