add alignment for gnuk.ld.in, add ChangeLog entries.

This commit is contained in:
NIIBE Yutaka
2012-01-20 23:57:23 +09:00
parent 21debc0567
commit aff9080b35
6 changed files with 146 additions and 59 deletions

View File

@@ -1,3 +1,67 @@
2012-01-20 Niibe Yutaka <gniibe@fsij.org>
Short APDU only CCID driver.
* STM32_USB-FS-Device_Driver/src/usb_core.c (DataStageOut)
(DataStageIn): Use usb_lld_to_pmabuf and usb_lld_from_pmabuf.
* src/configure (CERTDO_SUPPORT): Comment fix.
* src/gnuk.h (struct adpu): expected_res_size has type uint16_t.
(MAX_CMD_APDU_DATA_SIZE, MAX_RES_APDU_DATA_SIZE): New.
(MAX_CMD_APDU_SIZE, MAX_RES_APDU_SIZE, USB_BUF_SIZE): Remove.
(icc_state_p): New.
(set_res_sw): Rename from set_res_apdu.
* src/call-rsa.c (rsa_decrypt): Use MAX_RES_APDU_DATA_SIZE.
* src/openpgp.c (set_res_sw): Rename from set_res_apdu.
* src/openpgp.h: Use set_res_sw.
* src/main.c: Handle icc_state_p.
* src/openpgp-do.c (historical_bytes): command chaining but short
APDU only.
(extended_capabilities): Change for short APDU only.
* src/usb-icc.c (USB_BUF_SIZE): Define here (was in gnuk.h).
(struct ep_in, epi_init, struct ep_out, epo_init, endpoint_out)
(endpoint_in, icc_state_p, struct ccid, APDU_STATE_WAIT_COMMAND)
(APDU_STATE_COMMAND_CHAINING, APDU_STATE_COMMAND_RECEIVED)
(APDU_STATE_RESULT, APDU_STATE_RESULT_GET_RESPONSE, ccid_reset)
(ccid_init, CMD_APDU_HEAD_SIZE, apdu_init, notify_tx, no_buf)
(set_sw1sw2, get_sw1sw2, notify_icc, end_icc_rx, end_abdata)
(end_cmd_apdu_head, end_nomore_data, end_cmd_apdu_data)
(nomore_data, INS_GET_RESPONSE, icc_cmd_apdu_data, icc_abdata)
(icc_send_data_block_0x9000, icc_send_data_block_gr, ccid): New.
(icc_data_size, icc_seq, icc_next_p, icc_chain_p, icc_tx_size)
(icc_thread, icc_state, gpg_thread, ICC_RESPONSE_MSG_DATA_SIZE):
Remove.
(EP1_IN_Callback): Rewrite using epi.
(EP2_OUT_Callback): Rewrite using epo.
(icc_prepare_receive): Rewrite using epo and struct ccid.
(ATR): Change ofr short APDU only.
(icc_error, icc_power_on, icc_send_status, icc_power_off)
(icc_send_data_block, icc_send_params, icc_handle_data)
(icc_handle_timeout, USBthread): Rewrite using struct ccid.
* src/usb_desc.c (gnukConfigDescriptor): dwFeatures: Short APDU
level, dwMaxCCIDMessageLength: 271.
* src/usb_lld.c (usb_lld_to_pmabuf, usb_lld_from_pmabuf): New.
* src/usb_lld.h (usb_lld_txcpy, void usb_lld_write) Use
usb_lld_to_pmabuf.
(usb_lld_rxcpy): Use usb_lld_from_pmabuf.
* src/stmusb.mk (usb_mem.c): Remove.
* gnuk_put_binary.py (cmd_select_openpgp): No response APDU data.
(cmd_verify, cmd_write_binary): Send short APDU.
(__main__): Remove RANDOM_NUMBER_BITS support.
Bug fix for CERTDO_SUPPORT.
* src/gnuk.ld.in: Add missing alignment for _data_pool (when no
CERTDO_SUPPORT).
2012-01-19 Niibe Yutaka <gniibe@fsij.org>
* src/usb-icc.c (icc_handle_data): Handle the case when it only

