fixes and enhancements
authorNIIBE Yutaka <gniibe@fsij.org>
Thu, 9 Sep 2010 16:25:44 +0000 (01:25 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Thu, 9 Sep 2010 16:25:44 +0000 (01:25 +0900)
NEWS
README
THANKS [new file with mode: 0644]
doc/HACKING
doc/NOTES
src/flash.c
src/gnuk.h
src/random.c
src/usb-icc.c
src/usb_desc.c

diff --git a/NEWS b/NEWS
index 8c60254..dff2d36 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,14 @@
 Gnuk NEWS - User visible changes
 
+* Major changes in Gnuk 0.2
+
+  Released 2010-09-10, by NIIBE Yutaka
+
+** With DEBUG=1, timeout is more than 3 seconds.
+
+** Flash ROM entries for random numbers are cleared after use. 
+
+
 * Major changes in Gnuk 0.1
 
   Released 2010-09-10, by NIIBE Yutaka
diff --git a/README b/README
index 79fd165..3116893 100644 (file)
--- a/README
+++ b/README
@@ -1,6 +1,6 @@
 Gnuk - software for GPG USB Token
 
-                                                           Version 0.1
+                                                           Version 0.2
                                                             2010-09-10
                                                           Niibe Yutaka
                                      Free Software Initiative of Japan
@@ -54,8 +54,8 @@ Targets
 
 We use Olimex STM32-H103 board.
 
-I think that it runs on Olimex STM32-P103, STBee, or STBee mini too.
-Besides, we are porting it to STM32 Primer 2.
+I think that it could run on Olimex STM32-P103, STBee, or STBee mini
+too.  Besides, we are porting it to STM32 Primer 2.
 
 
 Souce code
@@ -93,11 +93,18 @@ Gnuk is distributed with external source code.
   STM32F10x USB Full Speed Device Library (USB-FS-Device_Lib)
   is a STM32F10x library for USB functionality.
 
-  I took Libraries/STM32_USB-FS-Device_Driver and a part of
-  Project/ in STM32_USB-FS-Device_Lib distribution.
+  I took Libraries/STM32_USB-FS-Device_Driver and 
+  Project/Virtual_COM_Port in STM32_USB-FS-Device_Lib distribution.
   See http://www.st.com for detail.
 
 
+Host Requirements
+=================
+
+For GNU/Linux, libccid version >= 1.3.11 is required.
+libccid version == 1.3.9 is known not working well by the issue [r4235].
+
+
 How to compile
 ==============
 
@@ -183,7 +190,6 @@ For libccid, we need following change:
                <string>Gemplus GemPC Key</string>
 ------------------
 
-
 Then, try following to see Gnuk runs:
 
   $ gpg --card-status
diff --git a/THANKS b/THANKS
new file mode 100644 (file)
index 0000000..05ac47c
--- /dev/null
+++ b/THANKS
@@ -0,0 +1,8 @@
+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.
+
+Jan Sur                        jan@suhr.info
+Kaz Kojima             kkojima@rr.iij4u.or.jp
+Shane Coughlan         scoughlan@openinventionnetwork.com
+Werner Koch            wk@gnupg.org
index aa22d21..2722544 100644 (file)
@@ -1,3 +1,17 @@
+* configure support
+
+configure script would be good to select a board and to generate
+serial number.
+
+
+* Random number update
+
+Currently, Gnuk doesn't have random number generator, but use random
+bytes calculated by hosts.  When Gnuk uses random number, the entry in
+Flash ROM will be cleared.  Some scheme to update random number bytes
+is needed.  Possibly, private Data Objects.
+
+
 * Random Number Generator
 
 RNG is needed for Data Encryption Key to encrypt private key (P and Q).
@@ -10,7 +24,7 @@ be possible to get entropy from USB traffic (of other devices).
 It would be good not to use malloc.
 
 
-* Manufacture ID
+* [DONE] Manufacture ID
 
 Get it from FSFE.
 
@@ -19,6 +33,7 @@ Get it from FSFE.
 
 Currently, aid[] in openpgp-do.c has serial number 00000001.
 It would be good to generate (random) number at compile time.
+Use same serial number for OpenPGPcard and USB serial number.
 
 
 * Flash ROM recover from shutdown
index bd92b13..4fc4825 100644 (file)
--- a/doc/NOTES
+++ b/doc/NOTES
@@ -11,7 +11,7 @@ OpenPGP card protocol implementation
 
 I try to follow "no clear password(s)" policy.
 After key import, keystrings are also removed.
-But because of this, we only support single key for this version.
+But because of this, it is not that easy to overwrite key(s).
 
 
 How a private key is stored
index e70c105..e7af9ee 100644 (file)
@@ -307,3 +307,10 @@ flash_key_release (const uint8_t *key_addr)
 {
   (void)key_addr;
 }
+
+void
+flash_clear_halfword (uint32_t addr)
+{
+  flash_program_halfword (addr, 0);
+}
+
index c519152..54e4dc5 100644 (file)
@@ -84,6 +84,7 @@ extern uint8_t *flash_key_alloc (void);
 extern void flash_key_release (const uint8_t *);
 extern const uint8_t *flash_do_pool (void);
 extern void flash_set_do_pool_last (const uint8_t *p);
+extern void flash_clear_halfword (uint32_t addr);
 
 #define KEY_MAGIC_LEN 8
 #define KEY_CONTENT_LEN 256    /* p and q */
index 629f2a2..cbd4aec 100644 (file)
@@ -30,9 +30,23 @@ extern void *_binary_random_bits_start;
 const uint8_t *
 random_bytes_get (void)
 {
-  uint32_t addr;
+  uint32_t addr, addr0;
 
   addr = (uint32_t)&_binary_random_bits_start + ((hardclock () << 5) & 0x3e0);
+  addr0 = addr; 
+
+  while (1)
+    {
+      if (*(uint32_t *)addr != 0)
+       break;
+
+      addr += 32;
+      if (addr >= ((uint32_t)&_binary_random_bits_start) + 1024)
+       addr = ((uint32_t)&_binary_random_bits_start);
+
+      if (addr == addr0)
+       fatal ();
+    }
 
   return (const uint8_t *)addr;
 }
@@ -40,12 +54,19 @@ random_bytes_get (void)
 void
 random_bytes_free (const uint8_t *p)
 {
-  (void)p;
+  int i;
+  uint32_t addr = (uint32_t)p;
+
+  for (i = 0; i < 16; i++)
+    flash_clear_halfword (addr+i*2);
 }
 
 uint32_t
 get_random (void)
 {
   const uint32_t *p = (const uint32_t *)random_bytes_get ();
-  return *p;
+  uint32_t r = *p;
+
+  random_bytes_free ((const uint8_t *)p);
+  return r;
 }
index 84cf700..bafa0ef 100644 (file)
 #include "hw_config.h"
 #include "usb_istr.h"
 
+#define ICC_SET_PARAMS         0x61
 #define ICC_POWER_ON           0x62
 #define ICC_POWER_OFF          0x63
 #define ICC_SLOT_STATUS                0x65
 #define ICC_XFR_BLOCK          0x6F
 #define ICC_DATA_BLOCK_RET     0x80
 #define ICC_SLOT_STATUS_RET    0x81
+#define ICC_SET_PARAMS_RET     0x82
 
 #define ICC_MSG_SEQ_OFFSET     6
 #define ICC_MSG_STATUS_OFFSET  7
@@ -153,9 +155,25 @@ enum icc_state
 
 static enum icc_state icc_state;
 
-/* Direct conversion, T=1, "FSIJ" */
-static const char ATR[] = { '\x3B', '\x84', '\x01', 'F', 'S', 'I', 'J',
-                           ('\x84'^'F'^'S'^'I'^'J') };
+/*
+ * ATR (Answer To Reset) string
+ *
+ * TS = 0x3B: Direct conversion
+ * T0 = 0x94: TA1 and TD1 follow, 4 historical bytes
+ * TA1 = 0x11: FI=1, DI=1
+ * TD1 = 0x81: TD2 follows, T=1
+ * TD2 = 0x31: TA3 and TB3 follow, T=1
+ * TA3 = 0xFE: IFSC = 254 bytes
+ * TB3 = 0x55: BWI = 5, CWI = 5   (BWT timeout 3.2 sec)
+ * Historical bytes: "FSIJ"
+ * XOR check
+ *
+ */
+static const char ATR[] = {
+  0x3B, 0x94, 0x11, 0x81, 0x31, 0xFE, 0x55,
+ 'F', 'S', 'I', 'J',
+ (0x94^0x11^0x81^0x31^0xFE^0x55^'F'^'S'^'I'^'J')
+};
 
 /* Send back ATR (Answer To Reset) */
 enum icc_state
@@ -183,7 +201,7 @@ icc_power_on (void)
     }
   else
     {
-      icc_tx_size = ICC_MSG_DATA_OFFSET + size_atr;
+      icc_tx_size = ICC_MSG_HEADER_SIZE + size_atr;
       USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
       SetEPTxValid (ENDP1);
       DEBUG_INFO ("ON\r\n");
@@ -217,7 +235,7 @@ icc_send_status (void)
     }
   else
     {
-      icc_tx_size = ICC_MSG_DATA_OFFSET;
+      icc_tx_size = ICC_MSG_HEADER_SIZE;
       USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
       SetEPTxValid (ENDP1);
     }
