serial number by chip unique ID
authorNIIBE Yutaka <gniibe@fsij.org>
Fri, 7 Jan 2011 07:18:47 +0000 (16:18 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Fri, 7 Jan 2011 07:18:47 +0000 (16:18 +0900)
ChangeLog
README
boards/common/hw_config.c
src/config.h.in
src/configure
src/gnuk.h
src/openpgp-do.c
src/openpgp.c
src/usb_desc.c
src/usb_prop.c

index 74df436..54e5296 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
+2011-01-07  NIIBE Yutaka  <gniibe@fsij.org>
+
+       * src/openpgp.c (cmd_read_binary): Call gpg_do_get_data for AID.
+
+       * src/openpgp-do.c (gpg_do_get_data): Added new argument WITH_TAG.
+
+       * src/usb_prop.c (gnuk_device_init)
+       (gnuk_device_GetStringDescriptor): gnukStringSerial with unique
+       chip ID.
+
+       * src/openpgp-do.c (do_openpgpcard_aid): New.
+       (openpgpcard_aid): Removed.
+
+       * boards/common/hw_config.c (unique_device_id): New.
+
 2011-01-06  NIIBE Yutaka  <gniibe@fsij.org>
 
+       * src/config.h.in (PINPAD_MORE_DEFINE): Added.
+
+       * src/configure: Requiring bash (for variable substitution), added
+       PINPAD.
+
+       * src/Makefile.in: Support PINPAD.
+
        * src/pin-cir.c (cir_timer_interrupt): Support Sharp protocol.
 
 2011-01-04  NIIBE Yutaka  <gniibe@fsij.org>
diff --git a/README b/README
index c7744f2..5a47154 100644 (file)
--- a/README
+++ b/README
@@ -1,7 +1,7 @@
 Gnuk - software for GPG USB Token
 
-                                                           Version 0.5
-                                                            2010-12-13
+                                                           Version 0.6
+                                                            2011-01-XX
                                                           Niibe Yutaka
                                      Free Software Initiative of Japan
 
@@ -26,7 +26,7 @@ USB Token by Gnuk everywhere.
 Release notes
 =============
 
-This is sixth release of Gnuk.  While it works well for specific
+This is seventh release of Gnuk.  While it works well for specific
 usages, it is still experimental.
 
 Tested features are:
@@ -51,7 +51,9 @@ Tested features are:
 
        * INTERNAL AUTHENTICATE
 
-       * Changing value of password status bytes (0x00C4).
+       * Changing value of password status bytes (0x00C4)
+
+       * Verify with pin pad
 
 It is known not-working well:
 
@@ -234,7 +236,7 @@ and you will see debug output of Gnuk.
 Libccid fix needed
 ------------------
 
-For libccid, we need following change:
+For libccid (< 1.4.1), we need following change:
 
 --- /etc/libccid_Info.plist.dpkg-dist  2009-07-29 06:50:20.000000000 +0900
 +++ /etc/libccid_Info.plist    2010-09-05 09:09:49.000000000 +0900
@@ -264,6 +266,8 @@ For libccid, we need following change:
                <string>Gemplus GemPC Key</string>
 ------------------
 
+This entry has been added into libccid 1.4.1 already ([r5425]).
+
 
 Testing Gnuk
 ------------
index 739451c..d355262 100644 (file)
@@ -31,3 +31,12 @@ Leave_LowPowerMode (void)
   else
     bDeviceState = ATTACHED;
 }
+
+const uint8_t *
+unique_device_id (void)
+{
+  /* STM32F103 has 96-bit unique device identifier */
+  const uint8_t *addr = (const uint8_t *)0x1ffff7e8;
+
+  return addr;
+}
index 7d50cae..da241d5 100644 (file)
@@ -2,19 +2,7 @@
 #ifdef DEBUG
 #define ENABLE_VIRTUAL_COM_PORT 1
 #endif
-
-@FSIJ_DEFINE@
-#ifdef WITH_FSIJ_SERIAL_NUMBER
-/* FSIJ */
-#define MANUFACTURER_IN_AID            0xf5, 0x17
-#else
-/* for random serial number*/
-#define MANUFACTURER_IN_AID            0xff, 0xfe
-#endif
-
-#define SERIAL_NUMBER_IN_AID  @SERIAL_NUMBER_FOUR_BYTES@
-
+@SERIAL_DEFINE@
 @DFU_DEFINE@
