serial number by chip unique ID

This commit is contained in:
NIIBE Yutaka
2011-01-07 16:18:47 +09:00
parent 57859fb417
commit 3ad45f036e
10 changed files with 134 additions and 67 deletions

View File

@@ -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> 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. * src/pin-cir.c (cir_timer_interrupt): Support Sharp protocol.
2011-01-04 NIIBE Yutaka <gniibe@fsij.org> 2011-01-04 NIIBE Yutaka <gniibe@fsij.org>

14
README
View File

@@ -1,7 +1,7 @@
Gnuk - software for GPG USB Token Gnuk - software for GPG USB Token
Version 0.5 Version 0.6
2010-12-13 2011-01-XX
Niibe Yutaka Niibe Yutaka
Free Software Initiative of Japan Free Software Initiative of Japan
@@ -26,7 +26,7 @@ USB Token by Gnuk everywhere.
Release notes 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. usages, it is still experimental.
Tested features are: Tested features are:
@@ -51,7 +51,9 @@ Tested features are:
* INTERNAL AUTHENTICATE * 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: It is known not-working well:
@@ -234,7 +236,7 @@ and you will see debug output of Gnuk.
Libccid fix needed 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.dpkg-dist 2009-07-29 06:50:20.000000000 +0900
+++ /etc/libccid_Info.plist 2010-09-05 09:09:49.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> <string>Gemplus GemPC Key</string>
------------------ ------------------
This entry has been added into libccid 1.4.1 already ([r5425]).
Testing Gnuk Testing Gnuk
------------ ------------

View File

@@ -31,3 +31,12 @@ Leave_LowPowerMode (void)
else else
bDeviceState = ATTACHED; 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;
}

View File

@@ -2,19 +2,7 @@
#ifdef DEBUG #ifdef DEBUG
#define ENABLE_VIRTUAL_COM_PORT 1 #define ENABLE_VIRTUAL_COM_PORT 1
#endif #endif
@SERIAL_DEFINE@
@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@
@DFU_DEFINE@ @DFU_DEFINE@
@PINPAD_DEFINE@ @PINPAD_DEFINE@
@PINPAD_MORE_DEFINE@ @PINPAD_MORE_DEFINE@

32
src/configure vendored
View File