@@ -265,7 +283,33 @@ icc_send_data_block (uint8_t status, uint8_t error, uint8_t chain,
     }
   else
     {
-      icc_tx_size = ICC_MSG_DATA_OFFSET + len;
+      icc_tx_size = ICC_MSG_HEADER_SIZE + len;
+      USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
+      SetEPTxValid (ENDP1);
+#ifdef DEBUG_MORE
+      DEBUG_INFO ("DATA\r\n");
+#endif
+    }
+}
+
+
+static void
+icc_send_params (void)
+{
+  memcpy (icc_tx_data, icc_rcv_data,
+         ICC_MSG_HEADER_SIZE + icc_header->data_len);
+  icc_tx_data[0] = ICC_SET_PARAMS_RET;
+  icc_tx_data[ICC_MSG_STATUS_OFFSET] = 0;
+  icc_tx_data[ICC_MSG_ERROR_OFFSET] = 0;
+  icc_tx_data[ICC_MSG_CHAIN_OFFSET] = icc_rcv_data[7];
+
+  if (!icc_tx_ready ())
+    {                          /* not ready to send */
+      DEBUG_INFO ("ERR09\r\n");
+    }
+  else
+    {
+      icc_tx_size = ICC_MSG_HEADER_SIZE + icc_header->data_len;
       USB_SIL_Write (EP1_IN, icc_tx_data, icc_tx_size);
       SetEPTxValid (ENDP1);
 #ifdef DEBUG_MORE
@@ -274,6 +318,7 @@ icc_send_data_block (uint8_t status, uint8_t error, uint8_t chain,
     }
 }
 
+
 static enum icc_state
 icc_handle_data (void)
 {
@@ -295,7 +340,7 @@ icc_handle_data (void)
       break;
     case ICC_STATE_WAIT:
       if (icc_header->msg_type == ICC_POWER_ON)
-       /* Not in the spec., but GPG 2 */
+       /* Not in the spec., but pcscd/libccid */
        next_state = icc_power_on ();
       else if (icc_header->msg_type == ICC_POWER_OFF)
        next_state = icc_power_off ();
@@ -326,6 +371,8 @@ icc_handle_data (void)
              DEBUG_INFO ("ERR02\r\n");
            }
        }
