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