no ext lc and le but short APDU only

This commit is contained in:
NIIBE Yutaka
2012-01-20 18:18:23 +09:00
parent f92ee76db5
commit 21debc0567
13 changed files with 1064 additions and 626 deletions

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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

View File

@@ -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)

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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 */

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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,7 +82,7 @@ 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))
@@ -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]