140 likes | 256 Views
OTP-CryptoAPI. Magnus Nyström & Gareth Richards, RSA Security 24 May 2005. Overview. Describes general Microsoft CryptoAPI objects, procedures and mechanisms that can be used to retrieve OTPs
E N D
OTP-CryptoAPI Magnus Nyström & Gareth Richards, RSA Security 24 May 2005
Overview • Describes general Microsoft CryptoAPI objects, procedures and mechanisms that can be used to retrieve OTPs • Intended to meet the needs of applications wishing to access connected OTP tokens in an interoperable manner • Eases the task for vendors of OTP-consuming applications • Enables a better user experience
CryptoAPI Principles of Operation • Intent is to follow the HMAC approach for CryptoAPI • CryptAcquireContext gives handle to key container • CryptCreateHash gives handle to key object, specifies OTP mechanism • CryptSetHashParam sets parameters (uses PKCS #11 structures) • CryptHashData generates OTPs • CryptGetHashParam retrieves the OTP value CryptAcquireContext CryptCreateHash CryptSetHashParam CryptHashData CryptGetHashParam
Current Design • Cryptographic Service Providers supporting the described mechanism are identified as being of type PROV_OTP • OTP algorithms will be of class CALG_CLASS_OTP • Keys currently created through CryptGenKey and CryptSetKeyParam, with parameters borrowed from the PKCS #11 sibling document
OTP Algorithm Profiles • Initial draft defines two OTP algorithms • CALG_SECURID • CALG_SECURID_TRADITIONAL • In correspondence, one additional OTP algorithm is suggested • CALG_HOTP • For CALG_SECURID and CALG_SECURID_TRADITIONAL, the document defines the parameters that may be used in calls to CryptSetHashParam
PKCS #11 vs. “pure” CryptoAPI approach Seems preferable to make document standalone from OTP-PKCS11 Easier to gain acceptance from CryptoAPI community Requires CryptoAPI definitions of key parameters (attributes) What PKCS #11 key attributes would have to be represented as CryptoAPI key parameters? Probably no need for PP_PARAMS due to KP_ALGID For Discussion
PKCS #11 Key Attributes vs. CryptoAPI Key Parameters • CKA_END_DATE (SYSTEMTIME?) • CKA_VALUE_LEN (KP_KEYLEN?) • CKA_SERIAL_NUMBER (BYTE *) • CKA_OTP_FORMAT (DWORD) • CKA_OTP_LENGTH (DWORD) • CKA_OTP_PINPAD (BOOL) • CKA_OTP_APP_BASED (BOOL) • CKA_OTP_{CHALLENGE, TIME, COUNTER}_MODE (DWORD) • CKA_OTP_DEFAULT_PIN{_ALLOWED, _SET} (BOOL) • CKA_OTP_SERVICE_IDENTIFIER (LPCTSTR) • CKA_OTP_TIME_INTERVAL (DWORD) • CKA_OTP_ACCEPT_{TIME, COUNTER} (BOOL) • CKA_OTP_COUNTER_VALUE (BYTE *)
Importing an OTP Key HCRYPTKEY ImportHOTPKEY( HCRYPTPROV hProv, HCRTYPKEY hUnwrapKey, // Required for SIMPLEBLOB BYTE *blob, // SIMPLEBLOB or PLAINTEXTBLOB DWORD blobLen, BYTE *serialNumber, DWORD serialNumberLen, SYSTEMTIME expiryDate { HCRYPTKEY hOTPKey = (HCRYPTKEY)NULL; BOOL bTrue = TRUE; ALG_ID algID = CALG_HOTP; // Import the OTP key. CryptImportKey(hProv, blob, blobLen, hUnwrapKey, 0, &hOTPKey); // Set the key attributes CryptSetKeyParam(hOTPKey, KP_SERIAL_NUMBER, serialNumber, serialNumberLen, 0); CryptSetKeyParam(hOTPKey, KP_END_DATE, expiryDate, sizeof(expiryDate), 0); CryptSetKeyParam(hOTPKey, KP_OTP_COUNTER_MODE, &bTrue, sizeof(bTrue), 0); // Enable the key. CryptSetKeyParam(hOTPKey, KP_ALGID, algID, sizeof(algID), 0); return hOTPKey; }
Exporting an OTP Key BOOL ExportHOTPKey( HCRYPTKEY hOTPKey HCRTYPKEY hwrapKey, BYTE *blob, // Buffer to receive SIMPLEBLOB DWORD *blobLen { return CryptExportKey(hOTPKey, hWrapKey, SIMPLEBLOB, 0, blob, blobLen); }
Generating an OTP Key HCRYPTKEY GenerateSecurIDKey( HCRYPTPROV hProv, BYTE *serialNumber, DWORD serialNumberLen, SYSTEMTIME *expiryDate { HCRYPTKEY hOTPKey =(HCRYPTKEY)NULL; BOOL bTrue = TRUE; ALG_ID algID = CALG_SECURID; // Generate the OTP key. CryptGenKey(hProv, algID, CRYPT_EXPORTABLE, &hOTPKey); // Set the key attributes. CryptSetKeyParam(hOTPKey, KP_SERIAL_NUMBER, serialNumber, serialNumberLen, 0); CryptSetKeyParam(hOTPKey, KP_END_DATE, expiryDate, sizeof(SYSTEMTIME), 0); CryptSetKeyParam(hOTPKey, KP_OTP_TIME_MODE, &bTrue, sizeof(bTrue), 0); //Enable the key. CryptSetKeyParam(hOTPKey, KP_ALGID, algID, sizeof(algID), 0); return hOTPKey; }
Retrieving an OTP void GetOTP( HCRYPTPROV hProv, HCRYPTKEY hOTPKey, // Can be NULL to use default key. wchar_t *pPIN, BYTE *buf, DWORD *bufLen ) { HCRYPTHASH hHash = (HCRYPTHASH)NULL; SECURID_PARAMS securIDParams = {0}; securIDParams.flags = 0; securIDParams.pPIN = pin; securIDParams.applicationID = NULL; securIDParams.pReserved = NULL; CryptCreateHash(hProv, CALG_SECURID, hOTPKey, 0, hHash); CryptSetHashParam(hHash, HP_OTP_PARAM, &securIDParams, sizeof(securIDParams), 0); CryptHashData(hHash, NULL, 0, 0); CryptGetHashParam(hHash, HP_HASHVAL, buf, bufLen, 0); CryptDestroyHash(hHash); }
Importing OTP Key & Retrieving OTP // Acquire handle to target container. CryptAcquireContext (&hProv, pszContainer, pszProvider, PROV_OTP, 0); // Open handle to wrapping key to unwrap OTP key. CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hUnwrapKey); // Import the OTP key. hOTPKey = ImportSecurIDKey (hProv, hUnwrapKey, blob, blobLen, serialNumber, serialNumberLen, &expiryDate); // Generate an OTP from the new key. GetOTP (hProv, hOTPKey, pPIN, buf, &bufLen); CryptDestroyKey(hOTPKey); CryptDestroyKey(hUnwrapKey) CryptReleaseContext(hProv, 0);
Next Steps • Agreement and stabilization of document content • Preferably new draft within next 3 – 4 weeks, reflecting workshop discussions • Additional draft versions expected to be required • Possible future contribution of document? • Would preferably be “adopted” by Microsoft • Need Microsoft recognition of at least: PROV_OTP, ALG_CLASS_OTP • Preferably also the key parameters and the algorithm identifiers • Ideally, our definitions and structures would be part of CRYPTOAPI.H