Secure Channel Sample Class Implementation. HID Global OMNIKEY 5326 DFR
Реклама
Реклама
Software Developer Guide, 5326-903, Rev A.0
7 Secure Channel Sample Class Implementation
}
{
7.1 Constructor
CSecureChannel::CSecureChannel() m_hProv = NULL; m_hMK m_hSCBK
= NULL;
= NULL; m_hSMAC1 = NULL; m_hSMAC2 = NULL; m_hSENC = NULL; memset((void*)m_abICV, 0x00, sizeof(m_abICV));
{
}
{
7.2 Destructor
CSecureChannel::~CSecureChannel(void)
// release the resources if(m_hProv)
CryptReleaseContext(m_hProv, 0); if(m_hSCBK)
{
CryptDestroyKey(m_hSCBK);
} if(m_hSMAC1)
{
}
{
CryptDestroyKey(m_hSMAC1);
} if(m_hSMAC2)
CryptDestroyKey(m_hSMAC2);
March 2012 Page 36 of 72
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
} if(m_hSENC)
{
}
CryptDestroyKey(m_hSENC); if(m_hMK)
{
CryptDestroyKey(m_hMK);
}
7.3 Initialize 1
bool CSecureChannel::Init(BYTE* abKey, DWORD* dwLength, BYTE* abChallenge, DWORD* dwLengthCh)
{
BYTE pbData[100];
DWORD dwSize = sizeof(pbData);
HCRYPTKEY phKey; struct {
BLOBHEADER hdr;
DWORD
BYTE cbKeySize; rgbKeyData [16];
} myBlob; if (*dwLength != 16) return false; if(!CryptAcquireContext( &m_hProv,
{
if(!CryptAcquireContext( &m_hProv,
0,
NULL,//MS_ENH_RSA_AES_PROV,
PROV_RSA_AES,
CRYPT_NEWKEYSET)) // 0))
Page 37 of 72 March 2012
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
}
{
return false;
}
0,
NULL,//MS_ENH_RSA_AES_PROV,
PROV_RSA_AES,
0)) memcpy(m_abMasterKey, abKey, 16);
// generate the client challange (8 byte random number) if (CryptGenKey(m_hProv, CALG_AES_128, CRYPT_EXPORTABLE, &phKey))
{ if (!CryptExportKey(phKey, NULL, PLAINTEXTKEYBLOB, 0, pbData, &dwSize)) return false; if (dwSize == sizeof(myBlob))
{
BYTE clientChallenge[] =
{0x46,0x90,0x2B,0x57,0xC6,0x8D,0x14,0x90}; memcpy(m_abClientChallenge, clientChallenge, sizeof(clientChallenge));
}
//memcpy(m_abClientChallenge, &pbData[dwSize-16], 8); else return false;
CryptDestroyKey(phKey);
// import the master key myBlob.hdr.bType = PLAINTEXTKEYBLOB; myBlob.hdr.bVersion = CUR_BLOB_VERSION; myBlob.hdr.reserved = 0;
Page 38 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
} myBlob.hdr.aiKeyAlg = CALG_AES_128; myBlob.cbKeySize = 16;
{ memcpy(myBlob.rgbKeyData, m_abMasterKey, 16); if (!CryptImportKey(m_hProv, (BYTE*)&myBlob, sizeof(myBlob), NULL, 0, &m_hMK))
} return false;
} if (*dwLengthCh < 8) return false; memcpy(abChallenge, m_abClientChallenge, 8);
*dwLengthCh = 8; return true;
March 2012
© 2012 HID Global Corporation. All rights reserved.
Page 39 of 72
Software Developer Guide, 5326-903, Rev A.0
}
{
7.4 Initialize 2
bool CSecureChannel::Init(CString strKey, CString* strChallenge) bool fRet = true;
BYTE abKey[32];
DWORD dwKSize = sizeof(abKey);
BYTE abChallenge[32];
DWORD dwCSize = sizeof(abChallenge); do
{ if ( !ConvertStringToHex(strKey, abKey, &dwKSize) )
{ fRet = false; break;
} if ( !Init(abKey, &dwKSize, abChallenge, &dwCSize) )
{
} fRet= false; break; if ( !ConvertHexToString(abChallenge, dwCSize, strChallenge) )
{
}
} while (false); fRet = false; break; return fRet;
Page 40 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
{
7.5 Check Server Authentication 1
bool CSecureChannel::CheckServerAutentication(BYTE* abServerAuthData, DWORD* dwLengthAuthData, BYTE* abClientAuthData, DWORD* dwLengthCl)
BYTE abKeyInput[16];
BYTE abClientCryptogram[16];
BYTE abServerCryptogram[16];
BYTE abIV[16];
BYTE pbData[100];
DWORD dwSizeCMAC = sizeof(m_abCMAC); memset(abClientCryptogram, 0x00, sizeof(abClientCryptogram)); memset(abServerCryptogram, 0x00, sizeof(abServerCryptogram)); memset(m_abCMAC, 0x00, sizeof(m_abCMAC)); memset(abIV, 0x00, sizeof(abIV));
DWORD dwSize = sizeof(abKeyInput); if (*dwLengthAuthData != 32) return false; if (*dwLengthCl != 32) return false; memcpy(m_abUID, abServerAuthData, 8); for (int ii = 0; ii < 8; ++ii)
{ abKeyInput[8+ii] = ~m_abUID[ii]; abKeyInput[ii] = m_abUID[ii];
}
// generate the basekey
DWORD dwData = CRYPT_MODE_ECB;
Page 41 of 72 March 2012
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
)) if (!CryptSetKeyParam(m_hMK, KP_MODE, (BYTE*)&dwData, 0))
{
} if (CryptExportKey(m_hSCBK, NULL, PLAINTEXTKEYBLOB, 0, pbData, &dwSize))
}
{ return false; if (!ImportKey(&m_hSCBK, abKeyInput, &dwSize, m_hMK))
{ return false;
} dwSize = sizeof(pbData); memcpy(m_abSCBK, &pbData[dwSize-16], 16);
// save the server challange memcpy(m_abServerChallenge, &abServerAuthData[8], 8);
// compute session keys if (!DeriveKeys( (unsigned short)(m_abServerChallenge[0] << 8) + m_abServerChallenge[1] return false;
// compute the client cryptogram memcpy(abClientCryptogram, m_abServerChallenge, sizeof(m_abServerChallenge)); memcpy(&abClientCryptogram[8], m_abClientChallenge, sizeof(m_abClientChallenge)); dwSize = sizeof(abClientCryptogram); if (!ComputeCryptogram(abClientCryptogram, &dwSize)) return false;
// compute the server cryptogram memcpy(abServerCryptogram, m_abClientChallenge, sizeof(m_abClientChallenge)); memcpy(&abServerCryptogram[8], m_abServerChallenge, sizeof(m_abServerChallenge)); dwSize = sizeof(abServerCryptogram); if (!ComputeCryptogram(abServerCryptogram, &dwSize))
March 2012 Page 42 of 72
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
0) return false;
// check server authentication data if (memcmp(&abServerAuthData[16], abServerCryptogram, sizeof(abServerCryptogram)) != return false;
}
// check length of the buffer if (*dwLengthCl < 32) return false;
// copy client auth data to the output buffer memcpy(abClientAuthData, abClientCryptogram, sizeof(abClientCryptogram));
// calculate the C-MAC if (!ComputeMAC(abIV, abClientCryptogram, 0, sizeof(abClientCryptogram), m_abCMAC,
&dwSizeCMAC)) return false; memcpy(&abClientAuthData[16], m_abCMAC, 16); return true;
March 2012
© 2012 HID Global Corporation. All rights reserved.
Page 43 of 72
Software Developer Guide, 5326-903, Rev A.0
}
{
7.6 Check Server Authentication 2
bool CSecureChannel::CheckServerAutentication(CString strServerAuthData, CString* strClientAuthData) bool fRet = true;
BYTE pbData1[100];
BYTE pbData2[32];
DWORD dwSize1;
DWORD dwSize2; do{ dwSize1 = sizeof(pbData1); if ( !ConvertStringToHex(strServerAuthData, pbData1, &dwSize1) )
}
{ fRet = false; break; dwSize2 = sizeof(pbData2); if ( !CheckServerAutentication(pbData1, &dwSize1, pbData2, &dwSize2) )
{
} fRet = false; break; if ( !ConvertHexToString(pbData2, dwSize2, strClientAuthData) )
{
}
} while (false); fRet = false; break; return fRet;
Page 44 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
7.7 Derive Keys
bool CSecureChannel::DeriveKeys(unsigned short usSeqCounter)
{
BYTE abInput[16];
DWORD dwSize = sizeof(abInput);
DWORD dwData;
BYTE pbData[100]; memset((void*)abInput, 0x00, sizeof(abInput)); dwData = CRYPT_MODE_ECB; if (!CryptSetKeyParam(m_hSCBK, KP_MODE, (BYTE*)&dwData, 0))
{
} return false;
// generate the SMAC1 abInput[0] = 0x01; abInput[1] = 0x01; abInput[2] = (BYTE)(usSeqCounter >> 8); abInput[3] = (BYTE) usSeqCounter; dwSize = sizeof(abInput); if (!ImportKey(&m_hSMAC1, abInput, &dwSize, m_hSCBK)) return false;
// generate the SMAC2 memset((void*)abInput, 0x00, sizeof(abInput)); abInput[0] = 0x01; abInput[1] = 0x02; abInput[2] = (BYTE)(usSeqCounter >> 8); abInput[3] = (BYTE) usSeqCounter; dwSize = sizeof(abInput); if (!ImportKey(&m_hSMAC2, abInput, &dwSize, m_hSCBK)) return false;
Page 45 of 72 March 2012
© 2012 HID Global Corporation. All rights reserved.
}
Software Developer Guide, 5326-903, Rev A.0
// generate the SENC memset((void*)abInput, 0x00, sizeof(abInput)); abInput[0] = 0x01; abInput[1] = 0x82; abInput[2] = (BYTE)(usSeqCounter >> 8); abInput[3] = (BYTE) usSeqCounter; dwSize = sizeof(abInput); if (!ImportKey(&m_hSENC, abInput, &dwSize, m_hSCBK)) return false; dwSize = sizeof(pbData);
CryptExportKey(m_hSENC, NULL, PLAINTEXTKEYBLOB, 0, pbData, &dwSize); memcpy(m_abSENC, &pbData[dwSize-16], 16); dwSize = sizeof(pbData);
CryptExportKey(m_hSMAC1, NULL, PLAINTEXTKEYBLOB, 0, pbData, &dwSize); memcpy(m_abSMAC1, &pbData[dwSize-16], 16); dwSize = sizeof(pbData);
CryptExportKey(m_hSMAC2, NULL, PLAINTEXTKEYBLOB, 0, pbData, &dwSize); memcpy(m_abSMAC2, &pbData[dwSize-16], 16); return true;
Page 46 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
7.8 Compute Cryptogram
bool CSecureChannel::ComputeCryptogram(BYTE* abINOUT, DWORD* dwSize)
{
DWORD
DWORD dwData = CRYPT_MODE_ECB; dwLength = *dwSize;
HCRYPTKEY hDuplicateKey;
BYTE abIV[16]; memset((void*)abIV, 0x00, sizeof(abIV));
} if(*dwSize != 16) return false;
CryptDuplicateKey(m_hSENC, 0, 0, &hDuplicateKey); if (!CryptSetKeyParam(hDuplicateKey, KP_MODE, (BYTE*)&dwData, 0)) return false; if (!CryptSetKeyParam(hDuplicateKey, KP_IV, abIV, 0)) return false; if (!CryptEncrypt(hDuplicateKey,
NULL,
FALSE, return false;
0,
abINOUT,
dwSize,
dwLength))
CryptDestroyKey(hDuplicateKey); return true;
Page 47 of 72 March 2012
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
7.9 Import Key
bool CSecureChannel::ImportKey(HCRYPTKEY* hKey, BYTE* abIN, DWORD* dwSize,
HCRYPTKEY hKeyIN)
{
DWORD dwLength = *dwSize; bool fOK
BYTE* abIV[16];
= true;
HCRYPTKEY hDuplicateKey; memset((void*)abIV, 0x00, sizeof(abIV)); struct {
BLOBHEADER hdr;
DWORD
BYTE
} myBlob; cbKeySize; rgbKeyData [16];
// generate the key
{
CryptDuplicateKey(hKeyIN, 0, 0, &hDuplicateKey); do if (!CryptSetKeyParam(hDuplicateKey, KP_IV, (const BYTE*)abIV, 0))
}
{ fOK = false; break; if (!CryptEncrypt(hDuplicateKey,
NULL,
FALSE,
0,
{
abIN,
dwSize,
dwLength))
Page 48 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
} fOK = false; break;
}
// import the key myBlob.hdr.bType = PLAINTEXTKEYBLOB; myBlob.hdr.bVersion = CUR_BLOB_VERSION; myBlob.hdr.reserved = 0; hKey)) myBlob.hdr.aiKeyAlg = CALG_AES_128; myBlob.cbKeySize = 16; memcpy(myBlob.rgbKeyData, abIN, 16); if (!CryptImportKey(m_hProv, (BYTE*)&myBlob, sizeof(myBlob), NULL, 0,
{
}
} while (false); fOK = false; break;
CryptDestroyKey(hDuplicateKey); return true;
March 2012
© 2012 HID Global Corporation. All rights reserved.
Page 49 of 72
Software Developer Guide, 5326-903, Rev A.0
7.10 Compute Mac
bool CSecureChannel::ComputeMAC(BYTE *abIV, BYTE* abIN, unsigned int uiOffset,
DWORD dwSize, BYTE* abOUT, DWORD* dwSizeOUT)
{
DWORD dwLength = dwSize + 16; do
{
DWORD dwNewSize = (DWORD)ceil((dwSize + 1.0) / 16.0) * 16; bool fOK = true;
HCRYPTKEY hDuplicateKey;
BYTE *abPadded = new BYTE [dwNewSize];
DWORD dwPaddedSize = dwNewSize;
BYTE *abPadded2 = new BYTE [dwNewSize];
DWORD dwPaddedSize2
BYTE *abIV2 = new byte[16];
= dwNewSize;
// generate the key
CryptDuplicateKey(m_hSMAC1, 0, 0, &hDuplicateKey);
}
{
} else if ((dwSize == 0) || ((dwSize % 16) != 0))
{ if (!Pad(abIN, uiOffset, dwSize, abPadded, &dwPaddedSize))
{ fOK = false; break;
} uiOffset = 0; dwPaddedSize = dwSize; memcpy((void*)abPadded, abIN, (size_t)dwPaddedSize);
March 2012 Page 50 of 72
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
March 2012 if (dwPaddedSize > 16)
{ memcpy(abPadded2, abPadded, dwPaddedSize); dwPaddedSize2 = dwPaddedSize -16; if (!CryptSetKeyParam(hDuplicateKey, KP_IV, abIV, 0))
{
} fOK = false; break; if (!CryptEncrypt(hDuplicateKey,
NULL,
FALSE,
0,
{ fOK = false;
}
if (dwPaddedSize2 > 0) break;
&abPadded2[uiOffset],
&dwPaddedSize2,
dwLength))
{
memcpy(abIV2, &abPadded2[dwPaddedSize2-16], 16);
}
}
else
{
} memcpy((void*)abIV2, (void*)abIV, 16);
CryptDestroyKey(hDuplicateKey);
CryptDuplicateKey(m_hSMAC2, 0, 0, &hDuplicateKey);
© 2012 HID Global Corporation. All rights reserved.
Page 51 of 72
Software Developer Guide, 5326-903, Rev A.0
}
{
}
} if (!CryptSetKeyParam(hDuplicateKey, KP_IV, abIV2, 0))
{ fOK = false; break; memcpy(abPadded2, &abPadded[uiOffset + dwPaddedSize -16], 16); dwPaddedSize2 = 16; if (!CryptEncrypt(hDuplicateKey,
NULL, fOK = false; break;
FALSE,
0,
abPadded2,
&dwPaddedSize2,
dwLength)) if (dwPaddedSize2 > *dwSizeOUT)
{ fOK = false; break;
} memcpy(abOUT, abPadded2, dwPaddedSize2);
*dwSizeOUT = dwPaddedSize2;
} while (false);
CryptDestroyKey(hDuplicateKey); delete[] abIV2; delete[] abPadded; delete[] abPadded2; return fOK;
March 2012 Page 52 of 72
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
7.11 Pad
bool CSecureChannel::Pad(BYTE* abIN, unsigned int uiOffset, DWORD dwSizeIN, BYTE* abOUT, DWORD *dwSizeOUT)
{
DWORD dwNewSize = (DWORD)ceil((dwSizeIN + 1.0) / 16.0) * 16; if (*dwSizeOUT < dwNewSize) return false;
*dwSizeOUT = dwNewSize; memset((void*)abOUT, 0x00, dwNewSize);
memcpy(abOUT, &abIN[uiOffset], (size_t)dwSizeIN);//)Array.Copy(input, offset, output, 0, length);
abOUT[dwSizeIN] = 0x80; return true;
}
7.12 Unpad
bool CSecureChannel::WrapInput(BYTE* abIN, DWORD dwINSize, BYTE* abOUT, DWORD
*dwOUTSize)
{
BYTE* abPlainPadded;
BYTE abComplementIV[16]; bool fOK = true;
HCRYPTKEY hDuplicateKey;
DWORD dwPlainPadded = (DWORD)ceil((dwINSize + 1.0) / 16.0) * 16;
DWORD dwSizeMAC = sizeof(m_abCMAC); abPlainPadded = new BYTE[dwPlainPadded]; do
{ if (!Pad(abIN, 0, dwINSize, abPlainPadded, & dwPlainPadded))
{
Page 53 of 72 March 2012
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
}
{ fOK = false; break; for (int ii = 0; ii < 16; ++ii)
} abComplementIV[ii] = ~m_abRMAC[ii];
}
{
CryptDuplicateKey(m_hSENC, 0, 0, &hDuplicateKey); if (!CryptSetKeyParam(hDuplicateKey, KP_IV, abComplementIV, 0)) fOK = false; break;
}
{ if (!CryptEncrypt(hDuplicateKey,
NULL,
FALSE,
0,
abPlainPadded,
&dwPlainPadded,
dwPlainPadded)) fOK = false; break; if (!ComputeMAC(m_abRMAC, abPlainPadded, 0, dwPlainPadded, m_abCMAC, &dwSizeMAC))
{ fOK = false; break;
} if (*dwOUTSize < (dwSizeMAC + dwPlainPadded))
Page 54 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
}
{
} fOK = false; break; memcpy(abOUT, abPlainPadded, dwPlainPadded); memcpy(&abOUT[dwPlainPadded], m_abCMAC, dwSizeMAC);
*dwOUTSize = dwSizeMAC + dwPlainPadded;
} while (false);
CryptDestroyKey(hDuplicateKey); delete[] abPlainPadded; return fOK;
March 2012
© 2012 HID Global Corporation. All rights reserved.
Page 55 of 72
Software Developer Guide, 5326-903, Rev A.0
7.13 Wrap
bool CSecureChannel::WrapInput(CString strIN, CString* strOUT)
{ bool fRet = true;
BYTE *pbData1 = new BYTE[strIN.GetLength() / 2];
DWORD dwSize1 = strIN.GetLength() / 2;
BYTE *pbData2 = new BYTE[((DWORD)ceil((dwSize1 + 1.0) / 16.0) + 1 ) * 16];
DWORD dwSize2 = ((DWORD)ceil((dwSize1 + 1.0) / 16.0) + 1 ) * 16;
} do{ if ( !ConvertStringToHex(strIN, pbData1, &dwSize1) )
{ fRet = false; break;
} if ( !WrapInput(pbData1, dwSize1, pbData2, &dwSize2) )
{
} fRet = false; break; if ( !ConvertHexToString(pbData2, dwSize2, strOUT) )
{
}
} while (false); fRet = false; break; delete[] pbData1; delete[] pbData2; return fRet;
March 2012 Page 56 of 72
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
7.14 Unwrap 1
bool CSecureChannel::Unwrap(BYTE* abIN, DWORD dwINSize, BYTE* abOUT, DWORD
*dwOUTSize)
{ bool fOK = true;
BYTE abComplementIV[16];
DWORD dwEncrypted = dwINSize - 16;
BYTE *abEncrypted = new BYTE[dwEncrypted];
DWORD dwUnPadded = dwINSize - 16;
BYTE *abUnPadded = new BYTE[dwUnPadded];
DWORD dwMACSize = sizeof(m_abRMAC);
HCRYPTKEY hDuplicateKey;
CryptDuplicateKey(m_hSENC, 0, 0, &hDuplicateKey); do
{ if (dwINSize < 16)
{ fOK = false;
} break;
// compute and check the MAC if (!ComputeMAC(m_abCMAC, abIN, 0, dwINSize - 16, m_abRMAC,
&dwMACSize))
{ fOK = false;
} break; if (memcmp(m_abRMAC, &abIN[dwINSize-16], dwMACSize) != 0)
{ fOK = false; break;
Page 57 of 72 March 2012
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
}
&dwEncrypted)) if (dwINSize > 16)
{ for (int ii = 0; ii < 16; ++ii)
{ abComplementIV[ii] = ~m_abCMAC[ii];
} memcpy(abEncrypted, abIN, dwINSize - 16); dwEncrypted = dwINSize - 16; if (!CryptSetKeyParam(hDuplicateKey, KP_IV, abComplementIV, 0))
{
} fOK = false; break; if (!CryptDecrypt(hDuplicateKey, NULL, FALSE, 0, abEncrypted,
}
}
{ fOK = false; break; if (!UnPad(abEncrypted, dwEncrypted, abUnPadded, &dwUnPadded))
{ fOK = false; break;
} else memcpy(abOUT, abUnPadded, dwUnPadded);
*dwOUTSize = dwUnPadded;
March 2012 Page 58 of 72
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
}
{
}
} while (false);
*dwOUTSize = 0; delete[] abUnPadded; delete[] abEncrypted;
CryptDestroyKey(hDuplicateKey); if (!fOK)
*dwOUTSize = 0; return fOK;
//
//
//
7.15 Unwrap 2
bool CSecureChannel::Unwrap(CString strIN, CString* strOUT)
{ bool fRet = true;
BYTE *pbData1; pbData1 = (BYTE*)malloc(strIN.GetLength() / 2); pbData1 = new BYTE[(strIN.GetLength() / 2) + 1];//(strIN.GetLength() / 2) + 1
BYTE *pbData2; pbData2 = new BYTE[(strIN.GetLength() / 2) + 1]; pbData2 = (BYTE*)malloc(strIN.GetLength() / 2);
DWORD dwSize1;
DWORD dwSize2; memset(pbData1, 0x00, (strIN.GetLength() / 2) + 1); memset(pbData2, 0x00, (strIN.GetLength() / 2) + 1); do{ dwSize1 = strIN.GetLength() / 2; if ( !ConvertStringToHex(strIN, pbData1, &dwSize1) )
{ fRet = false; break;
March 2012 Page 59 of 72
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
}
} dwSize2 = strIN.GetLength() / 2; if ( !Unwrap(pbData1, dwSize1, pbData2, &dwSize2) )
{
} fRet = false; break; if ( !ConvertHexToString(pbData2, dwSize2, strOUT) )
{ fRet = false; break;
}
} while (false); delete[] pbData2; delete[] pbData1; return fRet;
Page 60 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
7.16 Covert String to Hex
bool CSecureChannel::ConvertStringToHex(CString strInput, BYTE *acOutput, DWORD
*dwLength)
{
DWORD dwLengthIn = *dwLength; int
DWORD
DWORD iResult = 0; ii = 0; bHex = 0x00;
} for (ii = 0; ii < strInput.GetLength()/2; ++ii)
{ if ( ii < dwLengthIn )
{ iResult = sscanf_s(strInput.Mid(ii * 2, 2), "%02x", &bHex);
(BYTE)acOutput[ii] = (BYTE)bHex; if (iResult != 1) return false;
}
} else
*dwLength = ii; return true; return false;
March 2012
© 2012 HID Global Corporation. All rights reserved.
Page 61 of 72
Software Developer Guide, 5326-903, Rev A.0
7.17 Convert Hex To String
bool CSecureChannel::ConvertHexToString(BYTE *acInput, DWORD dwLength, CString
*strOutput)
{
CString strTemp;
}
*strOutput = ""; for (DWORD ii = 0; ii < dwLength; ++ii)
}
{ strTemp = *strOutput; strOutput->Format("%s%02X", strTemp, (unsigned char)acInput[ii]); return true;
Page 62 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
8 Appendix Reader Configuration References
8.1 Reader Capabilities
Table 2 - Reader Capabilities Structure
Root Branch readerCapabilities [A0h] deviceID [81h] productName [82h] productPlatform [83h] enabledCLFeatures [84h] frirmwareVersion [85h] sioProcessorVersion[86h] sdrVersion [87h] hfControllerVersion [88h] hardwareVersion [89h] hostInterfaces [8Ah] numberOfContactlessSlots [8Ch] humanInterfaces [AEh] vendorName [8Fh] sioProcessorFirmwareID [90h] exchangeLevel [91h] serialNumber [92h] hfControllerType [93h]
8.1.1 Device ID
Relative TLV:
Access:
Type:
Length:
Value:
Description:
Get APDU
A0 02 81 00
Read-only
OCTET STRING
2
00 01
Device Identifier
FF70076B 08 A206A004A0028100 00
March 2012
© 2012 HID Global Corporation. All rights reserved.
Page 63 of 72
Software Developer Guide, 5326-903, Rev A.0
8.1.2 Product Name
Relative TLV: A0 02 82 00
Access: Read-only
Type:
Length:
0 terminated String
13
Value:
Description:
Get APDU
“OMNIKEY 5326”
Name of product
FF70076B 08 A206A004A0028200 00
8.1.3 Product Platform
Relative TLV: A0 02 83 00
Access: Read-only
Type:
Length:
0 terminated String
8
Value:
Description:
Get APDU
“AviatoR”
Name of processor platform
FF70076B 08 A206A004A0028300 00
8.1.4 Enabled Contactless Features
Relative TLV: A0 02 84 00
Access:
Type:
Read-only
OCTET STRING
Length:
Value:
Description:
2
0000 1000 0011 0000b
Flags for supported contactless features
Bit 4 – SIO Processor available
Bit 5 – LF Processor available (SDR)
Bit 11 – PicoPass 15693-2 support available
Get APDU FF70076B 08 A206A004A0028400 00
8.1.5 Firmware Version
Relative TLV: A0 02 85 00
Access: Read-only
Type:
Length:
Value:
Description:
Get APDU
OCTET STRING
3
XX YY ZZ
FwVersionMajor + FwVersionMinor + BuildNr
FF70076B 08 A206A004A0028500 00
Page 64 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
8.1.6 SIO Processor Version
Relative TLV: A0 02 86 00
Access: Read-only
Type:
Length:
OCTET STRING
2
Value:
Description:
Get APDU
XX YY
Version number of SIO Processor
FF70076B 08 A206A004A0028600 00
8.1.7 SDR Version
Relative TLV: A0 02 87 00
Access: Read-only
Type:
Length:
OCTET STRING
6
Value:
Description:
XX XX XX XX XX 00
Version string of SDR (low frequency processor)
NULL terminated string for example, “03.07”
Get APDU FF70076B 08 A206A004A0028700 00
8.1.8 HF Controller Version
Relative TLV: A0 02 88 00
Access:
Type:
Read-only
OCTET STRING
Length:
Value:
Description:
Get APDU
1
XX
CLRC663 version register
FF70076B 08 A206A004A0028800 00
8.1.9 Hardware Version
Relative TLV: A0 02 89 00
Access: Read-only
Type:
Length:
Value:
Description:
0 terminated string variable
End Item Number ; Revision; Version Index
Hardware version string according AGILE: first part = End Item Number + Delimiter second part = Revision + Delimiter third part = Version Index
Get APDU FF70076B 08 A206A004A0028900 00
Page 65 of 72 March 2012
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
8.1.10 Host Interface Flags
Relative TLV: A0 02 8A 00
Access: Read-only
Type:
Length:
Value:
Description:
OCTET STRING
1
0000 0010b
Get APDU
Flags for available Host interfaces
Bit 1 – USB available
FF70076B 08 A206A004A0028A00 00
8.1.11 Number of Contact Slots
Relative TLV: A0 02 8B 00
Access: Read-only
Type:
Length:
UNSIGNED INTEGER 8
1
Value:
Description:
Get APDU
0
Number of available contact slots
FF70076B 08 A206A004A0028B00 00
8.1.12 Number of Contactless Slots
Relative TLV: A0 02 8C 00
Access: Read-only
Type:
Length:
Value:
Description:
Get APDU
UNSIGNED INTEGER 8
1
1
Number of available contactless slots
FF70076B 08 A206A004A0028C00 00
8.1.13 Number of Antennas
Relative TLV: A0 02 8D 00
Access: Read-only
Type:
Length:
Value:
Description:
Get APDU
UNSIGNED INTEGER 8
1
1
Number of available high frequency antennas
FF70076B 08 A206A004A0028D00 00
Page 66 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
8.1.14 Human Interfaces Descriptor
Relative TLV: A0 02 AE 00
Access: Read-only
Type:
Length:
Value:
Description:
Get APDU
UNSIGNED INTEGER 8 variable
Constructed TLV structure
TLV Description of available human interfaces
FF70076B 08 A206A004A002AE00 00
8.1.15 Vendor Name
Relative TLV: A0 02 8F 00
Access: Read-only
Type:
Length:
0 TERMINATED STRING
11
Value:
Description:
Get APDU
“HID Global”
Vendor name
FF70076B 08 A206A004A0028F00 00
8.1.16 SIO Processor Firmware ID
Relative TLV: A0 02 90 00
Access: Read-only
Type:
Length:
OCTET STRING
6
Value:
Description:
Get APDU
XX XX XX XX XX XX
SIO processor firmware identifier
FF70076B 08 A206A004A0029000 00
8.1.17 Exchange Level Flags
Relative TLV: A0 02 91 00
Access: Read-only
Type:
Length:
OCTET STRING
1
Value:
Description:
0000 0001b
CCID exchange level flags:
Bit 0 – Short APDU exchange level with CCID
Get APDU FF70076B 08 A206A004A0029100 00
Page 67 of 72 March 2012
© 2012 HID Global Corporation. All rights reserved.
Software Developer Guide, 5326-903, Rev A.0
8.1.18 Serial Number
Relative TLV: A0 02 92 00
Access: Read-only
Type:
Length:
OCTET STRING
9
Value:
Description:
Get APDU
XX XX XX XX XX XX XX XX XX
Unique IFD serial number
FF70076B 08 A206A004A0029200 00
8.1.19 HF Controller Type
Relative TLV: A0 02 93 00
Access: Read-only
Type:
Length:
0 TERMINATED STRING
6
Value:
Description:
“RC663”
Type of integrated high frequency front end controller
Get APDU FF70076B 08 A206A004A0029300 00
8.1.20 Size of User EEPROM
Relative TLV: A0 02 94 00
Access: Read-only
Type:
Length:
Value:
Description:
Get APDU
UNSIGNED INTEGER 16
2
04 00
Size of user EEPROM for free use
FF70076B 08 A206A004A0029400 00
Page 68 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
8.2 Reader Configuration Control
Root Branch readerConfigurationControl [A9h] applySetValues [80h] restoreFactoryDefaults [81h]
8.2.1 Apply Set Values
Relative TLV: A9 02 80 00
Access: Not accessible
Type:
Length:
Description:
Get APDU
COMMAND
0 byte
Apply the Configuration items for the runtime system
FF70076B 08 A206A104A9028000
8.2.2 Restore Factory Defaults
Relative TLV: A9 02 81 00
Access: Not accessible
Type:
Length:
Description:
COMMAND
0 byte
Restore the factory defaults.
This means that any custom values will be lost.
Get APDU FF70076B 08 A206A104A9028100
March 2012
© 2012 HID Global Corporation. All rights reserved.
Page 69 of 72
Software Developer Guide, 5326-903, Rev A.0
9 Appendix Definitions, Abbreviations and Symbols
MSDN
OID
PAC
PACS
PDU
PC/SC
SIO
AES
APDU
API
ASN.1
BER
CLA
DER
MAC
Advanced Encryption Standard
Application Protocol Data Unit
Application Programming Interface
Abstract Syntax Notation One
Basic Encoding Rules
Class byte of an APDU
Distinguished Encoding Rules
Message Authentication Code
Microsoft
®
Developer Network
Object Identifier
Physical Access Control
PAC Physical Access Control Services
Protocol Data Unit
Personal Computer/Smart Card
Secure Identity Object
Page 70 of 72
© 2012 HID Global Corporation. All rights reserved.
March 2012
Software Developer Guide, 5326-903, Rev A.0
10 Appendix References
[ISO 7816-4]
[ISO 8825]
[ISO 9797-1]
[PCSC-3-Sup-CL]
[PCSC-3]
[PCSC-3-Sup]
[PCSC-3-AMD]
ISO 7816-4
Identification cards — Integrated circuit cards -
Part 4: Organization, security and commands for
Interchange
Second edition - 2005-01-15
ISO/IEC8825 ASN.1 encoding rules:
Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)
Fourth edition 2008-12-15 or
X.690
Information technology – ASN.1 encoding rules:
Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)
ISO 9797-1
Information technology - Security techniques –
Message Authentication Codes (MACs) Part 1:
Mechanisms using a block cipher
Second edition - 2011-03-01
Interoperability Specification for ICCs and Personal Computer Systems
Part 3. Supplemental Document for Contactless ICCs
Revision 2.02.00
Interoperability Specification for ICCs and Personal Computer Systems
Part 3. Requirements for PC-Connected Interface Devices
Revision 2.01.09
Interoperability Specification for ICCs and Personal Computer Systems
Part 3. Supplemental Document
Revision 2.01.08
Interoperability Specification for ICCs and Personal Computer Systems
Part 3. Requirements for PC-Connected Interface Devices - AMENDMENT 1
Revision 2.01.09
March 2012 Page 71 of 72
© 2012 HID Global Corporation. All rights reserved.
HID Global Headquarters:
North America: +1 949 732 2000
Toll Free: 1 800 237 7769
Europe, Middle East, Africa: +49 6123 791 0
Asia Pacific: +852 3160 9800
Latin America: +52 477 779 1492 support.hidglobal.com h i d g l o b a l . c o m
Изтегляне
Реклама