Experimental Ack-button feature added (not yet finished).

This commit is contained in:
NIIBE Yutaka
2018-09-27 07:30:17 +09:00
parent c3a0eb1439
commit c6e32a36fb
7 changed files with 121 additions and 25 deletions

View File

@@ -51,6 +51,7 @@ endif
ifeq ($(CHIP),stm32f103)
CSRC += mcu-stm32f103.c
CSRC += ack-button.c
endif
###################################

35
src/ack-button.c Normal file
View File

@@ -0,0 +1,35 @@
#include <stdint.h>
#include <string.h>
#include <chopstx.h>
#include "board.h"
#include "mcu/stm32f103.h"
void
ackbtn_init (chopstx_intr_t *intr)
{
chopstx_claim_irq (intr, INTR_REQ_EXTI);
/* Configure EXTI line */
#ifdef AFIO_EXTICR_INDEX
AFIO->EXTICR[AFIO_EXTICR_INDEX] = AFIO_EXTICR1_EXTIx_Py;
#endif
EXTI->IMR &= ~EXTI_IMR;
EXTI->RTSR |= EXTI_RTSR_TR;
}
void
ackbtn_enable (void)
{
EXTI->PR |= EXTI_PR;
EXTI->IMR |= EXTI_IMR;
}
void
ackbtn_disable (void)
{
EXTI->IMR &= ~EXTI_IMR;
EXTI->PR |= EXTI_PR;
}

View File

@@ -26,8 +26,9 @@ void ccid_card_change_signal (int how);
/* CCID thread */
#define EV_RX_DATA_READY 1 /* USB Rx data available */
#define EV_EXEC_FINISHED 2 /* OpenPGP Execution finished */
#define EV_TX_FINISHED 4 /* CCID Tx finished */
#define EV_CARD_CHANGE 8
#define EV_EXEC_FINISHED_ACK 4 /* OpenPGP Execution finished, requires ACK */
#define EV_TX_FINISHED 8 /* CCID Tx finished */
#define EV_CARD_CHANGE 16
/* OpenPGPcard thread */
#define EV_PINPAD_INPUT_DONE 1
@@ -53,12 +54,12 @@ enum ccid_state {
CCID_STATE_NOCARD, /* No card available */
CCID_STATE_START, /* Initial */
CCID_STATE_WAIT, /* Waiting APDU */
/* Busy1, Busy2, Busy3, Busy5 */
CCID_STATE_EXECUTE, /* Busy4 */
CCID_STATE_EXECUTE, /* Executing command */
CCID_STATE_CONFIRM_ACK, /* Execution finished, waiting user's ACK */
CCID_STATE_RECEIVE, /* APDU Received Partially */
CCID_STATE_SEND, /* APDU Sent Partially */
CCID_STATE_EXITED, /* ICC Thread Terminated */
CCID_STATE_EXITED, /* CCID Thread Terminated */
CCID_STATE_EXEC_REQUESTED, /* Exec requested */
};
@@ -378,7 +379,17 @@ extern uint8_t admin_authorized;
#define NR_KEY_ALGO_ATTR_DEC 0xf2
#define NR_KEY_ALGO_ATTR_AUT 0xf3
/*
* NR_UINT_SOMETHING could be here... Use 0xf[456789abcd]
* Representation of User Interaction Flag:
* 0 (UIF disabled): No record in flash memory
* 1 (UIF enabled): 0xf?ff
* 2 (UIF permanently enabled): 0xf?00
*
*/
#define NR_DO_UIF_SIG 0xf6
#define NR_DO_UIF_DEC 0xf7
#define NR_DO_UIF_AUT 0xf8
/*
* NR_UINT_SOMETHING could be here... Use 0xf[459abcd]
*/
/* 123-counters: Recorded in flash memory by 2-halfword (4-byte). */
/*
@@ -461,6 +472,12 @@ int pinpad_getline (int msg_code, uint32_t timeout_usec);
#endif
struct chx_intr;
void ackbtn_init (struct chx_intr *intr);
void ackbtn_enable (void);
void ackbtn_disable (void);
extern uint8_t _regnual_start, __heap_end__[];
uint8_t * sram_address (uint32_t offset);

View File

@@ -135,6 +135,12 @@ static const uint8_t extended_capabilities[] __attribute__ ((aligned (1))) = {
0x01, 0x00,
};
/* General Feature Management */
static const uint8_t feature_mngmnt[] __attribute__ ((aligned (1))) = {
3,
0x81, 0x01, 0x20,
};
/* Algorithm Attributes */
#define OPENPGP_ALGO_RSA 0x01
#define OPENPGP_ALGO_ECDH 0x12
@@ -1614,18 +1620,20 @@ static const uint16_t cmp_ch_data[] = {
};
static const uint16_t cmp_app_data[] = {
3,
4,
GPG_DO_AID,
GPG_DO_HIST_BYTES,
GPG_DO_DISCRETIONARY,
GPG_DO_FEATURE_MNGMNT,
};
static const uint16_t cmp_discretionary[] = {
8,
11,
GPG_DO_EXTCAP,
GPG_DO_ALG_SIG, GPG_DO_ALG_DEC, GPG_DO_ALG_AUT,
GPG_DO_PW_STATUS,
GPG_DO_FP_ALL, GPG_DO_CAFP_ALL, GPG_DO_KGTIME_ALL
GPG_DO_FP_ALL, GPG_DO_CAFP_ALL, GPG_DO_KGTIME_ALL,
GPG_DO_UIF_SIG, GPG_DO_UIF_DEC, GPG_DO_UIF_AUT
};
static const uint16_t cmp_ss_temp[] = { 1, GPG_DO_DS_COUNT };
@@ -1664,11 +1672,15 @@ gpg_do_table[] = {
rw_algorithm_attr },
{ GPG_DO_ALG_AUT, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
rw_algorithm_attr },
{ GPG_DO_UIF_SIG, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_uif },
{ GPG_DO_UIF_DEC, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_uif },
{ GPG_DO_UIF_AUT, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, rw_uif },
{ GPG_DO_KDF, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
rw_kdf },
/* Fixed data */
{ GPG_DO_HIST_BYTES, DO_FIXED, AC_ALWAYS, AC_NEVER, historical_bytes },
{ GPG_DO_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities },
{ GPG_DO_FEATURE_MNGMNT, DO_FIXED, AC_ALWAYS, AC_NEVER, feature_mngmnt },
/* Compound data: Read access only */
{ GPG_DO_CH_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ch_data },
{ GPG_DO_APP_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_app_data },