-
 @PINPAD_DEFINE@
 @PINPAD_MORE_DEFINE@
index ffcc9f4..60e9681 100755 (executable)
@@ -3,7 +3,7 @@
 #
 # This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
 #
-# Copyright (C) 2010 Free Software Initiative of Japan
+# Copyright (C) 2010, 2011 Free Software Initiative of Japan
 #
 # This file is a part of Gnuk, a GnuPG USB Token implementation.
 # Gnuk is free software: you can redistribute it and/or modify it
@@ -24,7 +24,7 @@ help=no
 target=OLIMEX_STM32_H103
 verbose=no
 with_dfu=default
-with_fsij=no
+with_fixed_serial=no
 debug=no
 pinpad=no
 
@@ -62,10 +62,10 @@ for option; do
     with_dfu=yes ;;
   --without-dfu)
     with_dfu=no ;;
-  --with-fsij)
-    with_fsij=yes ;;
-  --without-fsij)
-    with_fsij=no ;;
+  --with-fixed-serial)
+    with_fixed_serial=yes ;;
+  --without-fixed-serial)
+    with_fixed_serial=no ;;
   *)
     echo "Unrecognized option \`$option'" >&2
     echo "Try \`$0 --help' for more information." >&2
@@ -92,7 +92,7 @@ Configuration:
   --enable-pinpad={cir,dial}
                        PIN input device support        [no]
   --with-dfu           build image for DFU             [<target specific>]
-  --with-fsij          Use FSIJ serial number          [no: random number]
+  --with-fixed-serial  Use fixed serial number         [no: chip unique ID]
 EOF
   exit 0
 fi
@@ -126,19 +126,18 @@ STM8S_DISCOVERY)
   ;;
 esac
 
-# --with-fsij option
-if test "$with_fsij" = "no"; then
-  echo "Using random serial number for card AID"
-  FSIJ_DEFINE="#undef WITH_FSIJ_SERIAL_NUMBER"
-  SERIAL_NUMBER_FOUR_BYTES=`od -t u1 -N 4 /dev/random | sed -n -e '/^0000000/s/^0000000  *//' -e 's/  */,/gp'`
+# --with-fixed-serial option
+if test "$with_fixed_serial" = "no"; then
+  echo "Using chip unique ID for card AID"
+  SERIAL_DEFINE="#undef SERIAL_NUMBER_IN_AID"
 else
-  echo "Using FSIJ assigned serial number for card AID"
+  echo "Using fixed serial number (at compile time) for card AID"
   if test "x$MAIL" = "x"; then
     echo "ERROR: Please set MAIL shell variable to select FSIJ serial number" >&2
     exit 1
   fi
-  FSIJ_DEFINE="#define WITH_FSIJ_SERIAL_NUMBER 1"
-  SERIAL_NUMBER_FOUR_BYTES=`sed -n -e "/^$MAIL/s/^.* \(..\):\(..\):\(..\):\(..\)/0x\1, 0x\2, 0x\3, 0x\4/p" ../FSIJ_SERIAL_NUMBER`
+  SERIAL=`sed -n -e "/^$MAIL/s/^.* \(..\):\(..\):\(..\):\(..\)/0x\1, 0x\2, 0x\3, 0x\4/p" ../FSIJ_SERIAL_NUMBER`
+  SERIAL_DEFINE="#define SERIAL_NUMBER_IN_AID $SERIAL"
 fi
 
 # --enable-debug option
@@ -193,7 +192,6 @@ sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
     -e "s/@PINPAD_DEFINE@/$PINPAD_DEFINE/" \
     -e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
     -e "s/@DFU_DEFINE@/$DFU_DEFINE/" \
-    -e "s/@FSIJ_DEFINE@/$FSIJ_DEFINE/" \
-    -e "s/@SERIAL_NUMBER_FOUR_BYTES@/$SERIAL_NUMBER_FOUR_BYTES/" \
+    -e "s/@SERIAL_DEFINE@/$SERIAL_DEFINE/" \
        < config.h.in > config.h
 exit 0
index f33b96e..8956657 100644 (file)
@@ -93,7 +93,7 @@ uint16_t data_objects_number_of_bytes;
 
 extern void gpg_data_scan (const uint8_t *p);
 extern void gpg_data_copy (const uint8_t *p);
