diff options
Diffstat (limited to 'Library/CommonLib')
-rw-r--r-- | Library/CommonLib/EfiConsole.c | 124 | ||||
-rw-r--r-- | Library/CommonLib/EfiUsb.c | 60 |
2 files changed, 180 insertions, 4 deletions
diff --git a/Library/CommonLib/EfiConsole.c b/Library/CommonLib/EfiConsole.c index 3ab1515..0d94235 100644 --- a/Library/CommonLib/EfiConsole.c +++ b/Library/CommonLib/EfiConsole.c @@ -2,7 +2,7 @@ EFI console helpers routines/wrappers
Copyright (c) 2016. Disk Cryptography Services for EFI (DCS), Alex Kolotnikov, Alex Kolotnikov
-Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
+Copyright (c) 2016. VeraCrypt, Mounir IDRASSI
This program and the accompanying materials are licensed and made available
under the terms and conditions of the GNU Lesser General Public License, version 3.0 (LGPL-3.0).
@@ -27,15 +27,51 @@ UINTN gCELine = 0; VOID
PrintBytes(
- IN UINT8* Data,
- IN UINT32 Size)
+ IN UINT8* Data,
+ IN UINTN Size)
+{
+ UINTN i;
+ for (i = 0; i < Size; ++i) {
+ UINTN val = Data[i];
+ OUT_PRINT(L"%02X", val);
+ }
+}
+
+/*
+#define DUMP_MAX_LINE_LEN 1024
+typedef struct _DUMP_STATE {
+ CHAR8 line[DUMP_MAX_LINE_LEN];
+
+} DUMP_STATE;
+
+VOID
+DumpBytes(
+ IN UINT8* Data,
+ IN UINT32 Size)
{
UINT32 i;
+ CHAR8 text[17];
+ UINTN addr = 0;
for (i = 0; i < Size; ++i) {
+ if ((addr & 0x0F) == 0) {
+ SetMem(text, sizeof(text) - 1, ' ');
+ text[16] = 0;
+ OUT_PRINT(L"%08X: ", addr);
+ }
UINT32 val = Data[i];
- OUT_PRINT(L"%02X", val);
+ OUT_PRINT(L"%02X ", val);
+ if (val > 31 && val < 127) {
+ text[i & 0x0F] = (CHAR8)(val & 0x0FF);
+ }
+ addr++;
+ if ((addr & 0x0F) == 0) {
+ OUT_PRINT(L"|%a|", text);
+ }
+ }
+ if (addr & 0x0F) != 0) {
}
}
+*/
//////////////////////////////////////////////////////////////////////////
// Input
@@ -353,6 +389,86 @@ AsciiStrToGuid( return res;
}
+BOOLEAN
+AsciiHexToBytes(
+ OUT UINT8 *b,
+ IN UINTN *bytesLen,
+ IN CHAR8 *str
+ )
+{
+ UINT8 low = 0;
+ UINT8 high = 0;
+ BOOLEAN res = TRUE;
+ UINTN cnt = 0;
+ UINTN len = 0;
+ CHAR8 *pos = str;
+ if (b == NULL || str == NULL || bytesLen == NULL) return FALSE;
+ if (*bytesLen == 0) return TRUE;
+ len = AsciiStrLen(str);
+ if (len == 0) return TRUE;
+ if (len > 2 && str[0] == '0' && str[1] == 'x') {
+ pos += 2;
+ }
+ if ((len & 1) == 0) {
+ res = AsciiHexToDigit(&high, pos++);
+ }
+ res = res && AsciiHexToDigit(&low, pos++);
+ *b = low | high << 4;
+ b++;
+ cnt++;
+ while (res && (cnt < *bytesLen) && (*pos != 0)) {
+ res = AsciiHexToDigit(&high, pos++);
+ res = res && AsciiHexToDigit(&low, pos++);
+ *b = low | high << 4;
+ b++;
+ cnt++;
+ }
+ *bytesLen = cnt;
+ return res;
+}
+
+BOOLEAN
+StrHexToBytes(
+ OUT UINT8 *b,
+ IN UINTN *bytesLen,
+ IN CHAR16 *str
+ )
+{
+ UINT8 low = 0;
+ UINT8 high = 0;
+ BOOLEAN res = TRUE;
+ UINTN cnt = 0;
+ UINTN len = 0;
+ CHAR16 *pos = str;
+ if (b == NULL || str == NULL || bytesLen == NULL) return FALSE;
+ if (*bytesLen == 0) return TRUE;
+ len = StrLen(str);
+ if (len == 0) return TRUE;
+ if (len > 2 && str[0] == '0' && str[1] == 'x') {
+ pos += 2;
+ }
+ if ((len & 1) == 0) {
+ res = AsciiHexToDigit(&high, (CHAR8*)pos);
+ pos++;
+ }
+ res = res && AsciiHexToDigit(&low, (CHAR8*)pos);
+ pos++;
+ *b = low | high << 4;
+ b++;
+ cnt++;
+ while (res && (cnt < *bytesLen) && (*pos != 0)) {
+ res = AsciiHexToDigit(&high, (CHAR8*)pos);
+ pos++;
+ res = res && AsciiHexToDigit(&low, (CHAR8*)pos);
+ pos++;
+ *b = low | high << 4;
+ b++;
+ cnt++;
+ }
+ *bytesLen = cnt;
+ return res;
+}
+
//////////////////////////////////////////////////////////////////////////
// Console menu
//////////////////////////////////////////////////////////////////////////
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;
+}
|