View File

@@ -1501,7 +1501,7 @@ const struct command cmds[] = {
};
#define NUM_CMDS ((int)(sizeof (cmds) / sizeof (struct command)))
static void
static int
process_command_apdu (void)
{
int i;
@@ -1536,6 +1536,8 @@ process_command_apdu (void)
DEBUG_BYTE (cmd);
GPG_NO_INS ();
}
return (cmd == INS_PSO) | (cmd == INS_INTERNAL_AUTHENTICATE);
}
void *
@@ -1553,6 +1555,7 @@ openpgp_card_thread (void *arg)
int len, pw_len, newpw_len;
#endif
eventmask_t m = eventflag_wait (openpgp_comm);
int r = 0;
DEBUG_INFO ("GPG!: ");
@@ -1640,10 +1643,11 @@ openpgp_card_thread (void *arg)
break;
led_blink (LED_START_COMMAND);
process_command_apdu ();
r = process_command_apdu ();
if (!r)
led_blink (LED_FINISH_COMMAND);
done:
eventflag_signal (ccid_comm, EV_EXEC_FINISHED);
eventflag_signal (ccid_comm, r? EV_EXEC_FINISHED_ACK : EV_EXEC_FINISHED);
}
gpg_fini ();

View File

@@ -1,7 +1,7 @@
/*
* usb-ccid.c -- USB CCID protocol handling
*
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017
* Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
@@ -1076,7 +1076,9 @@ ccid_send_data_block (struct ccid *c)
static void
ccid_send_data_block_time_extension (struct ccid *c)
{
ccid_send_data_block_internal (c, CCID_CMD_STATUS_TIMEEXT, 1);
ccid_send_data_block_internal (c, CCID_CMD_STATUS_TIMEEXT,
(c->ccid_state == CCID_STATE_CONFIRM_ACK?
0xff : 1));
}
static void
@@ -1461,6 +1463,7 @@ ccid_handle_data (struct ccid *c)
}
break;
case CCID_STATE_EXECUTE:
case CCID_STATE_CONFIRM_ACK:
if (c->ccid_header.msg_type == CCID_POWER_OFF)
next_state = ccid_power_off (c);
else if (c->ccid_header.msg_type == CCID_SLOT_STATUS)
@@ -1489,6 +1492,7 @@ ccid_handle_timeout (struct ccid *c)
switch (c->ccid_state)
{
case CCID_STATE_EXECUTE:
case CCID_STATE_CONFIRM_ACK:
ccid_send_data_block_time_extension (c);
break;
default:
@@ -1561,7 +1565,8 @@ extern int usb_get_descriptor (struct usb_dev *dev);
extern void random_init (void);
extern void random_fini (void);
static chopstx_intr_t interrupt;
static chopstx_intr_t ack_intr;
static chopstx_intr_t usb_intr;
/*
* Return 0 for normal USB event
@@ -1576,7 +1581,7 @@ usb_event_handle (struct usb_dev *dev)
e = usb_lld_event_handler (dev);
ep_num = USB_EVENT_ENDP (e);
chopstx_intr_done (&interrupt);
chopstx_intr_done (&usb_intr);
/* Transfer to endpoint (not control endpoint) */
if (ep_num != 0)
@@ -1678,7 +1683,8 @@ usb_event_handle (struct usb_dev *dev)
static chopstx_poll_cond_t ccid_event_poll_desc;
static struct chx_poll_head *const ccid_poll[] = {
(struct chx_poll_head *const)&interrupt,
(struct chx_poll_head *const)&ack_intr,
(struct chx_poll_head *const)&usb_intr,
(struct chx_poll_head *const)&ccid_event_poll_desc
};
#define CCID_POLL_NUM (sizeof (ccid_poll)/sizeof (struct chx_poll_head *))
@@ -1697,9 +1703,10 @@ ccid_thread (void *arg)
eventflag_init (&ccid.openpgp_comm);
usb_lld_init (&dev, USB_INITIAL_FEATURE);
chopstx_claim_irq (&interrupt, INTR_REQ_USB);
chopstx_claim_irq (&usb_intr, INTR_REQ_USB);
usb_event_handle (&dev); /* For old SYS < 3.0 */
ackbtn_init (&ack_intr);
eventflag_prepare_poll (&c->ccid_comm, &ccid_event_poll_desc);
reset:
@@ -1732,7 +1739,7 @@ ccid_thread (void *arg)
chopstx_poll (timeout_p, CCID_POLL_NUM, ccid_poll);
if (interrupt.ready)
if (usb_intr.ready)
{
if (usb_event_handle (&dev) == 0)
continue;
@@ -1752,6 +1759,15 @@ ccid_thread (void *arg)
goto reset;
}
if (ack_intr.ready)
{
ackbtn_disable ();
chopstx_intr_done (&ack_intr);
led_blink (LED_FINISH_COMMAND);
if (c->ccid_state == CCID_STATE_CONFIRM_ACK)
goto exec_done;
}
timeout = USB_CCID_TIMEOUT;
m = eventflag_get (&c->ccid_comm);
@@ -1779,6 +1795,7 @@ ccid_thread (void *arg)
else if (m == EV_EXEC_FINISHED)
if (c->ccid_state == CCID_STATE_EXECUTE)
{
exec_done:
if (c->a->sw == GPG_THREAD_TERMINATED)
{
c->sw1sw2[0] = 0x90;
@@ -1810,7 +1827,17 @@ ccid_thread (void *arg)
}
else
{
DEBUG_INFO ("ERR07\r\n");
DEBUG_INFO ("ERR05\r\n");
}
else if (m == EV_EXEC_FINISHED_ACK)
if (c->ccid_state == CCID_STATE_EXECUTE)
{
ackbtn_enable ();
c->ccid_state = CCID_STATE_CONFIRM_ACK;
}
else
{
DEBUG_INFO ("ERR06\r\n");
}
else if (m == EV_TX_FINISHED)
{
@@ -1842,7 +1869,7 @@ ccid_thread (void *arg)
/* Loading reGNUal. */
while (bDeviceState != USB_DEVICE_STATE_UNCONNECTED)
{
chopstx_intr_wait (&interrupt);
chopstx_intr_wait (&usb_intr);
usb_event_handle (&dev);
}

View File

@@ -1,7 +1,7 @@
/*
* usb_ctrl.c - USB control pipe device specific code for Gnuk
*
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017
* Copyright (C) 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*