VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/Library/CommonLib/EfiUsb.c
diff options
context:
space:
mode:
Diffstat (limited to 'Library/CommonLib/EfiUsb.c')
-rw-r--r--Library/CommonLib/EfiUsb.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/Library/CommonLib/EfiUsb.c b/Library/CommonLib/EfiUsb.c
index b5bdac5..f885cc6 100644
--- a/Library/CommonLib/EfiUsb.c
+++ b/Library/CommonLib/EfiUsb.c
@@ -16,9 +16,11 @@ https://opensource.org/licenses/LGPL-3.0
#include <Library/DevicePathLib.h>
#include <Library/PrintLib.h>
#include <Protocol/UsbIo.h>
+#include <Library/BaseMemoryLib.h>
EFI_HANDLE* gUSBHandles = NULL;
UINTN gUSBCount = 0;
+UINTN gUSBSelect = 0;
EFI_STATUS
InitUsb() {
@@ -86,3 +88,61 @@ UsbGetId(
*id = buff;
return EFI_SUCCESS;
}
+
+//////////////////////////////////////////////////////////////////////////
+// Smart card over usb
+//////////////////////////////////////////////////////////////////////////
+
+/**
+* Send APDU to smart card
+* @param[IN] cmd command to send
+* @param[IN] cmdLen size of Apdu command
+* @param[OUT] resp smart card response
+* @param[OUT] respLen smart card response length
+* @param[OUT] statusSc smart card status (0x9000 - OK)
+* @return EFI_SUCCESS if send success. Or platform dependent error
+*/
+EFI_STATUS
+UsbScTransmit(
+ IN EFI_USB_IO_PROTOCOL *UsbIO,
+ IN UINT8* cmd,
+ IN UINTN cmdLen,
+ OUT UINT8* resp,
+ OUT UINTN* respLen,
+ OUT UINT16* statusSc
+ ) {
+ CCID_HEADER_OUT* oheader = (CCID_HEADER_OUT*)cmd;
+ CCID_HEADER_IN* iheader = (CCID_HEADER_IN*)resp;
+ EFI_STATUS status;
+ UINT32 usbres;
+ UINTN len;
+ UINTN resplen;
+ // Init CCID HEADER
+ SetMem(cmd,sizeof(CCID_HEADER_OUT), 0);
+ oheader->bMessageType = PC_to_RDR_XfrBlock_Message;
+ oheader->bSeq = 0x99;
+ oheader->dwLength = (UINT32)(cmdLen - sizeof(CCID_HEADER_OUT));
+ len = cmdLen;
+ // Send APDU
+ PrintBytes(cmd, len);
+ OUT_PRINT(L"\n");
+ status = UsbIO->UsbBulkTransfer(UsbIO, 2,cmd, &len, 5000, &usbres);
+ if (EFI_ERROR(status)) {
+ ERR_PRINT(L"SC send: %r\n", status);
+ return status;
+ }
+ len = *respLen;
+ SetMem(resp, len, 0);
+ do {
+ status = UsbIO->UsbBulkTransfer(UsbIO, 0x81, resp, &len, 5000, &usbres);
+ } while ((status == EFI_SUCCESS) && ((iheader->bStatus & 0xC0) == 0x80)); // Timeout? => retry
+ if (EFI_ERROR(status)) {
+ ERR_PRINT(L"SC resp: %r\n", status);
+ return status;
+ }
+ // Parse response
+ resplen = iheader->dwLength;
+ *respLen = iheader->dwLength + sizeof(CCID_HEADER_IN);
+ *statusSc = (UINT16)(resp[sizeof(CCID_HEADER_IN) + resplen - 1]) | (((UINT16)resp[sizeof(CCID_HEADER_IN) + resplen - 2]) << 8);
+ return EFI_SUCCESS;
+}