Developing UEFI Based application for enabling pre-boot authentication using Feitian Auto ePass 2003 FIPS USB Token. I'm still in the initial stage of the development process.
Now I'm able to fetch Manufacturer, Product Code of the token by using UsbIo->UsbGetDeviceDescriptor protocol. But when I try to find serial number it's throwing an error.
Is there any other way to find the serial number of the USB Token? Please help me on this..
This is my sample code for finding serial number
EFI_USB_DEVICE_DESCRIPTOR DevDesc;
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
EFI_USB_CONFIG_DESCRIPTOR ConfigDescriptor;
EFI_USB_IO_PROTOCOL *UsbIo;
EFI_STATUS Status;
EFI_HANDLE *HandleBuffer = NULL;
BOOLEAN LangFound;
UINTN HandleCount;
UINT8 EndpointNumber;
CHAR16* ManufacturerString = NULL;
CHAR16* ProductString = NULL;
CHAR16* SerialNumber = NULL;
UINT16* LangIDTable;
UINT16 TableSize;
INTN Index;
int index;
unsigned char* device_descriptor, * ccid_descriptor;
EFI_USB_DEVICE_REQUEST DevReq;
UINT32 Status_uint;
Status = gBS->LocateHandleBuffer( ByProtocol,
&gEfiUsbIoProtocolGuid,
NULL,
&HandleCount,
&HandleBuffer );
if (EFI_ERROR(Status)) {
Print(L"ERROR: LocateHandleBuffer.\n");
goto ErrorExit;
}
UINT8 usbIndex;
for (usbIndex = 0; usbIndex < HandleCount; usbIndex++) {
Status = gBS->HandleProtocol( HandleBuffer[usbIndex],
&gEfiUsbIoProtocolGuid,
(VOID**)&UsbIo );
if (EFI_ERROR(Status)) {
Print(L"ERROR: Open UsbIo.\n");
goto ErrorExit;
}
Status = UsbIo->UsbGetDeviceDescriptor( UsbIo, &DevDesc );
if (EFI_ERROR(Status)) {
Print(L"ERROR: UsbGetDeviceDescriptor.\n");
goto ErrorExit;
}
Status = UsbIo->UsbGetConfigDescriptor( UsbIo, &ConfigDescriptor );
if (EFI_ERROR (Status))
{
Print(L"UsbGetConfigDescriptor %d", Status);
goto ErrorExit;
}
Status = UsbIo->UsbGetInterfaceDescriptor( UsbIo, &InterfaceDescriptor );
if (EFI_ERROR (Status)) {
Print(L"ERROR: UsbGetInterfaceDescriptor.\n");
goto ErrorExit;
}
if (InterfaceDescriptor.InterfaceClass != CLASS_CCID) {
continue;
}
Print(L":::::::::::::::::::::: CCID ::::::::::::::::::::::\n");
//
// Get all supported languages.
//
TableSize = 0;
LangIDTable = NULL;
Status = UsbIo->UsbGetSupportedLanguages(UsbIo, &LangIDTable, &TableSize);
if (EFI_ERROR(Status)) {
Print(L"ERROR: UsbGetSupportedLanguages.\n");
return Status;
}
/* Get Manufacturer string */
for (Index = 0; Index < TableSize / sizeof(LangIDTable[0]); Index++) {
ManufacturerString = NULL;
Status = UsbIo->UsbGetStringDescriptor(UsbIo,
LangIDTable[Index],
DevDesc.StrManufacturer,
&ManufacturerString);
if (EFI_ERROR(Status) || (ManufacturerString == NULL)) {
continue;
}
Print(L"StrManufacturer ::%s\n", ManufacturerString);
FreePool(ManufacturerString);
break;
}
/* Get Product string */
for (Index = 0; Index < TableSize / sizeof(LangIDTable[0]); Index++) {
ProductString = NULL;
Status = UsbIo->UsbGetStringDescriptor(UsbIo,
LangIDTable[Index],
DevDesc.StrProduct,
&ProductString);
if (EFI_ERROR(Status) || (ProductString == NULL)) {
continue;
}
Print(L"StrProduct ::%s\n", ProductString);
FreePool(ProductString);
break;
}
/* Get Serial string */
for (Index = 0; Index < TableSize / sizeof(LangIDTable[0]); Index++) {
SerialNumber = NULL;
Status = UsbIo->UsbGetStringDescriptor(UsbIo,
LangIDTable[Index],
DevDesc.StrSerialNumber,
&SerialNumber);
if (EFI_ERROR(Status) || (SerialNumber == NULL)) {
Print(L"Error in finding SerialNumber \n");
continue;
}
Print(L"SerialNumber :: %s\n", SerialNumber);
FreePool(SerialNumber);
break;
}
Print(L"usbIndex ::%d\n", usbIndex);
Print(L"IdVendor ::%d\n", DevDesc.IdVendor);
Print(L"IdProduct ::%d\n", DevDesc.IdProduct);
}
Print(L"\n");
FreePool(HandleBuffer);
return Status;
From what I have read, the Feitian Technologies ePass2003 uses an Infineon M7893 or SLE 78CUFX5000PH (M7893-B) security chip.
As you have found out, the serial number for the ePass2003 is not stored in the USB device descriptor but in the security chip.
To obtain chip global data such as OEM information, algorithm support, FIPS mode indicator, RAM size and serial number, the GetData primitive is used. See the M7893 programming guide. if you can obtain access to it.
The driver for ePass2003 in OpenSC is called “epass2003”. The source code is currently available at https://github.com/OpenSC/OpenSC/blob/master/src/libopensc/card-epass2003.c. It has dependencies on OpenSSL and ASN.1 and some non-EDK2 headers, but these are easily worked around.
If all you are looking for is the serial number, it should be fairly easy to write a UEFI application (or driver) to get that information either by studying how the OpenSC ePass2003 driver does it (hint - look at epass2003_get_serialnr
or studying the ePass2003 SDK which is available for free from Feitain and elsewhere.
The UEFI 2.5 specification released in April 2015 detailed 2 protocols relating to smart cards, i.e. Smart Card Reader and Smart Card Edge.
typedef struct _EFI_SMART_CARD_READER_PROTOCOL {
EFI_SMART_CARD_READER_CONNECT SCardConnect;
EFI_SMART_CARD_READER_DISCONNECT SCardDisconnect;
EFI_SMART_CARD_READER_STATUS SCardStatus;
EFI_SMART_CARD_READER_TRANSMIT SCardTransmit;
EFI_SMART_CARD_READER_CONTROL SCardControl;
EFI_SMART_CARD_READER_GET_ATTRIB SCardGetAttrib;
} EFI_SMART_CARD_READER_PROTOCOL;
typedef struct _EFI_SMART_CARD_EDGE_PROTOCOL {
EFI_SMART_CARD_EDGE_GET_CONTEXT GetContext;
EFI_SMART_CARD_EDGE_CONNECT Connect;
EFI_SMART_CARD_EDGE_DISCONNECT Disconnect;
EFI_SMART_CARD_EDGE_GET_CSN GetCsn;
EFI_SMART_CARD_EDGE_GET_READER_NAME GetReaderName;
EFI_SMART_CARD_EDGE_VERIFY_PIN VerifyPin;
EFI_SMART_CARD_EDGE_GET_PIN_REMAINING GetPinRemaining;
EFI_SMART_CARD_EDGE_GET_DATA GetData;
EFI_SMART_CARD_EDGE_GET_CREDENTIAL GetCredential;
EFI_SMART_CARD_EDGE_SIGN_DATA SignData;
EFI_SMART_CARD_EDGE_DECRYPT_DATA DecryptData;
EFI_SMART_CARD_EDGE_BUILD_DH_AGREEMENT BuildDHAgreement;
} EFI_SMART_CARD_EDGE_PROTOCOL;
EDK2 does not contain a sample implementation at present. However, you may be interested in the GPL2-licensed sample implementation by Ludovic Rousseau which is available at https://github.com/LudovicRousseau/edk2/tree/SmartCard
. The implementation code, which is circa 5 years old and which I have not tested, is at MdeModulePkg/Library/SmartCardReader
. Read his blog (https://ludovicrousseau.blogspot.com/) also as he provides useful sample applications also.