diff --git a/ChangeLog b/ChangeLog index 3177963..103f91a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2016-10-13 Niibe Yutaka + + * tests: New test suite for OpenPGP card with PyTest. + + * src/configure (factory_reset): New. + + * src/usb-ccid.c (ccid_power_on): Use ATR_head and historical + bytes. + + * src/openpgp-do.c (rw_algorithm_attr): Clear fingerprint, timestamp, + and possibly ds_counter. + 2016-10-12 Niibe Yutaka * test/features/steps.py (cmd_reset_retry_counter): Fix. diff --git a/src/config.h.in b/src/config.h.in index 923ab41..5723167 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -8,3 +8,4 @@ @CERTDO_DEFINE@ @HID_CARD_CHANGE_DEFINE@ @SERIALNO_STR_LEN_DEFINE@ +@LIFE_CYCLE_MANAGEMENT_DEFINE@ diff --git a/src/configure b/src/configure index 765df6e..a4eda6b 100755 --- a/src/configure +++ b/src/configure @@ -43,6 +43,7 @@ sys1_compat=yes pinpad=no certdo=no hid_card_change=no +factory_reset=no # Revision number if test -e ../.git; then @@ -87,6 +88,10 @@ for option; do sys1_compat=yes ;; --disable-sys1-compat) sys1_compat=no ;; + --enable-factory-reset) + factory_reset=yes ;; + --disable-factory-reset) + factory_reset=no ;; --with-dfu) with_dfu=yes ;; --without-dfu) @@ -131,6 +136,8 @@ Configuration: --disable-sys1-compat disable SYS 1.0 compatibility [no] executable is target independent but requires SYS 2.0 or newer + --enable-factory-reset + support life cycle management [no] --with-dfu build image for DFU [] EOF exit 0 @@ -248,6 +255,15 @@ else echo "Card insert/removal by HID device is NOT supported" fi +# --enable-factory-reset option +if test "$factory_reset" = "yes"; then + LIFE_CYCLE_MANAGEMENT_DEFINE="#define LIFE_CYCLE_MANAGEMENT_SUPPORT 1" + echo "Life cycle management is supported" +else + LIFE_CYCLE_MANAGEMENT_DEFINE="#undef LIFE_CYCLE_MANAGEMENT_SUPPORT" + echo "Life cycle management is NOT supported" +fi + ### !!! Replace following string of "FSIJ" to yours !!! #### SERIALNO="FSIJ-`cat ../VERSION | sed -e 's%^[^/]*/%%'`-" @@ -375,6 +391,7 @@ sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \ -e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \ -e "s/@CERTDO_DEFINE@/$CERTDO_DEFINE/" \ -e "s/@HID_CARD_CHANGE_DEFINE@/$HID_CARD_CHANGE_DEFINE/" \ + -e "s/@LIFE_CYCLE_MANAGEMENT_DEFINE@/$LIFE_CYCLE_MANAGEMENT_DEFINE/" \ -e "s/@SERIALNO_STR_LEN_DEFINE@/$SERIALNO_STR_LEN_DEFINE/" \ < config.h.in > config.h exit 0 diff --git a/src/gnuk.h b/src/gnuk.h index 055310c..b74e03f 100644 --- a/src/gnuk.h +++ b/src/gnuk.h @@ -100,6 +100,7 @@ void ac_fini (void); void set_res_sw (uint8_t sw1, uint8_t sw2); +extern const uint8_t historical_bytes[]; extern uint16_t data_objects_number_of_bytes; #define CHALLENGE_LEN 32 diff --git a/src/openpgp-do.c b/src/openpgp-do.c index dcaec7e..71b613d 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -1,7 +1,7 @@ /* * openpgp-do.c -- OpenPGP card Data Objects (DO) handling * - * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015 + * Copyright (C) 2010, 2011, 2012, 2013, 2014, 2015, 2016 * Free Software Initiative of Japan * Author: NIIBE Yutaka * @@ -94,7 +94,7 @@ uint16_t data_objects_number_of_bytes; */ /* Historical Bytes (template) */ -static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = { +const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = { 10, 0x00, 0x31, 0x84, /* Full DF name, GET DATA, MF */ @@ -763,6 +763,22 @@ rw_algorithm_attr (uint16_t tag, int with_tag, { gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL); flash_enum_clear (algo_attr_pp); + if (kk == GPG_KEY_FOR_SIGNING) + { + gpg_reset_digital_signature_counter (); + gpg_do_write_simple (NR_DO_FP_SIG, NULL, 0); + gpg_do_write_simple (NR_DO_KGTIME_SIG, NULL, 0); + } + else if (kk == GPG_KEY_FOR_DECRYPTION) + { + gpg_do_write_simple (NR_DO_FP_DEC, NULL, 0); + gpg_do_write_simple (NR_DO_KGTIME_DEC, NULL, 0); + } + else + { + gpg_do_write_simple (NR_DO_FP_AUT, NULL, 0); + gpg_do_write_simple (NR_DO_KGTIME_AUT, NULL, 0); + } if (*algo_attr_pp != NULL) return 0; } @@ -770,6 +786,22 @@ rw_algorithm_attr (uint16_t tag, int with_tag, || (*algo_attr_pp)[1] != algo) { gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL); + if (kk == GPG_KEY_FOR_SIGNING) + { + gpg_reset_digital_signature_counter (); + gpg_do_write_simple (NR_DO_FP_SIG, NULL, 0); + gpg_do_write_simple (NR_DO_KGTIME_SIG, NULL, 0); + } + else if (kk == GPG_KEY_FOR_DECRYPTION) + { + gpg_do_write_simple (NR_DO_FP_DEC, NULL, 0); + gpg_do_write_simple (NR_DO_KGTIME_DEC, NULL, 0); + } + else + { + gpg_do_write_simple (NR_DO_FP_AUT, NULL, 0); + gpg_do_write_simple (NR_DO_KGTIME_AUT, NULL, 0); + } *algo_attr_pp = flash_enum_write (kk_to_nr (kk), algo); if (*algo_attr_pp == NULL) return 0; diff --git a/src/usb-ccid.c b/src/usb-ccid.c index 1222381..736d4ee 100644 --- a/src/usb-ccid.c +++ b/src/usb-ccid.c @@ -720,24 +720,12 @@ usb_tx_done (uint8_t ep_num, uint16_t len) * TB3 = 0x55: BWI = 5, CWI = 5 (BWT timeout 3.2 sec) * TD3 = 0x1f: TA4 follows, T=15 * TA4 = 0x03: 5V or 3.3V - * Historical bytes: to be explained... - * XOR check * - * Minimum: 0x3b, 0x8a, 0x80, 0x01, + historical bytes, xor check + * Minimum: 0x3b, 0x8a, 0x80, 0x01 * */ -static const uint8_t ATR[] = { +static const uint8_t ATR_head[] = { 0x3b, 0xda, 0x11, 0xff, 0x81, 0xb1, 0xfe, 0x55, 0x1f, 0x03, - 0x00, - 0x31, 0x84, /* full DF name, GET DATA, MF */ - 0x73, - 0x80, /* DF full name */ - 0x01, /* 1-byte */ - 0x80, /* Command chaining, No extended Lc and extended Le */ - 0x00, - 0x90, 0x00, - (0xda^0x11^0xff^0x81^0xb1^0xfe^0x55^0x1f^0x03 - ^0x00^0x31^0x84^0x73^0x80^0x01^0x80^0x00^0x90^0x00) }; /* @@ -783,8 +771,10 @@ extern uint8_t __process3_stack_base__[], __process3_stack_size__[]; static enum ccid_state ccid_power_on (struct ccid *c) { - size_t size_atr = sizeof (ATR); - uint8_t p[CCID_MSG_HEADER_SIZE]; + size_t size_atr = sizeof (ATR_head) + historical_bytes[0] + 1; + uint8_t p[CCID_MSG_HEADER_SIZE+size_atr]; + uint8_t xor_check = 0; + int i; if (c->application == 0) c->application = chopstx_create (PRIO_GPG, STACK_ADDR_GPG, @@ -802,8 +792,14 @@ ccid_power_on (struct ccid *c) p[CCID_MSG_ERROR_OFFSET] = 0x00; p[CCID_MSG_CHAIN_OFFSET] = 0x00; - usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE); - usb_lld_txcpy (ATR, c->epi->ep_num, CCID_MSG_HEADER_SIZE, size_atr); + memcpy (p + CCID_MSG_HEADER_SIZE, ATR_head, sizeof (ATR_head)); + memcpy (p + CCID_MSG_HEADER_SIZE + sizeof (ATR_head), + historical_bytes + 1, historical_bytes[0]); + for (i = 1; i < (int)size_atr - 1; i++) + xor_check ^= p[CCID_MSG_HEADER_SIZE + i]; + p[CCID_MSG_HEADER_SIZE+size_atr-1] = xor_check; + + usb_lld_txcpy (p, c->epi->ep_num, 0, CCID_MSG_HEADER_SIZE + size_atr); /* This is a single packet Bulk-IN transaction */ c->epi->buf = NULL; diff --git a/tests/README b/tests/README index e51c643..8aefe70 100644 --- a/tests/README +++ b/tests/README @@ -1,5 +1,9 @@ Here is a test suite for OpenPGP card. +For now, only TPDU card reader is supported for OpenPGP card. +Gnuk Token is supported as well. + + You need to install: $ sudo apt-get install python3-pytest python3-usb