no ext lc and le but short APDU only
This commit is contained in:
@@ -15,6 +15,9 @@
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "usb_lib.h"
|
||||
extern void usb_lld_to_pmabuf (const void *src, uint16_t addr, uint32_t n);
|
||||
extern void usb_lld_from_pmabuf (void *dst, uint16_t addr, uint32_t n);
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define ValBit(VAR,Place) (VAR & (1 << Place))
|
||||
@@ -460,7 +463,7 @@ void DataStageOut(void)
|
||||
#ifdef STM32F10X_CL
|
||||
OTGD_FS_PCD_EP_Read(ENDP0, Buffer, Length);
|
||||
#else
|
||||
PMAToUserBufferCopy(Buffer, GetEPRxAddr(ENDP0), Length);
|
||||
usb_lld_from_pmabuf (Buffer, GetEPRxAddr(ENDP0), Length);
|
||||
#endif /* STM32F10X_CL */
|
||||
}
|
||||
|
||||
@@ -544,7 +547,7 @@ void DataStageIn(void)
|
||||
#ifdef STM32F10X_CL
|
||||
OTGD_FS_PCD_EP_Write (ENDP0, DataBuffer, Length);
|
||||
#else
|
||||
UserToPMABufferCopy(DataBuffer, GetEPTxAddr(ENDP0), Length);
|
||||
usb_lld_to_pmabuf (DataBuffer, GetEPTxAddr(ENDP0), Length);
|
||||
#endif /* STM32F10X_CL */
|
||||
|
||||
SetEPTxCount(ENDP0, Length);
|
||||
|
||||
@@ -167,7 +167,7 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
|
||||
#endif
|
||||
|
||||
r = rsa_pkcs1_decrypt (&rsa_ctx, RSA_PRIVATE, &output_len,
|
||||
input, output, MAX_RES_APDU_SIZE - 2);
|
||||
input, output, MAX_RES_APDU_DATA_SIZE);
|
||||
rsa_free (&rsa_ctx);
|
||||
if (r < 0)
|
||||
{
|
||||
|
||||
21
src/gnuk.h
21
src/gnuk.h
@@ -36,7 +36,7 @@ struct apdu {
|
||||
uint8_t *cmd_apdu_head; /* CLS INS P1 P2 [ internal Lc ] */
|
||||
uint8_t *cmd_apdu_data;
|
||||
uint16_t cmd_apdu_data_len; /* Nc, calculated by Lc field */
|
||||
uint32_t expected_res_size; /* Ne, calculated by Le field */
|
||||
uint16_t expected_res_size; /* Ne, calculated by Le field */
|
||||
|
||||
/* response APDU */
|
||||
uint16_t sw;
|
||||
@@ -55,10 +55,10 @@ extern struct apdu apdu;
|
||||
#define EV_VERIFY_CMD_AVAILABLE ((eventmask_t)8)
|
||||
#define EV_MODIFY_CMD_AVAILABLE ((eventmask_t)16)
|
||||
|
||||
/* maximum cmd apdu data is key import 22+4+128+128 (proc_key_import) */
|
||||
#define MAX_CMD_APDU_SIZE (7+282) /* header + data */
|
||||
/* maximum res apdu data is public key 5+9+256+2 (gpg_do_public_key) */
|
||||
#define MAX_RES_APDU_SIZE ((5+9+256)+2) /* Data + status */
|
||||
/* Maximum cmd apdu data is key import 22+4+128+128 (proc_key_import) */
|
||||
#define MAX_CMD_APDU_DATA_SIZE (22+4+128+128) /* without header */
|
||||
/* Maximum res apdu data is public key 5+9+256 (gpg_do_public_key) */
|
||||
#define MAX_RES_APDU_DATA_SIZE (5+9+256) /* without trailer */
|
||||
|
||||
#define ICC_MSG_HEADER_SIZE 10
|
||||
|
||||
@@ -68,13 +68,6 @@ extern struct apdu apdu;
|
||||
/* USB buffer size of LL (Low-level): size of single Bulk transaction */
|
||||
#define USB_LL_BUF_SIZE 64
|
||||
|
||||
/*
|
||||
* USB buffer size of USB-ICC driver
|
||||
* (Changing this, dwMaxCCIDMessageLength too !!)
|
||||
*/
|
||||
#define USB_BUF_SIZE ((10 + 10 + MAX_CMD_APDU_SIZE + USB_LL_BUF_SIZE - 1) \
|
||||
/ USB_LL_BUF_SIZE * USB_LL_BUF_SIZE)
|
||||
|
||||
enum icc_state
|
||||
{
|
||||
ICC_STATE_START, /* Initial */
|
||||
@@ -85,7 +78,7 @@ enum icc_state
|
||||
ICC_STATE_SEND, /* APDU Sent Partially */
|
||||
};
|
||||
|
||||
extern volatile enum icc_state icc_state;
|
||||
extern enum icc_state *icc_state_p;
|
||||
|
||||
extern volatile uint8_t auth_status;
|
||||
#define AC_NONE_AUTHORIZED 0x00
|
||||
@@ -116,7 +109,7 @@ extern void ac_reset_admin (void);
|
||||
extern void ac_fini (void);
|
||||
|
||||
|
||||
extern void set_res_apdu (uint8_t sw1, uint8_t sw2);
|
||||
extern void set_res_sw (uint8_t sw1, uint8_t sw2);
|
||||
extern uint16_t data_objects_number_of_bytes;
|
||||
|
||||
extern void gpg_data_scan (const uint8_t *p);
|
||||
|
||||
@@ -287,6 +287,13 @@ static void display_fatal_code (void)
|
||||
|
||||
static void display_status_code (void)
|
||||
{
|
||||
enum icc_state icc_state;
|
||||
|
||||
if (icc_state_p == NULL)
|
||||
icc_state = ICC_STATE_START;
|
||||
else
|
||||
icc_state = *icc_state_p;
|
||||
|
||||
if (icc_state == ICC_STATE_START)
|
||||
{
|
||||
set_led (1);
|
||||
|
||||
@@ -77,12 +77,11 @@ uint16_t data_objects_number_of_bytes;
|
||||
static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
||||
10,
|
||||
0x00,
|
||||
0x31, 0x80, /* Full DF name */
|
||||
0x31, 0x84, /* Full DF name, GET DATA, MF */
|
||||
0x73,
|
||||
0x80, 0x01, 0x40, /* Full DF name */
|
||||
0x80, 0x01, 0x80, /* Full DF name */
|
||||
/* 1-byte */
|
||||
/* No command chaining */
|
||||
/* Extended Lc and Le */
|
||||
/* Command chaining, No extended Lc and Le */
|
||||
0x00, 0x90, 0x00 /* Status info (no life cycle management) */
|
||||
};
|
||||
|
||||
@@ -90,27 +89,24 @@ static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
|
||||
static const uint8_t extended_capabilities[] __attribute__ ((aligned (1))) = {
|
||||
10,
|
||||
0x30, /*
|
||||
* No SM, No get challenge,
|
||||
* No SM,
|
||||
* No get challenge,
|
||||
* Key import supported,
|
||||
* PW status byte can be put,
|
||||
* No private_use_DO,
|
||||
* No algo change allowed
|
||||
*/
|
||||
0, /* Secure Messaging Algorithm: N/A (TDES=0, AES=1) */
|
||||
0x00, 0x00, /* Max get challenge */
|
||||
0x00, 0x00, /* Max get challenge (0: Get challenge not supported) */
|
||||
#ifdef CERTDO_SUPPORT
|
||||
0x07, 0xfe, /* max. length of cardholder certificate (2KB - 2)*/
|
||||
0x08, 0x00, /* max. length of cardholder certificate (2KiB) */
|
||||
#else
|
||||
0x00, 0x00,
|
||||
#endif
|
||||
/* Max. length of command data */
|
||||
(MAX_CMD_APDU_SIZE>>8), (MAX_CMD_APDU_SIZE&0xff),
|
||||
/* Max. length of command APDU */
|
||||
0x00, 0xff,
|
||||
/* Max. length of response data */
|
||||
#ifdef CERTDO_SUPPORT
|
||||
0x08, 0x00, /* the case of cardholder ceritificate */
|
||||
#else
|
||||
(MAX_RES_APDU_SIZE>>8), (MAX_RES_APDU_SIZE&0xff),
|
||||
#endif
|
||||
0x00, 0xff,
|
||||
};
|
||||
|
||||
/* Algorithm Attributes */
|
||||
|
||||
@@ -67,7 +67,7 @@ select_file_TOP_result[] __attribute__ ((aligned (1))) = {
|
||||
};
|
||||
|
||||
void
|
||||
set_res_apdu (uint8_t sw1, uint8_t sw2)
|
||||
set_res_sw (uint8_t sw1, uint8_t sw2)
|
||||
{
|
||||
apdu.sw = (sw1 << 8) | sw2;
|
||||
}
|
||||
@@ -510,7 +510,7 @@ cmd_select_file (void)
|
||||
if (apdu.cmd_apdu_data_len != 6
|
||||
|| memcmp (openpgpcard_aid, apdu.cmd_apdu_data, 6) != 0)
|
||||
{
|
||||
DEBUG_WORD (apdu.cmd_apdu_data_len);
|
||||
DEBUG_SHORT (apdu.cmd_apdu_data_len);
|
||||
DEBUG_BINARY (apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
|
||||
|
||||
GPG_NO_FILE ();
|
||||
@@ -528,6 +528,7 @@ cmd_select_file (void)
|
||||
res_APDU[1] = 0x12;
|
||||
res_APDU[2] = 0x84; /* overwrite: DF name */
|
||||
res_APDU_size += 2;
|
||||
GPG_SUCCESS ();
|
||||
}
|
||||
}
|
||||
else if (apdu.cmd_apdu_data_len == 2
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#define GPG_MEMORY_FAILURE() set_res_apdu (0x65, 0x81)
|
||||
#define GPG_SECURITY_FAILURE() set_res_apdu (0x69, 0x82)
|
||||
#define GPG_SECURITY_AUTH_BLOCKED() set_res_apdu (0x69, 0x83)
|
||||
#define GPG_CONDITION_NOT_SATISFIED() set_res_apdu (0x69, 0x85)
|
||||
#define GPG_COMMAND_NOT_ALLOWED() set_res_apdu (0x69, 0x86)
|
||||
#define GPG_FUNCTION_NOT_SUPPORTED() set_res_apdu (0x6a, 0x81)
|
||||
#define GPG_NO_FILE() set_res_apdu (0x6a, 0x82)
|
||||
#define GPG_NO_RECORD() set_res_apdu (0x6a, 0x88)
|
||||
#define GPG_BAD_P0_P1() set_res_apdu (0x6b, 0x00)
|
||||
#define GPG_NO_INS() set_res_apdu (0x6d, 0x00)
|
||||
#define GPG_ERROR() set_res_apdu (0x6f, 0x00)
|
||||
#define GPG_SUCCESS() set_res_apdu (0x90, 0x00)
|
||||
#define GPG_MEMORY_FAILURE() set_res_sw (0x65, 0x81)
|
||||
#define GPG_SECURITY_FAILURE() set_res_sw (0x69, 0x82)
|
||||
#define GPG_SECURITY_AUTH_BLOCKED() set_res_sw (0x69, 0x83)
|
||||
#define GPG_CONDITION_NOT_SATISFIED() set_res_sw (0x69, 0x85)
|
||||
#define GPG_COMMAND_NOT_ALLOWED() set_res_sw (0x69, 0x86)
|
||||
#define GPG_FUNCTION_NOT_SUPPORTED() set_res_sw (0x6a, 0x81)
|
||||
#define GPG_NO_FILE() set_res_sw (0x6a, 0x82)
|
||||
#define GPG_NO_RECORD() set_res_sw (0x6a, 0x88)
|
||||
#define GPG_BAD_P0_P1() set_res_sw (0x6b, 0x00)
|
||||
#define GPG_NO_INS() set_res_sw (0x6d, 0x00)
|
||||
#define GPG_ERROR() set_res_sw (0x6f, 0x00)
|
||||
#define GPG_SUCCESS() set_res_sw (0x90, 0x00)
|
||||
|
||||
@@ -3,5 +3,5 @@ STMUSBSRCDIR = $(STMUSBDIR)/src
|
||||
STMUSBINCDIR = $(STMUSBDIR)/inc
|
||||
STMUSBSRC= \
|
||||
$(STMUSBSRCDIR)/usb_init.c $(STMUSBSRCDIR)/usb_int.c \
|
||||
$(STMUSBSRCDIR)/usb_mem.c $(STMUSBSRCDIR)/usb_core.c \
|
||||
$(STMUSBSRCDIR)/usb_core.c \
|
||||
$(STMUSBSRCDIR)/usb_regs.c
|
||||
|
||||
1476
src/usb-icc.c
1476
src/usb-icc.c
File diff suppressed because it is too large
Load Diff
@@ -102,7 +102,7 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
* ccid-driver.
|
||||
*/
|
||||
0x42, 0x08, 0x04, 0x00, /* dwFeatures (not ICCD):
|
||||
* Short and extended APDU level: 0x40000 *
|
||||
* Short APDU level : 0x20000 *
|
||||
* (what? means ICCD?) : 0x00800 *
|
||||
* Automatic IFSD : 0x00400
|
||||
* NAD value other than 0x00 : 0x00200
|
||||
@@ -115,7 +115,7 @@ static const uint8_t gnukConfigDescriptor[] = {
|
||||
* Auto activaction of ICC : 0x00004
|
||||
* Automatic conf. based on ATR : 0x00002 g
|
||||
*/
|
||||
0x40, 0x01, 0, 0, /* dwMaxCCIDMessageLength */
|
||||
0x0f, 0x01, 0, 0, /* dwMaxCCIDMessageLength: 271 */
|
||||
0xff, /* bClassGetResponse: */
|
||||
0xff, /* bClassEnvelope: */
|
||||
0, 0, /* wLCDLayout: FIXED VALUE */
|
||||
|
||||
@@ -27,3 +27,76 @@ void usb_lld_init (void) {
|
||||
RCC->APB1RSTR = RCC_APB1RSTR_USBRST;
|
||||
RCC->APB1RSTR = 0;
|
||||
}
|
||||
|
||||
void usb_lld_to_pmabuf (const void *src, uint16_t wPMABufAddr, size_t n)
|
||||
{
|
||||
const uint8_t *s = (const uint8_t *)src;
|
||||
uint16_t *p;
|
||||
uint16_t w;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
if ((wPMABufAddr & 1))
|
||||
{
|
||||
p = (uint16_t *)(PMAAddr + (wPMABufAddr - 1) * 2);
|
||||
w = *p;
|
||||
w = (w & 0xff) | (*s++) << 8;
|
||||
*p = w;
|
||||
p += 2;
|
||||
n--;
|
||||
}
|
||||
else
|
||||
p = (uint16_t *)(PMAAddr + wPMABufAddr * 2);
|
||||
|
||||
while (n >= 2)
|
||||
{
|
||||
w = *s++;
|
||||
w |= (*s++) << 8;
|
||||
*p = w;
|
||||
p += 2;
|
||||
n -= 2;
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
w = *s;
|
||||
*p = w;
|
||||
}
|
||||
}
|
||||
|
||||
void usb_lld_from_pmabuf (void *dst, uint16_t wPMABufAddr, size_t n)
|
||||
{
|
||||
uint8_t *d = (uint8_t *)dst;
|
||||
uint16_t *p;
|
||||
uint16_t w;
|
||||
|
||||
if (n == 0)
|
||||
return;
|
||||
|
||||
if ((wPMABufAddr & 1))
|
||||
{
|
||||
p = (uint16_t *)(PMAAddr + (wPMABufAddr - 1) * 2);
|
||||
w = *p;
|
||||
*d++ = (w >> 8);
|
||||
p += 2;
|
||||
n--;
|
||||
}
|
||||
else
|
||||
p = (uint16_t *)(PMAAddr + wPMABufAddr * 2);
|
||||
|
||||
while (n >= 2)
|
||||
{
|
||||
w = *p;
|
||||
*d++ = (w & 0xff);
|
||||
*d++ = (w >> 8);
|
||||
p += 2;
|
||||
n -= 2;
|
||||
}
|
||||
|
||||
if (n > 0)
|
||||
{
|
||||
w = *p;
|
||||
*d = (w & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#define STM32_USB_IRQ_PRIORITY 11
|
||||
void usb_lld_init (void);
|
||||
|
||||
extern void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n);
|
||||
extern void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n);
|
||||
|
||||
extern inline void usb_lld_stall_tx (int ep_num)
|
||||
{
|
||||
SetEPTxStatus (ep_num, EP_TX_STALL);
|
||||
@@ -16,10 +19,10 @@ extern inline int usb_lld_tx_data_len (int ep_num)
|
||||
return GetEPTxCount (ep_num);
|
||||
}
|
||||
|
||||
extern inline void usb_lld_txcpy (const uint8_t *src,
|
||||
extern inline void usb_lld_txcpy (const void *src,
|
||||
int ep_num, int offset, size_t len)
|
||||
{
|
||||
UserToPMABufferCopy ((uint8_t *)src, GetEPTxAddr (ep_num) + offset, len);
|
||||
usb_lld_to_pmabuf (src, GetEPTxAddr (ep_num) + offset, len);
|
||||
}
|
||||
|
||||
extern inline void usb_lld_tx_enable (int ep_num, size_t len)
|
||||
@@ -28,9 +31,9 @@ extern inline void usb_lld_tx_enable (int ep_num, size_t len)
|
||||
SetEPTxValid (ep_num);
|
||||
}
|
||||
|
||||
extern inline void usb_lld_write (uint8_t ep_num, void *buf, size_t len)
|
||||
extern inline void usb_lld_write (uint8_t ep_num, const void *buf, size_t len)
|
||||
{
|
||||
UserToPMABufferCopy (buf, GetEPTxAddr (ep_num), len);
|
||||
usb_lld_to_pmabuf (buf, GetEPTxAddr (ep_num), len);
|
||||
SetEPTxCount (ep_num, len);
|
||||
SetEPTxValid (ep_num);
|
||||
}
|
||||
@@ -48,5 +51,5 @@ extern inline int usb_lld_rx_data_len (int ep_num)
|
||||
extern inline void usb_lld_rxcpy (uint8_t *dst,
|
||||
int ep_num, int offset, size_t len)
|
||||
{
|
||||
PMAToUserBufferCopy (dst, GetEPRxAddr (ep_num) + offset, len);
|
||||
usb_lld_from_pmabuf (dst, GetEPRxAddr (ep_num) + offset, len);
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ class GnukToken(object):
|
||||
self.connection = cardservice.connection
|
||||
|
||||
def cmd_verify(self, who, passwd):
|
||||
apdu = [0x00, 0x20, 0x00, 0x80+who, 0, 0, len(passwd)] + s2l(passwd)
|
||||
apdu = [0x00, 0x20, 0x00, 0x80+who, len(passwd)] + s2l(passwd)
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
@@ -59,10 +59,20 @@ class GnukToken(object):
|
||||
while count*256 < data_len:
|
||||
if count == 0:
|
||||
d = data[:256]
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, 0, len(d)>>8, len(d)&0xff] + s2l(d)
|
||||
if len(d) <= 255:
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, len(d) ] + s2l(d)
|
||||
else:
|
||||
apdu0 = [0x10, ins, 0x80+fileid, 0x00, 255 ] + s2l(d[:255])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu0)
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, 1 ] + s2l(d[255:])
|
||||
else:
|
||||
d = data[256*count:256*(count+1)]
|
||||
apdu = [0x00, ins, count, 0x00, 0, len(d)>>8, len(d)&0xff] + s2l(d)
|
||||
if len(d) <= 255:
|
||||
apdu = [0x00, ins, count, 0x00, len(d) ] + s2l(d)
|
||||
else:
|
||||
apdu0 = [0x10, ins, count, 0x00, 255 ] + s2l(d[:255])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu0)
|
||||
apdu = [0x00, ins, 0x80+fileid, 0x00, 1 ] + s2l(d[255:])
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
if is_update:
|
||||
@@ -72,13 +82,13 @@ class GnukToken(object):
|
||||
count += 1
|
||||
|
||||
def cmd_select_openpgp(self):
|
||||
apdu = [0x00, 0xa4, 0x04, 0x00, 6, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01 ]
|
||||
apdu = [0x00, 0xa4, 0x04, 0x0c, 6, 0xd2, 0x76, 0x00, 0x01, 0x24, 0x01 ]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
|
||||
def cmd_get_data(self, tagh, tagl):
|
||||
apdu = [0x00, 0xca, tagh, tagl]
|
||||
apdu = [0x00, 0xca, tagh, tagl ]
|
||||
response, sw1, sw2 = self.connection.transmit(apdu)
|
||||
if not (sw1 == 0x90 and sw2 == 0x00):
|
||||
raise ValueError, ("%02x%02x" % (sw1, sw2))
|
||||
@@ -146,18 +156,6 @@ if __name__ == '__main__':
|
||||
exit(1)
|
||||
print "Writing serial number"
|
||||
data = binascii.unhexlify(serial_data_hex)
|
||||
elif sys.argv[1] == '-r':
|
||||
fileid = 1 # Random number bits
|
||||
if len(sys.argv) == 3:
|
||||
filename = sys.argv[2]
|
||||
f = open(filename)
|
||||
else:
|
||||
filename = stdin
|
||||
f = sys.stdin
|
||||
data = f.read()
|
||||
f.close()
|
||||
print "%s: %d" % (filename, len(data))
|
||||
print "Updating random bits"
|
||||
else:
|
||||
fileid = 0 # Card holder certificate
|
||||
filename = sys.argv[1]
|
||||
|
||||
Reference in New Issue
Block a user