From 206b17fef7d7249afc1c92e8cf83c966716cb402 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 10 Dec 2010 16:31:25 +0900 Subject: [PATCH] works better on windows --- ChangeLog | 18 ++++++++ NEWS | 6 ++- THANKS | 1 + src/usb-cdc-vport.c | 13 ++---- src/usb-icc.c | 23 +++++++--- src/usb_desc.c | 40 +++++++++--------- src/usb_prop.c | 100 ++++++++++++++++++++++++++++++++++++++------ 7 files changed, 151 insertions(+), 50 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc51d8b..59ff218 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2010-12-10 NIIBE Yutaka + + * src/usb-cdc-vport.c (Virtual_Com_Port_Data_Setup) + (Virtual_Com_Port_NoData_Setup): No check for class&interface + request. + + * src/usb-icc.c (ATR): Fixed. + + * src/usb_desc.c (/* ICC Descriptor*/): bcdCCID = 1.1. + dwDefaultClock = dwMaximumClock = 3571. + dwFeatures 0x00040842. + + * src/usb_prop.c (gnuk_clock_frequencies, gnuk_data_rates): New. + (gnuk_nothing_todo): Removed. + (gnuk_setup_with_data, gnuk_setup_with_nodata): New. + (Device_Property): Changed to call gnuk_setup_with_data and + gnuk_setup_with_nodata. + 2010-12-09 NIIBE Yutaka * src/usb-icc.c (icc_power_off): Set icc_data_size = 0 to specify diff --git a/NEWS b/NEWS index 92104ce..9beadff 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,7 @@ Gnuk NEWS - User visible changes Released 2010-12-XX, by NIIBE Yutaka ** LED blink -LED blink now shows status output the card. It shows the status of +LED blink now shows status output of the card. It shows the status of CHV3, CHV2, and CHV1 when GPG is accessing the card. ** New board support "STM8S Discovery" @@ -28,6 +28,10 @@ GPG2). For decryption, key import and get_public_key, changes are needed for GPG (scd/ccid-driver.c) to support the case of extended APDU. In short, you can sign with Gnuk by GPG 1. +** Windows support. +Gnuk could run on MS Windows, with "usbccid" driver and "winscard" +driver. + * Major changes in Gnuk 0.4 diff --git a/THANKS b/THANKS index 430ea94..bcb7c49 100644 --- a/THANKS +++ b/THANKS @@ -5,6 +5,7 @@ Gnuk was originally written by NIIBE Yutaka. People contributed by encouraging the development, testing the implementation, suggesting improvements, or fixing bugs. Here is a list of those people. +Achim Pietig achim@pietig.com Andre Zepezauer andre.zepezauer@student.uni-halle.de Hironobu SUZUKI hironobu@h2np.net Jan Suhr jan@suhr.info diff --git a/src/usb-cdc-vport.c b/src/usb-cdc-vport.c index 5ca2df6..23a1c81 100644 --- a/src/usb-cdc-vport.c +++ b/src/usb-cdc-vport.c @@ -68,15 +68,9 @@ Virtual_Com_Port_Data_Setup (uint8_t RequestNo) CopyRoutine = NULL; if (RequestNo == USB_CDC_REQ_GET_LINE_CODING) - { - if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) - CopyRoutine = Virtual_Com_Port_GetLineCoding; - } + CopyRoutine = Virtual_Com_Port_GetLineCoding; else if (RequestNo == USB_CDC_REQ_SET_LINE_CODING) - { - if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) - CopyRoutine = Virtual_Com_Port_SetLineCoding; - } + CopyRoutine = Virtual_Com_Port_SetLineCoding; if (CopyRoutine == NULL) return USB_UNSUPPORT; @@ -91,8 +85,7 @@ Virtual_Com_Port_Data_Setup (uint8_t RequestNo) static RESULT Virtual_Com_Port_NoData_Setup (uint8_t RequestNo) { - if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT) - && RequestNo == USB_CDC_REQ_SET_CONTROL_LINE_STATE) + if (RequestNo == USB_CDC_REQ_SET_CONTROL_LINE_STATE) /* Do nothing and success */ return USB_SUCCESS; diff --git a/src/usb-icc.c b/src/usb-icc.c index 72d1659..2bffc5c 100644 --- a/src/usb-icc.c +++ b/src/usb-icc.c @@ -229,20 +229,31 @@ volatile enum icc_state icc_state; * ATR (Answer To Reset) string * * TS = 0x3B: Direct conversion - * T0 = 0x94: TA1 and TD1 follow, 4 historical bytes + * T0 = 0xda: TA1, TC1 and TD1 follow, 10 historical bytes * TA1 = 0x11: FI=1, DI=1 + * TC1 = 0xff * TD1 = 0x81: TD2 follows, T=1 - * TD2 = 0x31: TA3 and TB3 follow, T=1 + * TD2 = 0xb1: TA3, TB3 and TD3 follow, T=1 * TA3 = 0xFE: IFSC = 254 bytes * TB3 = 0x55: BWI = 5, CWI = 5 (BWT timeout 3.2 sec) - * Historical bytes: "FSIJ" + * TD3 = 0x1f: TA4 follows, T=15 + * TA4 = 0x03: 5V or 3.3V + * Historical bytes: to be explained... * XOR check * */ static const char ATR[] = { - 0x3B, 0x94, 0x11, 0x81, 0x31, 0xFE, 0x55, - 'F', 'S', 'I', 'J', - (0x94^0x11^0x81^0x31^0xFE^0x55^'F'^'S'^'I'^'J') + 0x3b, 0xda, 0x11, 0xff, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0x03, + 0x00, + 0x31, 0x84, /* full DF name, GET DATA, MF */ + 0x73, + 0x80, /* DF full name */ + 0x01, /* 1-byte */ + 0x40, /* Extended Lc and extended Le */ + 0x00, + 0x90, 0x00, + (0xda^0x11^0xff^0x81^0xb1^0xfe^0x55^0x1f^0x03 + ^0x00^0x31^0x84^0x73^0x80^0x01^0x40^0x00^0x90^0x00) }; /* diff --git a/src/usb_desc.c b/src/usb_desc.c index 3005ec7..81d92d1 100644 --- a/src/usb_desc.c +++ b/src/usb_desc.c @@ -55,7 +55,7 @@ static const uint8_t gnukConfigDescriptor[] = { /* Interface Descriptor */ 9, /* bLength: Interface Descriptor size */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */ - 0, /* Index of this interface */ + 0, /* bInterfaceNumber: Index of this interface */ 0, /* Alternate setting for this interface */ 2, /* bNumEndpoints: Bulk-IN, Bulk-OUT */ USB_ICC_INTERFACE_CLASS, @@ -66,17 +66,17 @@ static const uint8_t gnukConfigDescriptor[] = { /* ICC Descriptor */ 54, /* bLength: */ 0x21, /* bDescriptorType: USBDESCR_ICC */ - 0x00, 0x01, /* bcdCCID: revision 1.0 */ + 0x10, 0x01, /* bcdCCID: revision 1.1 (of CCID) */ 0, /* bMaxSlotIndex: */ 1, /* bVoltageSupport: FIXED VALUE */ 0x02, 0, 0, 0, /* dwProtocols: T=1 */ - 0xfc, 0x0d, 0, 0, /* dwDefaultClock: FIXED VALUE */ - 0xfc, 0x0d, 0, 0, /* dwMaximumClock: FIXED VALUE*/ - 1, /* bNumClockSupported: FIXED VALUE*/ - 0x80, 0x25, 0, 0, /* dwDataRate: FIXED VALUE */ - 0x80, 0x25, 0, 0, /* dwMaxDataRate: FIXED VALUE */ + 0xf3, 0x0d, 0, 0, /* dwDefaultClock: 3571 (non-ICCD): 3580 (ICCD) */ + 0xf3, 0x0d, 0, 0, /* dwMaximumClock: 3571 (non-ICCD): 3580 (ICCD) */ + 1, /* bNumClockSupported: FIXED VALUE */ + 0x80, 0x25, 0, 0, /* dwDataRate: 9600: FIXED VALUE */ + 0x80, 0x25, 0, 0, /* dwMaxDataRate: 9600: FIXED VALUE */ 1, /* bNumDataRateSupported: FIXED VALUE */ - 0xfe, 0, 0, 0, /* dwMaxIFSD: */ + 0xfe, 0, 0, 0, /* dwMaxIFSD: 254 */ 0, 0, 0, 0, /* dwSynchProtocols: FIXED VALUE */ 0, 0, 0, 0, /* dwMechanical: FIXED VALUE */ /* @@ -86,22 +86,20 @@ static const uint8_t gnukConfigDescriptor[] = { * It is different now for better interaction to GPG's in-stock * ccid-driver. */ -#ifdef DEBUG - 0x82, 0x04, 0x04, 0x00, /* dwFeatures: - * Short and extended APDU level: 0x40000 + 0x42, 0x08, 0x04, 0x00, /* dwFeatures (not ICCD): + * Short and extended APDU level: 0x40000 * + * (what? means ICCD?) : 0x00800 * * Automatic IFSD : 0x00400 + * NAD value other than 0x00 : 0x00200 + * Can set ICC in clock stop : 0x00100 * Automatic PPS CUR : 0x00080 - * - * Automatic conf. based on ATR : 0x00002 + * Automatic PPS PROP : 0x00040 * + * Auto baud rate change : 0x00020 + * Auto clock change : 0x00010 + * Auto voltage selection : 0x00008 + * Auto activaction of ICC : 0x00004 + * Automatic conf. based on ATR : 0x00002 g */ -#else - 0x42, 0x00, 0x04, 0x00, /* dwFeatures: - * Short and extended APDU level: 0x40000 - * Automatic PPS PROP : 0x00040 - * - * Automatic conf. based on ATR : 0x00002 - */ -#endif 0x40, 0x01, 0, 0, /* dwMaxCCIDMessageLength */ 0xff, /* bClassGetResponse: */ 0xff, /* bClassEnvelope: */ diff --git a/src/usb_prop.c b/src/usb_prop.c index 9949359..3353589 100644 --- a/src/usb_prop.c +++ b/src/usb_prop.c @@ -178,14 +178,95 @@ gnuk_device_Get_Interface_Setting (uint8_t Interface, uint8_t AlternateSetting) return USB_SUCCESS; } -#if !defined(ENABLE_VIRTUAL_COM_PORT) -static RESULT -gnuk_nothing_todo (uint8_t RequestNo) +#define USB_CCID_REQ_ABORT 0x01 +#define USB_CCID_REQ_GET_CLOCK_FREQUENCIES 0x02 +#define USB_CCID_REQ_GET_DATA_RATES 0x03 + +static const uint8_t freq_table[] = { 0xf3, 0x0d, 0, 0, }; /* dwDefaultClock */ +static uint8_t * +gnuk_clock_frequencies (uint16_t len) { - (void)RequestNo; - return USB_UNSUPPORT; + if (len == 0) + { + pInformation->Ctrl_Info.Usb_wLength = sizeof (freq_table); + return NULL; + } + + return (uint8_t *)freq_table; } + +static const uint8_t data_rate_table[] = { 0x80, 0x25, 0, 0, }; /* dwDataRate */ +static uint8_t * +gnuk_data_rates (uint16_t len) +{ + if (len == 0) + { + pInformation->Ctrl_Info.Usb_wLength = sizeof (data_rate_table); + return NULL; + } + + return (uint8_t *)data_rate_table; +} + +static RESULT +gnuk_setup_with_data (uint8_t RequestNo) +{ + if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) + if (pInformation->USBwIndex0 == 0) /* Interface */ + { + if (RequestNo == USB_CCID_REQ_GET_CLOCK_FREQUENCIES) + { + pInformation->Ctrl_Info.CopyData = gnuk_clock_frequencies; + pInformation->Ctrl_Info.Usb_wOffset = 0; + gnuk_clock_frequencies (0); + return USB_SUCCESS; + } + else if (RequestNo == USB_CCID_REQ_GET_DATA_RATES) + { + pInformation->Ctrl_Info.CopyData = gnuk_data_rates; + pInformation->Ctrl_Info.Usb_wOffset = 0; + gnuk_data_rates (0); + return USB_SUCCESS; + } + else + return USB_UNSUPPORT; + } + else + { +#if defined(ENABLE_VIRTUAL_COM_PORT) + return Virtual_Com_Port_Data_Setup (RequestNo); +#else + return USB_UNSUPPORT; #endif + } + else + return USB_UNSUPPORT; +} + +static RESULT +gnuk_setup_with_nodata (uint8_t RequestNo) +{ + if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) + if (pInformation->USBwIndex0 == 0) /* Interface */ + { + if (RequestNo == USB_CCID_REQ_ABORT) + /* wValue: bSeq, bSlot */ + /* Abortion is not supported in Gnuk */ + return USB_UNSUPPORT; + else + return USB_UNSUPPORT; + } + else + { +#if defined(ENABLE_VIRTUAL_COM_PORT) + return Virtual_Com_Port_NoData_Setup (RequestNo); +#else + return USB_UNSUPPORT; +#endif + } + else + return USB_UNSUPPORT; +} /* * Interface to USB core @@ -196,13 +277,8 @@ const DEVICE_PROP Device_Property = { gnuk_device_reset, gnuk_device_Status_In, gnuk_device_Status_Out, -#ifdef ENABLE_VIRTUAL_COM_PORT - Virtual_Com_Port_Data_Setup, - Virtual_Com_Port_NoData_Setup, -#else - gnuk_nothing_todo, - gnuk_nothing_todo, -#endif + gnuk_setup_with_data, + gnuk_setup_with_nodata, gnuk_device_Get_Interface_Setting, gnuk_device_GetDeviceDescriptor, gnuk_device_GetConfigDescriptor,