Adding support for extended APDU.
Added SC-HSM ATR Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
46
hsm2040.c
46
hsm2040.c
@@ -385,6 +385,7 @@ void usb_tx_enable(const void *buf, uint32_t len)
|
|||||||
*/
|
*/
|
||||||
static const uint8_t ATR_head[] = {
|
static const uint8_t ATR_head[] = {
|
||||||
0x3b, 0xda, 0x11, 0xff, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0x03,
|
0x3b, 0xda, 0x11, 0xff, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0x03,
|
||||||
|
//0x3B,0xFE,0x18,0x00,0x00,0x81,0x31,0xFE,0x45,0x80,0x31,0x81,0x54,0x48,0x53,0x4D,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0xFA
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Send back ATR (Answer To Reset) */
|
/* Send back ATR (Answer To Reset) */
|
||||||
@@ -393,7 +394,14 @@ static enum ccid_state ccid_power_on (struct ccid *c)
|
|||||||
TU_LOG1("!!! CCID POWER ON %d\r\n",c->application);
|
TU_LOG1("!!! CCID POWER ON %d\r\n",c->application);
|
||||||
uint8_t p[CCID_MSG_HEADER_SIZE+1]; /* >= size of historical_bytes -1 */
|
uint8_t p[CCID_MSG_HEADER_SIZE+1]; /* >= size of historical_bytes -1 */
|
||||||
int hist_len = historical_bytes[0];
|
int hist_len = historical_bytes[0];
|
||||||
size_t size_atr = sizeof (ATR_head) + hist_len + 1;
|
|
||||||
|
char atr_sc_hsm[] = { 0x3B,0x8E,0x80,0x01,0x80,0x31,0x81,0x54,0x48,0x53,0x4D,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0x18 };
|
||||||
|
uint8_t mode = 1; //1 sc-hsm, 0 openpgp
|
||||||
|
size_t size_atr;
|
||||||
|
if (mode == 1)
|
||||||
|
size_atr = sizeof(atr_sc_hsm);
|
||||||
|
else
|
||||||
|
size_atr = sizeof (ATR_head) + hist_len + 1;
|
||||||
uint8_t xor_check = 0;
|
uint8_t xor_check = 0;
|
||||||
int i;
|
int i;
|
||||||
if (c->application == 0)
|
if (c->application == 0)
|
||||||
@@ -416,6 +424,12 @@ static enum ccid_state ccid_power_on (struct ccid *c)
|
|||||||
p[CCID_MSG_CHAIN_OFFSET] = 0x00;
|
p[CCID_MSG_CHAIN_OFFSET] = 0x00;
|
||||||
|
|
||||||
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
|
memcpy (endp1_tx_buf, p, CCID_MSG_HEADER_SIZE);
|
||||||
|
if (mode == 1)
|
||||||
|
{
|
||||||
|
memcpy(endp1_tx_buf+CCID_MSG_HEADER_SIZE, atr_sc_hsm, sizeof(atr_sc_hsm));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE, ATR_head, sizeof (ATR_head));
|
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE, ATR_head, sizeof (ATR_head));
|
||||||
|
|
||||||
for (i = 1; i < (int)sizeof (ATR_head); i++)
|
for (i = 1; i < (int)sizeof (ATR_head); i++)
|
||||||
@@ -429,7 +443,7 @@ static enum ccid_state ccid_power_on (struct ccid *c)
|
|||||||
xor_check ^= p[i];
|
xor_check ^= p[i];
|
||||||
p[i] = xor_check;
|
p[i] = xor_check;
|
||||||
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+sizeof (ATR_head), p, hist_len+1);
|
memcpy (endp1_tx_buf+CCID_MSG_HEADER_SIZE+sizeof (ATR_head), p, hist_len+1);
|
||||||
|
}
|
||||||
|
|
||||||
/* This is a single packet Bulk-IN transaction */
|
/* This is a single packet Bulk-IN transaction */
|
||||||
c->epi->buf = NULL;
|
c->epi->buf = NULL;
|
||||||
@@ -1112,6 +1126,32 @@ static int end_cmd_apdu_data (struct ep_out *epo, size_t orig_len)
|
|||||||
|
|
||||||
if (CMD_APDU_HEAD_SIZE + len != c->ccid_header.data_len)
|
if (CMD_APDU_HEAD_SIZE + len != c->ccid_header.data_len)
|
||||||
goto error;
|
goto error;
|
||||||
|
//len is the length after lc (whole APDU = len+5)
|
||||||
|
if (c->a->cmd_apdu_head[4] == 0 && len >= 2) { //extended
|
||||||
|
len -= 2;
|
||||||
|
if (len == 0) {
|
||||||
|
c->a->expected_res_size = (c->a->cmd_apdu_head[5] << 8) | c->a->cmd_apdu_head[6];
|
||||||
|
if (c->a->expected_res_size == 0)
|
||||||
|
c->a->expected_res_size = 0xffff+1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c->a->cmd_apdu_data_len = (c->a->cmd_apdu_data[0] << 8) | c->a->cmd_apdu_data[1];
|
||||||
|
len -= 2;
|
||||||
|
if (len < c->a->cmd_apdu_data_len)
|
||||||
|
goto error;
|
||||||
|
c->a->cmd_apdu_data += 3;
|
||||||
|
if (len == c->a->cmd_apdu_data_len) //no LE
|
||||||
|
c->a->expected_res_size = 0;
|
||||||
|
else {
|
||||||
|
if (len - c->a->cmd_apdu_data_len < 2)
|
||||||
|
goto error;
|
||||||
|
c->a->expected_res_size = (c->a->cmd_apdu_data[c->a->cmd_apdu_data_len] << 8) | c->a->cmd_apdu_data[c->a->cmd_apdu_data_len+1];
|
||||||
|
if (c->a->expected_res_size == 0)
|
||||||
|
c->a->expected_res_size = 0xffff+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
if (len == c->a->cmd_apdu_head[4])
|
if (len == c->a->cmd_apdu_head[4])
|
||||||
/* No Le field*/
|
/* No Le field*/
|
||||||
@@ -1127,11 +1167,13 @@ static int end_cmd_apdu_data (struct ep_out *epo, size_t orig_len)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
error:
|
error:
|
||||||
|
DEBUG_INFO("APDU header size error");
|
||||||
epo->err = 1;
|
epo->err = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->a->cmd_apdu_data_len += len;
|
c->a->cmd_apdu_data_len += len;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user