@@ -3,7 +3,7 @@
# #
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka # 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. # This file is a part of Gnuk, a GnuPG USB Token implementation.
# Gnuk is free software: you can redistribute it and/or modify it # Gnuk is free software: you can redistribute it and/or modify it
@@ -24,7 +24,7 @@ help=no
target=OLIMEX_STM32_H103 target=OLIMEX_STM32_H103
verbose=no verbose=no
with_dfu=default with_dfu=default
with_fsij=no with_fixed_serial=no
debug=no debug=no
pinpad=no pinpad=no
@@ -62,10 +62,10 @@ for option; do
with_dfu=yes ;; with_dfu=yes ;;
--without-dfu) --without-dfu)
with_dfu=no ;; with_dfu=no ;;
--with-fsij) --with-fixed-serial)
with_fsij=yes ;; with_fixed_serial=yes ;;
--without-fsij) --without-fixed-serial)
with_fsij=no ;; with_fixed_serial=no ;;
*) *)
echo "Unrecognized option \`$option'" >&2 echo "Unrecognized option \`$option'" >&2
echo "Try \`$0 --help' for more information." >&2 echo "Try \`$0 --help' for more information." >&2
@@ -92,7 +92,7 @@ Configuration:
--enable-pinpad={cir,dial} --enable-pinpad={cir,dial}
PIN input device support [no] PIN input device support [no]
--with-dfu build image for DFU [<target specific>] --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 EOF
exit 0 exit 0
fi fi
@@ -126,19 +126,18 @@ STM8S_DISCOVERY)
;; ;;
esac esac
# --with-fsij option # --with-fixed-serial option
if test "$with_fsij" = "no"; then if test "$with_fixed_serial" = "no"; then
echo "Using random serial number for card AID" echo "Using chip unique ID for card AID"
FSIJ_DEFINE="#undef WITH_FSIJ_SERIAL_NUMBER" SERIAL_DEFINE="#undef SERIAL_NUMBER_IN_AID"
SERIAL_NUMBER_FOUR_BYTES=`od -t u1 -N 4 /dev/random | sed -n -e '/^0000000/s/^0000000 *//' -e 's/ */,/gp'`
else 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 if test "x$MAIL" = "x"; then
echo "ERROR: Please set MAIL shell variable to select FSIJ serial number" >&2 echo "ERROR: Please set MAIL shell variable to select FSIJ serial number" >&2
exit 1 exit 1
fi fi
FSIJ_DEFINE="#define WITH_FSIJ_SERIAL_NUMBER 1" SERIAL=`sed -n -e "/^$MAIL/s/^.* \(..\):\(..\):\(..\):\(..\)/0x\1, 0x\2, 0x\3, 0x\4/p" ../FSIJ_SERIAL_NUMBER`
SERIAL_NUMBER_FOUR_BYTES=`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 fi
# --enable-debug option # --enable-debug option
@@ -193,7 +192,6 @@ sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
-e "s/@PINPAD_DEFINE@/$PINPAD_DEFINE/" \ -e "s/@PINPAD_DEFINE@/$PINPAD_DEFINE/" \
-e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \ -e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
-e "s/@DFU_DEFINE@/$DFU_DEFINE/" \ -e "s/@DFU_DEFINE@/$DFU_DEFINE/" \
-e "s/@FSIJ_DEFINE@/$FSIJ_DEFINE/" \ -e "s/@SERIAL_DEFINE@/$SERIAL_DEFINE/" \
-e "s/@SERIAL_NUMBER_FOUR_BYTES@/$SERIAL_NUMBER_FOUR_BYTES/" \
< config.h.in > config.h < config.h.in > config.h
exit 0 exit 0

View 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_scan (const uint8_t *p);
extern void gpg_data_copy (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_put_data (uint16_t tag, const uint8_t *data, int len);
extern void gpg_do_public_key (uint8_t kk_byte); 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); extern msg_t pin_main (void *arg);
#endif #endif
extern const uint8_t *unique_device_id (void);

View File

@@ -114,20 +114,10 @@ uint16_t data_objects_number_of_bytes;
/* /*
* Compile time vars: * Compile time vars:
* AID, Historical Bytes (template), Extended Capabilities, * Historical Bytes (template), Extended Capabilities,
* and Algorithm Attributes * 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) */ /* Historical Bytes (template) */
static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = { static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
10, 10,
@@ -412,6 +402,38 @@ do_kgtime_all (uint16_t tag, int with_tag)
return 1; 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 static int
do_ds_count (uint16_t tag, int with_tag) 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 }, { GPG_DO_KGTIME_ALL, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_kgtime_all },
/* Pseudo DO READ: calculated, not changeable by user */ /* Pseudo DO READ: calculated, not changeable by user */
{ GPG_DO_DS_COUNT, DO_PROC_READ, AC_ALWAYS, AC_NEVER, do_ds_count }, { 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 */ /* Pseudo DO READ/WRITE: calculated */
{ GPG_DO_PW_STATUS, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED, { GPG_DO_PW_STATUS, DO_PROC_READWRITE, AC_ALWAYS, AC_ADMIN_AUTHORIZED,
rw_pw_status }, rw_pw_status },
/* Fixed data */ /* 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_EXTCAP, DO_FIXED, AC_ALWAYS, AC_NEVER, extended_capabilities },
{ GPG_DO_ALG_SIG, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr }, { GPG_DO_ALG_SIG, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr },
{ GPG_DO_ALG_DEC, 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 * Call write_res_adpu to fill data returned
*/ */
void 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); 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 (do_p)
{ {
if (copy_do (do_p, 0) < 0) if (copy_do (do_p, with_tag) < 0)
/* Overwriting partially written result */ /* Overwriting partially written result */
GPG_SECURITY_FAILURE (); GPG_SECURITY_FAILURE ();
else else

View File

@@ -517,13 +517,8 @@ cmd_read_binary (void)
GPG_BAD_P0_P1 (); GPG_BAD_P0_P1 ();
else else
{ {
int len = openpgpcard_aid[0]; gpg_do_get_data (0x004f, 1); /* AID */
res_APDU[0] = 0x5a; 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 else
@@ -593,7 +588,7 @@ cmd_get_data (void)
if (file_selection != FILE_DF_OPENPGP) if (file_selection != FILE_DF_OPENPGP)
GPG_NO_RECORD(); GPG_NO_RECORD();
gpg_do_get_data (tag); gpg_do_get_data (tag, 0);
} }
static void static void

View File

@@ -220,13 +220,6 @@ static const uint8_t gnukStringProduct[] = {
' ', 0, 'T', 0, 'o', 0, 'k', 0, 'e', 0, 'n', 0 ' ', 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 = { const ONE_DESCRIPTOR Device_Descriptor = {
(uint8_t*)gnukDeviceDescriptor, (uint8_t*)gnukDeviceDescriptor,
sizeof (gnukDeviceDescriptor) sizeof (gnukDeviceDescriptor)
@@ -237,9 +230,8 @@ const ONE_DESCRIPTOR Config_Descriptor = {
sizeof (gnukConfigDescriptor) sizeof (gnukConfigDescriptor)
}; };
const ONE_DESCRIPTOR String_Descriptor[4] = { const ONE_DESCRIPTOR String_Descriptor[3] = {
{(uint8_t*)gnukStringLangID, sizeof (gnukStringLangID)}, {(uint8_t*)gnukStringLangID, sizeof (gnukStringLangID)},
{(uint8_t*)gnukStringVendor, sizeof (gnukStringVendor)}, {(uint8_t*)gnukStringVendor, sizeof (gnukStringVendor)},
{(uint8_t*)gnukStringProduct, sizeof (gnukStringProduct)}, {(uint8_t*)gnukStringProduct, sizeof (gnukStringProduct)},
{(uint8_t*)gnukStringSerial, sizeof (gnukStringSerial)},
}; };

View File

@@ -36,9 +36,34 @@
#include "usb-cdc-vport.c" #include "usb-cdc-vport.c"
#endif #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 static void
gnuk_device_init (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; pInformation->Current_Configuration = 0;
/* Connect the device */ /* Connect the device */
@@ -159,8 +184,18 @@ static uint8_t *
gnuk_device_GetStringDescriptor (uint16_t Length) gnuk_device_GetStringDescriptor (uint16_t Length)
{ {
uint8_t wValue0 = pInformation->USBwValue0; 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; return NULL;
else else
return Standard_GetDescriptorData (Length, return Standard_GetDescriptorData (Length,