+      else if (icc_header->msg_type == ICC_SET_PARAMS)
+       icc_send_params ();
       else
        {                       /* XXX: error */
          DEBUG_INFO ("ERR03\r\n");
index 932bc27..1532711 100644 (file)
@@ -75,7 +75,18 @@ static const uint8_t gnukConfigDescriptor[] = {
   0xfe, 0, 0, 0,         /* dwMaxIFSD:  */
   0, 0, 0, 0,            /* dwSynchProtocols: FIXED VALUE */
   0, 0, 0, 0,            /* dwMechanical: FIXED VALUE */
-  0x40, 0x08, 0x04, 0x00, /* dwFeatures: Short and extended APDU level */
+#ifdef DEBUG
+  0x80, 0x04, 0x04, 0x00, /* dwFeatures:
+                          *  Short and extended APDU level: 0x40000
+                          *  Automatic IFSD               : 0x00400
+                          *  Automatic PPS CUR            : 0x00080
+                          */
+#else
+  0x40, 0x00, 0x04, 0x00, /* dwFeatures:
+                          *  Short and extended APDU level: 0x40000
+                          *  Automatic PPS PROP           : 0x00040
+                          */
+#endif
   0x40, 0x00, 0, 0,      /* dwMaxCCIDMessageLength: 64 */
   0xff,                          /* bClassGetResponse: */
   0xff,                          /* bClassEnvelope: */