Fix with empty extended length header.
Fix buffer overflow when extended length. APDU shall be reset at every APDU beginning. Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
29
hsm2040.c
29
hsm2040.c
@@ -32,9 +32,9 @@ extern void low_flash_init();
|
|||||||
static uint8_t itf_num;
|
static uint8_t itf_num;
|
||||||
|
|
||||||
#if MAX_RES_APDU_DATA_SIZE > MAX_CMD_APDU_DATA_SIZE
|
#if MAX_RES_APDU_DATA_SIZE > MAX_CMD_APDU_DATA_SIZE
|
||||||
#define USB_BUF_SIZE (MAX_RES_APDU_DATA_SIZE+5)
|
#define USB_BUF_SIZE (MAX_RES_APDU_DATA_SIZE+20+9)
|
||||||
#else
|
#else
|
||||||
#define USB_BUF_SIZE (MAX_CMD_APDU_DATA_SIZE+5)
|
#define USB_BUF_SIZE (MAX_CMD_APDU_DATA_SIZE+20+9)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct apdu apdu;
|
struct apdu apdu;
|
||||||
@@ -193,16 +193,18 @@ static uint8_t endp1_tx_buf[64];
|
|||||||
#define APDU_STATE_RESULT_GET_RESPONSE 4
|
#define APDU_STATE_RESULT_GET_RESPONSE 4
|
||||||
|
|
||||||
static void ccid_prepare_receive (struct ccid *c);
|
static void ccid_prepare_receive (struct ccid *c);
|
||||||
|
static void apdu_init (struct apdu *a);
|
||||||
|
|
||||||
static void ccid_reset (struct ccid *c)
|
static void ccid_reset (struct ccid *c)
|
||||||
{
|
{
|
||||||
c->err = 0;
|
apdu_init(c->a);
|
||||||
c->tx_busy = 0;
|
c->err = 0;
|
||||||
c->state = APDU_STATE_WAIT_COMMAND;
|
c->tx_busy = 0;
|
||||||
c->p = c->a->cmd_apdu_data;
|
c->state = APDU_STATE_WAIT_COMMAND;
|
||||||
c->len = MAX_CMD_APDU_DATA_SIZE;
|
c->p = c->a->cmd_apdu_data;
|
||||||
c->a->cmd_apdu_data_len = 0;
|
c->len = MAX_CMD_APDU_DATA_SIZE;
|
||||||
c->a->expected_res_size = 0;
|
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)
|
static void ccid_init(struct ccid *c, struct ep_in *epi, struct ep_out *epo, struct apdu *a)
|
||||||
@@ -1119,6 +1121,11 @@ static int end_cmd_apdu_head (struct ep_out *epo, size_t orig_len)
|
|||||||
c->a->expected_res_size = 256;
|
c->a->expected_res_size = 256;
|
||||||
c->a->cmd_apdu_head[4] = 0;
|
c->a->cmd_apdu_head[4] = 0;
|
||||||
}
|
}
|
||||||
|
else if (epo->cnt == 9) { //extended
|
||||||
|
c->a->expected_res_size = (c->a->cmd_apdu_head[7] << 8) | c->a->cmd_apdu_head[8];
|
||||||
|
if (c->a->expected_res_size == 0)
|
||||||
|
c->a->expected_res_size = 65536;
|
||||||
|
}
|
||||||
|
|
||||||
c->a->cmd_apdu_data_len = 0;
|
c->a->cmd_apdu_data_len = 0;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1300,7 +1307,6 @@ static void ccid_rx_ready (uint16_t len)
|
|||||||
int offset = 0;
|
int offset = 0;
|
||||||
int cont;
|
int cont;
|
||||||
size_t orig_len = len;
|
size_t orig_len = len;
|
||||||
|
|
||||||
while (epo->err == 0)
|
while (epo->err == 0)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
@@ -1322,7 +1328,6 @@ static void ccid_rx_ready (uint16_t len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ORIG_LEN to distingush ZLP and the end of transaction
|
* ORIG_LEN to distingush ZLP and the end of transaction
|
||||||
* (ORIG_LEN != USB_LL_BUF_SIZE)
|
* (ORIG_LEN != USB_LL_BUF_SIZE)
|
||||||
@@ -1470,6 +1475,7 @@ void card_thread()
|
|||||||
int len, pw_len, newpw_len;
|
int len, pw_len, newpw_len;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
uint32_t m;
|
uint32_t m;
|
||||||
queue_remove_blocking(card_comm, &m);
|
queue_remove_blocking(card_comm, &m);
|
||||||
|
|
||||||
@@ -1557,6 +1563,7 @@ void card_thread()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
process_apdu();
|
process_apdu();
|
||||||
|
|
||||||
done:;
|
done:;
|
||||||
uint32_t flag = EV_EXEC_FINISHED;
|
uint32_t flag = EV_EXEC_FINISHED;
|
||||||
queue_add_blocking(ccid_comm, &flag);
|
queue_add_blocking(ccid_comm, &flag);
|
||||||
|
|||||||
Reference in New Issue
Block a user