From 3ad45f036e959d5fa3cab7381a2eb9f807cb5a2a Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Fri, 7 Jan 2011 16:18:47 +0900 Subject: [PATCH] serial number by chip unique ID --- ChangeLog | 22 +++++++++++++++++ README | 14 +++++++---- boards/common/hw_config.c | 9 +++++++ src/config.h.in | 14 +---------- src/configure | 32 ++++++++++++------------- src/gnuk.h | 4 +++- src/openpgp-do.c | 50 ++++++++++++++++++++++++++++----------- src/openpgp.c | 9 ++----- src/usb_desc.c | 10 +------- src/usb_prop.c | 37 ++++++++++++++++++++++++++++- 10 files changed, 134 insertions(+), 67 deletions(-) diff --git a/ChangeLog b/ChangeLog index 74df436..54e5296 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,27 @@ +2011-01-07 NIIBE Yutaka + + * 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 + * 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 diff --git a/README b/README index c7744f2..5a47154 100644 --- 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: Gemplus GemPC Key ------------------ +This entry has been added into libccid 1.4.1 already ([r5425]). + Testing Gnuk ------------ diff --git a/boards/common/hw_config.c b/boards/common/hw_config.c index 739451c..d355262 100644 --- a/boards/common/hw_config.c +++ b/boards/common/hw_config.c @@ -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; +} diff --git a/src/config.h.in b/src/config.h.in index 7d50cae..da241d5 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -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@ diff --git a/src/configure b/src/configure index ffcc9f4..60e9681 100755 --- a/src/configure +++ b/src/configure @@ -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 [] - --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 diff --git a/src/gnuk.h b/src/gnuk.h index f33b96e..8956657 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -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); diff --git a/src/openpgp-do.c b/src/openpgp-do.c index 6ab5c0b..f80f7e4 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -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 diff --git a/src/openpgp.c b/src/openpgp.c index c1e8c02..69e1ed4 100644 --- a/src/openpgp.c +++ b/src/openpgp.c @@ -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 diff --git a/src/usb_desc.c b/src/usb_desc.c index 1b22b30..dbb764e 100644 --- a/src/usb_desc.c +++ b/src/usb_desc.c @@ -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)}, }; diff --git a/src/usb_prop.c b/src/usb_prop.c index 3353589..f8383f1 100644 --- a/src/usb_prop.c +++ b/src/usb_prop.c @@ -36,9 +36,34 @@ #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,