diff --git a/ChangeLog b/ChangeLog index 74d4008..cc51d8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2010-12-09 NIIBE Yutaka + + * src/usb-icc.c (icc_power_off): Set icc_data_size = 0 to specify + no command APDU. Signal GPGThread. + (icc_handle_data, USBthread): Don't signal main thread any more. + + * src/openpgp.c (GPGthread): Only process the command APDU, if any. + + * src/openpgp-do.c (do_tag_to_nr): Don't call fatal. + * src/main.c (fatal_code): New. + (main): Implemented 1-bit LED status display. + (fatal): Added argument CODE. + * src/flash.c (flash_data_pool_allocate): Supply argument FATAL_FLASH. + * src/random.c (random_bytes_get): Supply argument FATAL_RANDOM. + * src/ac.c (auth_status): Added volatile, and remove static. + 2010-12-08 NIIBE Yutaka * src/gnuk.h (AC_OTHER_AUTHORIZED): Renamed (was: diff --git a/NEWS b/NEWS index 760b3cc..92104ce 100644 --- a/NEWS +++ b/NEWS @@ -4,12 +4,19 @@ Gnuk NEWS - User visible changes Released 2010-12-XX, by NIIBE Yutaka -** New board support "STM8S Discovery". +** LED blink +LED blink now shows status output the card. It shows the status of +CHV3, CHV2, and CHV1 when GPG is accessing the card. + +** New board support "STM8S Discovery" ST-Link part (with STM32F103C8T6) of STM8S Discovery board is now supported. ** Digital signing for SHA224/SHA256/SHA384/SHA512 digestInfo is now possible. -** Fixes for password management. +** Fixes for password management +Now, you can allow card to do digital signing multiple times with +single authentication. You can use "forcesig" subcommand in card-edit +of GnuPG to enable the feature. ** Key management changes If you remove all keys, it is possible to import keys again. diff --git a/THANKS b/THANKS index 448bc78..430ea94 100644 --- a/THANKS +++ b/THANKS @@ -5,6 +5,7 @@ Gnuk was originally written by NIIBE Yutaka. People contributed by encouraging the development, testing the implementation, suggesting improvements, or fixing bugs. Here is a list of those people. +Andre Zepezauer andre.zepezauer@student.uni-halle.de Hironobu SUZUKI hironobu@h2np.net Jan Suhr jan@suhr.info Kaz Kojima kkojima@rr.iij4u.or.jp diff --git a/src/ac.c b/src/ac.c index 6f8c0fe..a1643d2 100644 --- a/src/ac.c +++ b/src/ac.c @@ -28,7 +28,7 @@ #include "polarssl/config.h" #include "polarssl/sha1.h" -static uint8_t auth_status = AC_NONE_AUTHORIZED; +uint8_t volatile auth_status = AC_NONE_AUTHORIZED; int ac_check_status (uint8_t ac_flag) diff --git a/src/flash.c b/src/flash.c index 66f2bc8..1e7d1a2 100644 --- a/src/flash.c +++ b/src/flash.c @@ -280,7 +280,7 @@ flash_data_pool_allocate (size_t size) if (is_data_pool_full (size)) if (flash_copying_gc () < 0 || /*still*/ is_data_pool_full (size)) - fatal (); + fatal (FATAL_FLASH); p = last_p; last_p += size; diff --git a/src/gnuk.h b/src/gnuk.h index 12b0cc0..08a7f2a 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -1,7 +1,3 @@ -extern Thread *blinker_thread; -#define EV_LED_ON ((eventmask_t)1) -#define EV_LED_OFF ((eventmask_t)2) - extern Thread *stdout_thread; #define EV_TX_READY ((eventmask_t)1) @@ -51,6 +47,20 @@ extern int res_APDU_size; / USB_LL_BUF_SIZE * USB_LL_BUF_SIZE) extern uint8_t icc_buffer[USB_BUF_SIZE]; +enum icc_state +{ + ICC_STATE_START, /* Initial */ + ICC_STATE_WAIT, /* Waiting APDU */ + /* Busy1, Busy2, Busy3, Busy5 */ + ICC_STATE_EXECUTE, /* Busy4 */ + ICC_STATE_RECEIVE, /* APDU Received Partially */ + /* Not used */ + ICC_STATE_SEND, /* APDU Sent Partially */ +}; + +extern volatile enum icc_state icc_state; + +extern volatile uint8_t auth_status; #define AC_NONE_AUTHORIZED 0x00 #define AC_PSO_CDS_AUTHORIZED 0x01 /* PW1 with 0x81 verified */ #define AC_OTHER_AUTHORIZED 0x02 /* PW1 with 0x82 verified */ @@ -185,7 +195,9 @@ extern void gpg_increment_digital_signature_counter (void); extern void gpg_set_pw3 (const uint8_t *newpw, int newpw_len); -extern void fatal (void) __attribute__ ((noreturn)); +extern void fatal (uint8_t code) __attribute__ ((noreturn)); +#define FATAL_FLASH 1 +#define FATAL_RANDOM 2 extern uint8_t keystring_md_pw3[KEYSTRING_MD_SIZE]; diff --git a/src/main.c b/src/main.c index 6a668a4..bb42e81 100644 --- a/src/main.c +++ b/src/main.c @@ -155,30 +155,31 @@ _write (const char *s, int size) static WORKING_AREA(waUSBthread, 128); extern msg_t USBthread (void *arg); -Thread *blinker_thread; /* - * LEDs blinks. - * When GPGthread execute some command, LED stop blinking, but always ON. + * main thread does 1-bit LED display output */ -#define LED_BLINKER_TIMEOUT MS2ST(200) +#define LED_TIMEOUT_INTERVAL MS2ST(100) +#define LED_TIMEOUT_ZERO MS2ST(50) +#define LED_TIMEOUT_ONE MS2ST(200) +#define LED_TIMEOUT_STOP MS2ST(500) +static volatile uint8_t fatal_code; + /* - * Entry point, note, the main() function is already a thread in the system - * on entry. + * Entry point. + * + * NOTE: the main function is already a thread in the system on entry. + * See the hwinit1_common function. */ int main (int argc, char **argv) { - eventmask_t m; - uint8_t led_state = 0; int count = 0; (void)argc; (void)argv; - blinker_thread = chThdSelf (); - usb_lld_init (); USB_Init(); @@ -199,26 +200,108 @@ main (int argc, char **argv) { count++; - m = chEvtWaitOneTimeout (ALL_EVENTS, LED_BLINKER_TIMEOUT); - if (m == EV_LED_ON) - led_state = 1; - else if (m == EV_LED_OFF) - led_state = 0; - - if (led_state) - set_led (1); - else + if (fatal_code != 0) { - if ((count & 1)) - set_led (1); + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_STOP); + set_led (1); + if (fatal_code & 1) + chThdSleep (LED_TIMEOUT_ONE); else - set_led (0); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + if (fatal_code & 2) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_STOP); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + } + + if (bDeviceState != CONFIGURED) + { + set_led (1); + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_STOP * 3); } + else + /* Device configured */ + if (icc_state == ICC_STATE_START) + { + set_led (1); + chThdSleep (LED_TIMEOUT_ONE); + set_led (0); + chThdSleep (LED_TIMEOUT_STOP * 3); + } + else + /* GPGthread running */ + { + set_led (1); + if ((auth_status & AC_ADMIN_AUTHORIZED) != 0) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + if ((auth_status & AC_OTHER_AUTHORIZED) != 0) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + if ((auth_status & AC_PSO_CDS_AUTHORIZED) != 0) + chThdSleep (LED_TIMEOUT_ONE); + else + chThdSleep (LED_TIMEOUT_ZERO); + + if (icc_state == ICC_STATE_WAIT) + { + set_led (0); + chThdSleep (LED_TIMEOUT_STOP * 2); + } + else if (icc_state == ICC_STATE_RECEIVE) + { + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_ONE); + set_led (0); + chThdSleep (LED_TIMEOUT_STOP); + } + else + { + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + set_led (1); + chThdSleep (LED_TIMEOUT_STOP); + set_led (0); + chThdSleep (LED_TIMEOUT_INTERVAL); + } + } #ifdef DEBUG_MORE - if (bDeviceState == CONFIGURED && (count % 100) == 0) + if (bDeviceState == CONFIGURED && (count % 10) == 0) { - DEBUG_SHORT (count / 100); + DEBUG_SHORT (count / 10); _write ("\r\nThis is ChibiOS 2.0.8 on STM32.\r\n" "Testing USB driver.\n\n" "Hello world\r\n\r\n", 35+21+15); @@ -230,8 +313,9 @@ main (int argc, char **argv) } void -fatal (void) +fatal (uint8_t code) { + fatal_code = code; _write ("fatal\r\n", 7); for (;;); } diff --git a/src/openpgp-do.c b/src/openpgp-do.c index abb481e..6ab5c0b 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -282,7 +282,7 @@ do_tag_to_nr (uint16_t tag) case GPG_DO_LANGUAGE: return NR_DO_LANGUAGE; default: - fatal (); + return NR_NONE; } } @@ -1231,11 +1231,16 @@ gpg_do_put_data (uint16_t tag, const uint8_t *data, int len) { uint8_t nr = do_tag_to_nr (tag); - *do_data_p = flash_do_write (nr, data, len); - if (*do_data_p) - GPG_SUCCESS (); - else + if (nr == NR_NONE) GPG_MEMORY_FAILURE (); + else + { + *do_data_p = flash_do_write (nr, data, len); + if (*do_data_p) + GPG_SUCCESS (); + else + GPG_MEMORY_FAILURE (); + } } break; } diff --git a/src/openpgp.c b/src/openpgp.c index 3ea6c29..60e4780 100644 --- a/src/openpgp.c +++ b/src/openpgp.c @@ -751,9 +751,11 @@ GPGthread (void *arg) DEBUG_INFO ("GPG!: "); DEBUG_WORD ((uint32_t)&m); - process_command_apdu (); - - chEvtSignal (icc_thread, EV_EXEC_FINISHED); + if (icc_data_size != 0) + { + process_command_apdu (); + chEvtSignal (icc_thread, EV_EXEC_FINISHED); + } } gpg_fini (); diff --git a/src/random.c b/src/random.c index cbd4aec..2a21b0a 100644 --- a/src/random.c +++ b/src/random.c @@ -45,7 +45,7 @@ random_bytes_get (void) addr = ((uint32_t)&_binary_random_bits_start); if (addr == addr0) - fatal (); + fatal (FATAL_RANDOM); } return (const uint8_t *)addr; diff --git a/src/usb-icc.c b/src/usb-icc.c index e02dfc5..72d1659 100644 --- a/src/usb-icc.c +++ b/src/usb-icc.c @@ -223,18 +223,7 @@ EP2_OUT_Callback (void) } } -enum icc_state -{ - ICC_STATE_START, /* Initial */ - ICC_STATE_WAIT, /* Waiting APDU */ - /* Busy1, Busy2, Busy3, Busy5 */ - ICC_STATE_EXECUTE, /* Busy4 */ - ICC_STATE_RECEIVE, /* APDU Received Partially */ - /* Not used */ - ICC_STATE_SEND, /* APDU Sent Partially */ -}; - -static enum icc_state icc_state; +volatile enum icc_state icc_state; /* * ATR (Answer To Reset) string @@ -368,9 +357,12 @@ icc_send_status (void) enum icc_state icc_power_off (void) { + icc_data_size = 0; + if (gpg_thread) { chThdTerminate (gpg_thread); + chEvtSignal (gpg_thread, (eventmask_t)1); chThdWait (gpg_thread); gpg_thread = NULL; } @@ -515,7 +507,6 @@ icc_handle_data (void) { /* Give this message to GPG thread */ chEvtSignal (gpg_thread, (eventmask_t)1); next_state = ICC_STATE_EXECUTE; - chEvtSignal (blinker_thread, EV_LED_ON); } else if (icc_header->param == 1) { @@ -558,7 +549,6 @@ icc_handle_data (void) icc_data_size = icc_next_p - icc_buffer - ICC_MSG_HEADER_SIZE; icc_chain_p = NULL; next_state = ICC_STATE_EXECUTE; - chEvtSignal (blinker_thread, EV_LED_ON); chEvtSignal (gpg_thread, (eventmask_t)1); } else /* icc_header->param == 3 is not supported. */ @@ -639,8 +629,6 @@ USBthread (void *arg) { if (icc_state == ICC_STATE_EXECUTE) { - chEvtSignal (blinker_thread, EV_LED_OFF); - icc_send_data_block_filling_header (res_APDU_size); icc_state = ICC_STATE_WAIT; }