-extern void gpg_do_get_data (uint16_t tag);
+extern void gpg_do_get_data (uint16_t tag, int with_tag);
 extern void gpg_do_put_data (uint16_t tag, const uint8_t *data, int len);
 extern void gpg_do_public_key (uint8_t kk_byte);
 
@@ -322,3 +322,5 @@ extern uint8_t pin_input_len;
 
 extern msg_t pin_main (void *arg);
 #endif
+
+extern const uint8_t *unique_device_id (void);
index 6ab5c0b..f80f7e4 100644 (file)
@@ -114,20 +114,10 @@ uint16_t data_objects_number_of_bytes;
 
 /*
  * Compile time vars:
- *   AID, Historical Bytes (template), Extended Capabilities,
+ *   Historical Bytes (template), Extended Capabilities,
  *   and Algorithm Attributes
  */
 
-/* AID */
-const uint8_t openpgpcard_aid[17] __attribute__ ((aligned (1))) = {
-  16,
-  0xd2, 0x76, 0x00, 0x01, 0x24, 0x01,
-  0x02, 0x00,                  /* Version 2.0 */
-  MANUFACTURER_IN_AID,
-  SERIAL_NUMBER_IN_AID,
-  0x00, 0x00
-};
-
 /* Historical Bytes (template) */
 static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
   10,
@@ -412,6 +402,38 @@ do_kgtime_all (uint16_t tag, int with_tag)
   return 1;
 }
 