2
src/configure vendored
View File

@@ -173,7 +173,7 @@ fi
# --enable-certdo option
if test "$certdo" = "yes"; then
CERTDO_DEFINE="#define CERTDO_SUPPORT 1"
echo "CERT.3 Data Object is supported (Note: it is not supported by GnuPG)"
echo "CERT.3 Data Object is supported"
else
CERTDO_DEFINE="#undef CERTDO_SUPPORT"
echo "CERT.3 Data Object is not supported"

View File

@@ -128,6 +128,7 @@ SECTIONS
.gnuk_flash :
{
. = ALIGN (@FLASH_PAGE_SIZE@);
_data_pool = .;
KEEP(*(.gnuk_data))
. = ALIGN(@FLASH_PAGE_SIZE@);

View File

@@ -103,10 +103,10 @@ static const uint8_t extended_capabilities[] __attribute__ ((aligned (1))) = {
#else
0x00, 0x00,
#endif
/* Max. length of command APDU */
0x00, 0xff,
/* Max. length of response data */
/* Max. length of command APDU data */
0x00, 0xff,
/* Max. length of response APDU data */
0x01, 0x00,
};
/* Algorithm Attributes */

View File

@@ -234,6 +234,16 @@ struct ccid {
#define APDU_STATE_RESULT 3
#define APDU_STATE_RESULT_GET_RESPONSE 4
static void ccid_reset (struct ccid *c)
{
c->err = 0;
c->state = APDU_STATE_WAIT_COMMAND;
c->p = c->a->cmd_apdu_data;
c->len = MAX_CMD_APDU_DATA_SIZE;
c->a->cmd_apdu_data_len = 0;
c->a->expected_res_size = 0;
}
static void ccid_init (struct ccid *c, struct ep_in *epi, struct ep_out *epo,
struct apdu *a, Thread *t)
{
@@ -412,10 +422,18 @@ static int end_icc_rx (struct ep_out *epo, size_t orig_len)
return 0;
}
static int end_notify (struct ep_out *epo, size_t orig_len)
static int end_abdata (struct ep_out *epo, size_t orig_len)
{
(void)epo;
(void)orig_len;
struct ccid *c = (struct ccid *)epo->priv;
size_t len = epo->cnt;
if (orig_len == USB_LL_BUF_SIZE && len < c->icc_header.data_len)
/* more packet comes */
return 1;
if (len != c->icc_header.data_len)
epo->err = 1;
return 0;
}
@@ -537,6 +555,7 @@ static void icc_abdata (struct ep_out *epo, size_t len)
struct ccid *c = (struct ccid *)epo->priv;
(void)len;
c->a->seq = c->icc_header.seq;
if (c->icc_header.msg_type == ICC_XFR_BLOCK)
{
c->a->seq = c->icc_header.seq;
@@ -548,7 +567,7 @@ static void icc_abdata (struct ep_out *epo, size_t len)
}
else
{
epo->end_rx = end_notify;
epo->end_rx = end_abdata;
epo->buf = c->p;
epo->buf_len = c->len;
epo->cnt = 0;
@@ -990,12 +1009,7 @@ icc_handle_data (struct ccid *c)
if (c->err != 0)
{
c->err = 0;
c->state = APDU_STATE_WAIT_COMMAND;
c->p = c->a->cmd_apdu_data;
c->len = MAX_CMD_APDU_DATA_SIZE;
c->a->cmd_apdu_data_len = 0;
c->a->expected_res_size = 0;
ccid_reset (c);
icc_error (c, ICC_OFFSET_DATA_LEN);
return next_state;
}
@@ -1004,9 +1018,15 @@ icc_handle_data (struct ccid *c)
{
case ICC_STATE_START:
if (c->icc_header.msg_type == ICC_POWER_ON)
next_state = icc_power_on (c);
{
ccid_reset (c);
next_state = icc_power_on (c);
}
else if (c->icc_header.msg_type == ICC_POWER_OFF)
next_state = icc_power_off (c);
{
ccid_reset (c);
next_state = icc_power_off (c);
}
else if (c->icc_header.msg_type == ICC_SLOT_STATUS)
icc_send_status (c);
else
@@ -1017,35 +1037,28 @@ icc_handle_data (struct ccid *c)
break;
case ICC_STATE_WAIT:
if (c->icc_header.msg_type == ICC_POWER_ON)
/* Not in the spec., but pcscd/libccid */
next_state = icc_power_on (c);
{
/* Not in the spec., but pcscd/libccid */
ccid_reset (c);
next_state = icc_power_on (c);
}
else if (c->icc_header.msg_type == ICC_POWER_OFF)
next_state = icc_power_off (c);
{
ccid_reset (c);
next_state = icc_power_off (c);
}
else if (c->icc_header.msg_type == ICC_SLOT_STATUS)
icc_send_status (c);
else if (c->icc_header.msg_type == ICC_XFR_BLOCK)
{
if (c->icc_header.param == 0)
{
DEBUG_INFO ("DUMP C\r\n");
DEBUG_SHORT (c->icc_state);
DEBUG_BYTE (c->state);
DEBUG_WORD (c->p);
DEBUG_WORD (c->len);
DEBUG_BYTE (c->err);
DEBUG_WORD (c->epo->buf);
DEBUG_WORD (c->epo->cnt);
DEBUG_WORD (c->epo->buf_len);
DEBUG_WORD (c->a->cmd_apdu_data);
DEBUG_BINARY (c->a->cmd_apdu_data, c->a->cmd_apdu_data_len);
if ((c->a->cmd_apdu_head[0] & 0x10) == 0)
{
if (c->state == APDU_STATE_COMMAND_CHAINING)
{ /* command chaining finished */
c->p += c->a->cmd_apdu_head[4];
c->a->cmd_apdu_head[4] = 0;
c->a->cmd_apdu_data_len = c->p - c->a->cmd_apdu_data;
DEBUG_INFO ("CMD chaning finished.\r\n");
}
@@ -1061,6 +1074,7 @@ icc_handle_data (struct ccid *c)
if (c->len == 0)
c->state = APDU_STATE_RESULT;
c->icc_state = ICC_STATE_WAIT;
DEBUG_INFO ("GET Response.\r\n");
}
else
{ /* Give this message to GPG thread */
@@ -1094,53 +1108,61 @@ icc_handle_data (struct ccid *c)
icc_send_params (c);
else if (c->icc_header.msg_type == ICC_SECURE)
{
if (icc_buffer[10] == 0x00) /* PIN verification */
if (c->p != c->a->cmd_apdu_data)
{
icc_buffer[0] = icc_buffer[25-10];
icc_buffer[1] = icc_buffer[26-10];
icc_buffer[2] = icc_buffer[27-10];
icc_buffer[3] = icc_buffer[28-10];
/* SECURE received in the middle of command chaining */
ccid_reset (c);
icc_error (c, ICC_OFFSET_DATA_LEN);
return next_state;
}
if (c->p[10-10] == 0x00) /* PIN verification */
{
c->a->cmd_apdu_head[0] = c->p[25-10];
c->a->cmd_apdu_head[1] = c->p[26-10];
c->a->cmd_apdu_head[2] = c->p[27-10];
c->a->cmd_apdu_head[3] = c->p[28-10];
/**/
icc_buffer[5] = 0; /* bConfirmPIN */
icc_buffer[6] = icc_buffer[17-10]; /* bEntryValidationCondition */
icc_buffer[7] = icc_buffer[18-10]; /* bNumberMessage */
icc_buffer[8] = icc_buffer[19-10]; /* wLangId L */
icc_buffer[9] = icc_buffer[20-10]; /* wLangId H */
icc_buffer[10] = icc_buffer[21-10]; /* bMsgIndex */
c->a->cmd_apdu_data[0] = 0; /* bConfirmPIN */
c->a->cmd_apdu_data[1] = c->p[17-10]; /* bEntryValidationCondition */
c->a->cmd_apdu_data[2] = c->p[18-10]; /* bNumberMessage */
c->a->cmd_apdu_data[3] = c->p[19-10]; /* wLangId L */
c->a->cmd_apdu_data[4] = c->p[20-10]; /* wLangId H */
c->a->cmd_apdu_data[5] = c->p[21-10]; /* bMsgIndex */
c->a->cmd_apdu_data_len = 6;
c->a->expected_res_size = 0;
c->a->sw = 0x9000;
c->a->res_apdu_data_len = 0;
c->a->res_apdu_data = &icc_buffer[5];
c->a->res_apdu_data = &c->p[5];
chEvtSignal (c->application, EV_VERIFY_CMD_AVAILABLE);
next_state = ICC_STATE_EXECUTE;
}
else if (icc_buffer[10] == 0x01) /* PIN Modification */
else if (c->p[10-10] == 0x01) /* PIN Modification */
{
uint8_t num_msgs = icc_buffer[21-10];
uint8_t num_msgs = c->p[21-10];
if (num_msgs == 0x00)
num_msgs = 1;
else if (num_msgs == 0xff)
num_msgs = 3;
icc_buffer[0] = icc_buffer[27 + num_msgs-10];
icc_buffer[1] = icc_buffer[28 + num_msgs-10];
icc_buffer[2] = icc_buffer[29 + num_msgs-10];
icc_buffer[3] = icc_buffer[30 + num_msgs-10];
c->a->cmd_apdu_head[0] = c->p[27 + num_msgs-10];
c->a->cmd_apdu_head[1] = c->p[28 + num_msgs-10];
c->a->cmd_apdu_head[2] = c->p[29 + num_msgs-10];
c->a->cmd_apdu_head[3] = c->p[30 + num_msgs-10];
/**/
icc_buffer[5] = icc_buffer[19-10]; /* bConfirmPIN */
icc_buffer[6] = icc_buffer[20-10]; /* bEntryValidationCondition */
icc_buffer[7] = icc_buffer[21-10]; /* bNumberMessage */
icc_buffer[8] = icc_buffer[22-10]; /* wLangId L */
icc_buffer[9] = icc_buffer[23-10]; /* wLangId H */
icc_buffer[10] = icc_buffer[24-10]; /* bMsgIndex, bMsgIndex1 */
c->a->cmd_apdu_data[0] = c->p[19-10]; /* bConfirmPIN */
c->a->cmd_apdu_data[1] = c->p[20-10]; /* bEntryValidationCondition */
c->a->cmd_apdu_data[2] = c->p[21-10]; /* bNumberMessage */
c->a->cmd_apdu_data[3] = c->p[22-10]; /* wLangId L */
c->a->cmd_apdu_data[4] = c->p[23-10]; /* wLangId H */
c->a->cmd_apdu_data[5] = c->p[24-10]; /* bMsgIndex, bMsgIndex1 */
if (num_msgs >= 2)
icc_buffer[11] = icc_buffer[25-10]; /* bMsgIndex2 */
c->a->cmd_apdu_data[6] = c->p[25-10]; /* bMsgIndex2 */
if (num_msgs == 3)
icc_buffer[12] = icc_buffer[26-10]; /* bMsgIndex3 */
c->a->cmd_apdu_data[7] = c->p[26-10]; /* bMsgIndex3 */
c->a->cmd_apdu_data_len = 5 + num_msgs;
c->a->expected_res_size = 0;

View File

@@ -88,7 +88,7 @@ class GnukToken(object):
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))