Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
351 views
in Technique[技术] by (71.8m points)

usbserial - How to get USB Token (Feitian Auto ePass 2003 FIPS USB Token) serial number in UEFI Application?

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.
");
    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.
");
        goto ErrorExit;
    }
 
    Status = UsbIo->UsbGetDeviceDescriptor( UsbIo, &DevDesc );
    if (EFI_ERROR(Status)) {
        Print(L"ERROR: UsbGetDeviceDescriptor.
");
        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.
");
        goto ErrorExit;
    }

    if (InterfaceDescriptor.InterfaceClass != CLASS_CCID) {
        continue;            
    }

    Print(L":::::::::::::::::::::: CCID ::::::::::::::::::::::
");

    //
    // Get all supported languages.
    //
    TableSize = 0;
    LangIDTable = NULL;
    Status = UsbIo->UsbGetSupportedLanguages(UsbIo, &LangIDTable, &TableSize);
    if (EFI_ERROR(Status)) {
        Print(L"ERROR: UsbGetSupportedLanguages.
");
        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
", 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
", 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 
");
            continue;
        }

        Print(L"SerialNumber :: %s
", SerialNumber);

        FreePool(SerialNumber);
        break;
    }

    Print(L"usbIndex ::%d
", usbIndex);
    Print(L"IdVendor ::%d
", DevDesc.IdVendor);
    Print(L"IdProduct ::%d
", DevDesc.IdProduct);    
}

Print(L"
");
FreePool(HandleBuffer);
return Status;
question from:https://stackoverflow.com/questions/65935926/how-to-get-usb-token-feitian-auto-epass-2003-fips-usb-token-serial-number-in-u

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...