+const uint8_t openpgpcard_aid_template[] = {
+  0xd2, 0x76, 0x00, 0x01, 0x24, 0x01,
+  0x02, 0x00,                  /* Version 2.0 */
+  0xf5, 0x17,                  /* Manufacturer: FSIJ */
+#if defined(SERIAL_NUMBER_IN_AID)
+  SERIAL_NUMBER_IN_AID
+#endif
+};
+
+static int
+do_openpgpcard_aid (uint16_t tag, int with_tag)
+{
+#if !defined(SERIAL_NUMBER_IN_AID)
+  const uint8_t *u = unique_device_id ();
+#endif
+
+  if (with_tag)
+    {
+      copy_tag (tag);
+      *res_p++ = 16;
+    }
+
+  memcpy (res_p, openpgpcard_aid_template, sizeof (openpgpcard_aid_template));
+  res_p += sizeof (openpgpcard_aid_template);
+#if !defined(SERIAL_NUMBER_IN_AID)
+  memcpy (res_p, u, 4);
+#endif
+  *res_p++ = 0;
+  *res_p++ = 0;
+  return 1;
+}
+
 static int
 do_ds_count (uint16_t tag, int with_tag)
 {
@@ -884,11 +906,11 @@ gpg_do_table[] = {
   { GPG_DO_KGTIME_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_kgtime_all },
   /* Pseudo DO READ: calculated, not changeable by user */
   { GPG_DO_DS_COUNT, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_ds_count },
+  { GPG_DO_AID, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_openpgpcard_aid },
   /* Pseudo DO READ/WRITE: calculated */
   { GPG_DO_PW_STATUS, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
     rw_pw_status },
   /* Fixed data */
-  { GPG_DO_AID, DO_FIXED, AC_ALWAYS, AC_NEVER, openpgpcard_aid },
   { GPG_DO_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities },
   { GPG_DO_ALG_SIG, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr },
   { GPG_DO_ALG_DEC, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr },
@@ -1167,7 +1189,7 @@ copy_do (const struct do_table_entry *do_p, int with_tag)
  *   Call write_res_adpu to fill data returned
  */
 void
-gpg_do_get_data (uint16_t tag)
+gpg_do_get_data (uint16_t tag, int with_tag)
 {
   const struct do_table_entry *do_p = get_do_entry (tag);
 
@@ -1178,7 +1200,7 @@ gpg_do_get_data (uint16_t tag)
 
   if (do_p)
     {
-      if (copy_do (do_p, 0) < 0)
+      if (copy_do (do_p, with_tag) < 0)
        /* Overwriting partially written result  */
        GPG_SECURITY_FAILURE ();
       else
index c1e8c02..69e1ed4 100644 (file)
@@ -517,13 +517,8 @@ cmd_read_binary (void)
        GPG_BAD_P0_P1 ();
       else
        {
-         int len = openpgpcard_aid[0];
-
+         gpg_do_get_data (0x004f, 1); /* AID */
          res_APDU[0] = 0x5a;
-         memcpy (res_APDU+1, openpgpcard_aid, len);
-         res_APDU[len+1] = 0x90;
-         res_APDU[len+2] = 0x00;
-         res_APDU_size = len + 3;
        }
     }
   else
@@ -593,7 +588,7 @@ cmd_get_data (void)
   if (file_selection != FILE_DF_OPENPGP)
     GPG_NO_RECORD();
 
-  gpg_do_get_data (tag);
+  gpg_do_get_data (tag, 0);
 }
 
 static void
index 1b22b30..dbb764e 100644 (file)
@@ -220,13 +220,6 @@ static const uint8_t gnukStringProduct[] = {
   ' ', 0, 'T', 0, 'o', 0, 'k', 0, 'e', 0, 'n', 0
 };
 
-static const uint8_t gnukStringSerial[] = {
-  8*2+2,                       /* bLength */
-  USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */
-  '2', 0, '0', 0, '1', 0, '0', 0,
-  '1', 0, '2', 0, '1', 0, '3', 0
-};
-
 const ONE_DESCRIPTOR Device_Descriptor = {
   (uint8_t*)gnukDeviceDescriptor,
   sizeof (gnukDeviceDescriptor)
@@ -237,9 +230,8 @@ const ONE_DESCRIPTOR Config_Descriptor = {
   sizeof (gnukConfigDescriptor)
 };
 
-const ONE_DESCRIPTOR String_Descriptor[4] = {
+const ONE_DESCRIPTOR String_Descriptor[3] = {
   {(uint8_t*)gnukStringLangID, sizeof (gnukStringLangID)},
   {(uint8_t*)gnukStringVendor, sizeof (gnukStringVendor)},
   {(uint8_t*)gnukStringProduct, sizeof (gnukStringProduct)},
-  {(uint8_t*)gnukStringSerial, sizeof (gnukStringSerial)},
 };
index 3353589..f8383f1 100644 (file)
 #include "usb-cdc-vport.c"
 #endif
 
+#define SIZE_STRING_SERIAL 22
+static uint8_t gnukStringSerial[SIZE_STRING_SERIAL] = {
+  10*2+2,                      /* bLength */
+  USB_STRING_DESCRIPTOR_TYPE,  /* bDescriptorType */
+#if defined(SERIAL_NUMBER_IN_AID)
+  'F', 0,                      /* 'F' for Fixed */
+#else
+  'C', 0,                      /* 'C' for Chip uniqure ID */
+#endif
+  '-', 0, 
+  0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0,
+};
+
 static void
 gnuk_device_init (void)
 {
+  const uint8_t *u = unique_device_id ();
+  int i;
+
+  for (i = 0; i < 4; i++)
+    {
+      gnukStringSerial[i*2+0x8] = (u[i] >> 4) + 'A';
+      gnukStringSerial[i*2+0x9] = 0;
+      gnukStringSerial[i*2+0xa] = (u[i] & 0x0f) + 'A';
+      gnukStringSerial[i*2+0xb] = 0;
+    }
+
   pInformation->Current_Configuration = 0;
 
   /* Connect the device */
@@ -159,8 +184,18 @@ static uint8_t *
 gnuk_device_GetStringDescriptor (uint16_t Length)
 {
   uint8_t wValue0 = pInformation->USBwValue0;
+  uint32_t  wOffset = pInformation->Ctrl_Info.Usb_wOffset;
 
-  if (wValue0 > (sizeof (String_Descriptor) / sizeof (ONE_DESCRIPTOR)))
+  if (wValue0 == 3)
+    /* Serial number is requested */
+    if (Length == 0)
+      {
+       pInformation->Ctrl_Info.Usb_wLength = SIZE_STRING_SERIAL - wOffset;
+       return 0;
+      }
+    else
+      return gnukStringSerial + wOffset;
+  else if (wValue0 > (sizeof (String_Descriptor) / sizeof (ONE_DESCRIPTOR)))
     return NULL;
   else
     return Standard_GetDescriptorData (Length,