LED blink
authorNIIBE Yutaka <gniibe@fsij.org>
Thu, 9 Dec 2010 01:12:54 +0000 (10:12 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Thu, 9 Dec 2010 01:12:54 +0000 (10:12 +0900)
ChangeLog
NEWS
THANKS
src/ac.c
src/flash.c
src/gnuk.h
src/main.c
src/openpgp-do.c
src/openpgp.c
src/random.c
src/usb-icc.c

index 74d4008..cc51d8b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2010-12-09  NIIBE Yutaka  <gniibe@fsij.org>
+
+       * 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  <gniibe@fsij.org>
 
        * src/gnuk.h (AC_OTHER_AUTHORIZED): Renamed (was:
diff --git a/NEWS b/NEWS
index 760b3cc..92104ce 100644 (file)
--- 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 (file)
--- 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
index 6f8c0fe..a1643d2 100644 (file)
--- 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)
index 66f2bc8..1e7d1a2 100644 (file)
@@ -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;
index 12b0cc0..08a7f2a 100644 (file)
@@ -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];
 
index 6a668a4..bb42e81 100644 (file)
@@ -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 (fatal_code != 0)
+       {
+         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
+           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 (led_state)
-       set_led (1);
-      else
+      if (bDeviceState != CONFIGURED)
        {
-         if ((count & 1))
+         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);
-         else
+           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 (;;);
 }
index abb481e..6ab5c0b 100644 (file)
@@ -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;
          }
index 3ea6c29..60e4780 100644 (file)
@@ -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 ();
index cbd4aec..2a21b0a 100644 (file)
@@ -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;
index e02dfc5..72d1659 100644 (file)
@@ -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;
            }