fix key page release
authorNIIBE Yutaka <gniibe@fsij.org>
Sat, 13 Dec 2014 12:57:38 +0000 (21:57 +0900)
committerNIIBE Yutaka <gniibe@fsij.org>
Mon, 15 Dec 2014 03:12:54 +0000 (12:12 +0900)
ChangeLog
README
src/call-rsa.c
src/ec_p256k1.c
src/flash.c
src/gnuk.h
src/openpgp-do.c

index 307473c..6963438 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2014-12-13  Niibe Yutaka  <gniibe@fsij.org>
+
+       * src/flash.c (flash_key_getpage, flash_key_release_page): New.
+
+       * src/openpgp-do.c (gpg_do_delete_prvkey): New arg.
+       (rw_algorithm_attr): Call gpg_do_delete_prvkey with CLEAN_PAGE_FULL.
+
 2014-12-12  Niibe Yutaka  <gniibe@fsij.org>
 
        * src/Makefile.in (build/bignum.o): Specific OPT for this target.
diff --git a/README b/README
index f0d2bbe..30e5d99 100644 (file)
--- a/README
+++ b/README
@@ -1,14 +1,14 @@
 Gnuk - An Implementation of USB Cryptographic Token for GnuPG
 
-                                                         Version 1.1.3
-                                                            2014-04-16
+                                                         Version 1.1.4
+                                                            2014-12-1x
                                                           Niibe Yutaka
                                      Free Software Initiative of Japan
 
 Warning
 =======
 
-This is another experimental release of Gnuk, version 1.1.3, which has
+This is another experimental release of Gnuk, version 1.1.4, which has
 incompatible changes to Gnuk 1.0.x.  Specifically, it now supports
 overriding key import, but importing keys (or generating keys) results
 password reset.  Please update your documentation for Gnuk Token, so
@@ -17,7 +17,8 @@ has supports of ECDSA (with NIST P256 and secp256k1) and EdDSA with
 EdDSA, but this feature is pretty much experimental, and it requires
 development version of GnuPG with newest version of libgcrypt.  You
 will not able to keep using EdDSA keys, as the key format is subject
-to change.
+to change.  It also support RSA-4096 experimentally, but users should
+know that it takes more than 8 second to sign/decrypt.
 
 
 What's Gnuk?
@@ -57,8 +58,9 @@ A0: Good points of Gnuk are:
            "for Free Software"; Gnuk supports GnuPG.
 
 Q1: What kind of key algorithm is supported?
-A1: Gnuk version 1.0 only supports 2048-bit RSA.
-    Development version of Gnuk (1.1.x) supports 256-bit ECDSA and EdDSA.
+A1: Gnuk version 1.0 only supports RSA 2048.
+    Development version of Gnuk (1.1.x) supports 256-bit ECDSA and EdDSA,
+    as well as RSA 4096-bit.  But it takes long time to sign with RSA 4096.
 
 Q2: How long does it take for digital signing?
 A2: It takes a second and a half or so. 
@@ -87,13 +89,7 @@ A6: You need a target board plus a JTAG/SWD debugger.  If you just
 Q7: How much does it cost?
 A7: Olimex STM32-H103 plus ARM-USB-TINY-H cost 70 Euro or so.
 
-Q8: How much does it cost for DIY version?
-A8: STM8S Discovery Kit costs 750 JPY (< $10 USD) only.  You can build
-    your own JTAG debugger using FTDI2232 module (1450 JPY), see:
-    http://www.fsij.org/gnuk/jtag_dongle_ftdi2232
-
 Q9: I got an error like "gpg: selecting openpgp failed: ec=6.108", what's up?
-
 A9: GnuPG's SCDaemon has problems for handling insertion/removal of
     card/reader.  When your newly inserted token is not found by
     GnuPG, try killing scdaemon and let it to be invoked again.  I do:
@@ -110,7 +106,7 @@ Aa: You need to deactivate seahorse-agent and gnome-keyring, but use
 
       $ gconftool-2 --type bool --set /apps/gnome-keyring/daemon-components/ssh false
 
-Qb: With GNOME 3, I can't use Gnuk Token at all.  Why?
+Qb: With GNOME 3.0, I can't use Gnuk Token at all.  Why?
 Ab: That's because gnome-keyring-daemon interferes GnuPG.  Type:
 
       $ gnome-session-properties
@@ -122,6 +118,16 @@ Qc: Do you know a good SWD debugger to connect FST-01 or something?
 Ac: ST-Link/V2 is cheap one.  We have a tool/stlinkv2.py as flash ROM
     writer program.
 
+Qd: With GNOME 3.x (x >= 8?), I can't use Gnuk Token at all.  Why?
+Ad: Please set the configration variable OnlyShowIn as none.  Like:
+
+       OnlyShowIn=
+
+    In the files of /etc/xdg/autostart/gnome-keyring-gpg.desktop and
+                    /etc/xdg/autostart/gnome-keyring-ssh.desktop
+
+
+
 
 Release notes
 =============
@@ -130,10 +136,9 @@ This is third experimental release in version 1.1 series of Gnuk.
 
 While it is daily use by its developer, some newly introduced features
 (including ECDSA/EdDSA, key generation and firmware upgrade) should be
-considered experimental.  ECDSA/EdDSA is really experimental.  The
-feature even requires manual edit of Makefile after 'configure'.
-More, EdDSA is much experimental.  You won't be able to keep using
-the EdDSA key, as it is subject to change.
+considered experimental.  ECDSA/EdDSA is really experimental.
+Further, EdDSA is much experimental.  You won't be able to keep using
+the EdDSA key, as the key format of GnuPG is subject to change.
 
 Tested features are:
 
@@ -181,11 +186,12 @@ DfuSe is for experiment only, because it is impossible for DfuSe to
 disable read from flash.  For real use, please consider killing DfuSe
 and enabling read protection using JTAG debugger.
 
-For PIN-pad support, I connect a consumer IR receive module to FST-01, and use controller for TV.  PIN verification
-is supported by this configuration.  Yes, it is not secure at all,
-since it is very easy to monitor IR output of the controllers.  It is
-just an experiment.  Note that hardware needed for this experiment is
-only a consumer IR receive module which is as cheap as 50 JPY.
+For PIN-pad support, I connect a consumer IR receive module to FST-01,
+and use controller for TV.  PIN verification is supported by this
+configuration.  Yes, it is not secure at all, since it is very easy to
+monitor IR output of the controllers.  It is just an experiment.  Note
+that hardware needed for this experiment is only a consumer IR receive
+module which is as cheap as 50 JPY.
 
 Note that you need pinpad support for GnuPG to use PIN-pad enabled
 Gnuk.  The pinpad support for GnuPG is only available in version 2.
@@ -223,7 +229,7 @@ External source code
 
 Gnuk is distributed with external source code.
 
-* chopstx/  -- Chopstx 0.03 (+ STBee support)
+* chopstx/  -- Chopstx 0.04
 
   We use Chopstx as the kernel for Gnuk.
 
@@ -380,30 +386,7 @@ Then, with another terminal, type following to write "gnuk.elf" to Flash ROM:
 Flying Stone Tiny 01
 --------------------
 
-If you are using Flying Stone Tiny 01, you need a SWD writer.  I am
-using revision 946 of Simon Qian's Versaloon.
-
-    svn checkout -r 946 http://vsprog.googlecode.com/svn/trunk/
-
-For OpenOCD, we need unofficial patch.
-
-See the article of Versaloon Forum:
-
-    http://www.versaloon.com/bbs/viewtopic.php?p=16179
-
-
-Type following to invoke OpenOCD:
-
-  $ openocd -f interface/vsllink.cfg -c "transport select swd" -c "swd_mode 2" -f target/stm32f1x.cfg
-
-Then, with another terminal, type following to write "gnuk.elf" to Flash ROM:
-
-  $ telnet localhost 4444
-  > reset halt
-  > flash write_image erase gnuk.elf
-  > reset
-  > exit
-  $ 
+If you are using Flying Stone Tiny 01, you need a SWD writer.
 
 OpenOCD 0.6.1 now supports ST-Link/V2.  We can use it:
 
@@ -568,7 +551,7 @@ You can get it by:
     $ git clone git://gitorious.org/gnuk/gnuk.git
 
 It's also available at: www.gniibe.org
-You can browse at: http://www.gniibe.org/gitweb?p=gnuk.git;a=summary
+You can browse at: http://git.gniibe.org/gitweb?p=gnuk/gnuk.git;a=summary
 
 I put Chopstx as a submodule of Git.  Please do this:
 
index 3f2e0a8..c494156 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * call-rsa.c -- Glue code between RSA computation and OpenPGP card protocol
  *
- * Copyright (C) 2010, 2011, 2012, 2013 Free Software Initiative of Japan
+ * Copyright (C) 2010, 2011, 2012, 2013, 2014
+ *               Free Software Initiative of Japan
  * Author: NIIBE Yutaka <gniibe@fsij.org>
  *
  * This file is a part of Gnuk, a GnuPG USB Token implementation.
index fe82a49..c97d3c8 100644 (file)
  *
  */
 
+/*
+ * Note: we don't take advantage of the specific feature of this curve,
+ * but use same method of computation as NIST P-256 curve.  That's due
+ * to some software patent(s).
+ */
+
 #include <stdint.h>
 #include <string.h>
 #include "bn.h"
index d5ab832..683f34a 100644 (file)
@@ -318,16 +318,20 @@ flash_do_release (const uint8_t *do_data)
 }
 
 
+static uint8_t *
+flash_key_getpage (enum kind_of_key kk)
+{
+  /* There is a page for each KK.  */
+  return &_keystore_pool + (FLASH_PAGE_SIZE * kk);
+}
+
 uint8_t *
 flash_key_alloc (enum kind_of_key kk)
 {
-  uint8_t *k0, *k;
+  uint8_t *k, *k0 = flash_key_getpage (kk);
   int i; 
   int key_size = gpg_get_algo_attr_key_size (kk, GPG_KEY_STORAGE);
 
-  /* There is a page for each KK.  */
-  k0 = &_keystore_pool + (FLASH_PAGE_SIZE * kk);
-
   /* Seek free space in the page.  */
   for (k = k0; k < k0 + FLASH_PAGE_SIZE; k += key_size)
     {
@@ -412,6 +416,12 @@ flash_key_release (uint8_t *key_addr, int key_size)
     flash_key_fill_zero_as_released (key_addr, key_size);
 }
 
+void
+flash_key_release_page (enum kind_of_key kk)
+{
+  flash_erase_page ((uint32_t)flash_key_getpage (kk));
+}
+
 
 void
 flash_clear_halfword (uint32_t addr)
index 88b526b..63b4a76 100644 (file)
@@ -137,6 +137,7 @@ void flash_do_release (const uint8_t *);
 const uint8_t *flash_do_write (uint8_t nr, const uint8_t *data, int len);
 uint8_t *flash_key_alloc (enum kind_of_key);
 void flash_key_release (uint8_t *, int);
+void flash_key_release_page (enum kind_of_key);
 int flash_key_write (uint8_t *key_addr,
                     const uint8_t *key_data, int key_data_len,
                     const uint8_t *pubkey, int pubkey_len);
index 7cf4de4..6d91b69 100644 (file)
 #include "polarssl/aes.h"
 #include "sha512.h"
 
+/* Forward declaration */
+#define CLEAN_PAGE_FULL 1
+#define CLEAN_SINGLE    0
+static void gpg_do_delete_prvkey (enum kind_of_key kk, int clean_page_full);
+
 
 #define PASSWORD_ERRORS_MAX 3  /* >= errors, it will be locked */
 static const uint8_t *pw_err_counter_p[3];
@@ -458,8 +463,15 @@ copy_tag (uint16_t tag)
 static int
 do_hist_bytes (uint16_t tag, int with_tag)
 {
-  /* XXX: For now, no life cycle management, just return template as is. */
-  /* XXX: Supporing TERMINATE DF / ACTIVATE FILE, we need to fix here */
+  /*
+   * Currently, we support no life cycle management.
+   * In case of Gnuk, user could flash the MCU, instead.
+   * Thus, just return the template as is.
+   *
+   * In future (when Gnuk will be onn the real smartcard),
+   * we can support life cycle management by implementing
+   * TERMINATE DF / ACTIVATE FILE and fix code around here.
+   */
   copy_do_1 (tag, historical_bytes, with_tag);
   return 1;
 }
@@ -717,17 +729,15 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
        return 0;               /* Error */
       else if (algo == ALGO_RSA2K && *algo_attr_pp != NULL)
        {
-         // xxx: make sure there is no key registered
+         gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
          flash_enum_clear (algo_attr_pp);
          if (*algo_attr_pp != NULL)
            return 0;
        }
       else if (*algo_attr_pp == NULL || (*algo_attr_pp)[1] != algo)
        {
-         int nr = kk_to_nr (kk);
-
-         // xxx: make sure there is no key registered
-         *algo_attr_pp = flash_enum_write (nr, algo);
+         gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
+         *algo_attr_pp = flash_enum_write (kk_to_nr (kk), algo);
          if (*algo_attr_pp == NULL)
            return 0;
        }
@@ -947,7 +957,7 @@ gpg_do_load_prvkey (enum kind_of_key kk, int who, const uint8_t *keystring)
 static int8_t num_prv_keys;
 
 static void
-gpg_do_delete_prvkey (enum kind_of_key kk)
+gpg_do_delete_prvkey (enum kind_of_key kk, int clean_page_full)
 {
   uint8_t nr = get_do_ptr_nr_for_kk (kk);
   const uint8_t *do_data = do_ptr[nr];
@@ -956,13 +966,20 @@ gpg_do_delete_prvkey (enum kind_of_key kk)
   int key_size = gpg_get_algo_attr_key_size (kk, GPG_KEY_STORAGE);
 
   if (do_data == NULL)
-    return;
+    {
+      if (clean_page_full)
+       flash_key_release_page (kk);
+      return;
+    }
 
   do_ptr[nr] = NULL;
   flash_do_release (do_data);
   key_addr = (uint8_t *)kd[kk].pubkey - prvkey_len;
   kd[kk].pubkey = NULL;
-  flash_key_release (key_addr, key_size);
+  if (clean_page_full)
+    flash_key_release_page (kk);
+  else
+    flash_key_release (key_addr, key_size);
 
   if (admin_authorized == BY_ADMIN && kk == GPG_KEY_FOR_SIGNING)
     {                  /* Recover admin keystring DO.  */
@@ -1014,7 +1031,7 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data,
   DEBUG_SHORT (prvkey_len);
 
   /* Delete it first, if any.  */
-  gpg_do_delete_prvkey (kk);
+  gpg_do_delete_prvkey (kk, CLEAN_SINGLE);
 
   pd = (struct prvkey_data *)malloc (sizeof (struct prvkey_data));
   if (pd == NULL)
@@ -1314,7 +1331,7 @@ proc_key_import (const uint8_t *data, int len)
                     || attr == ALGO_ED25519))
       || (len <= 22 && attr == ALGO_RSA2K) || (len <= 24 && attr == ALGO_RSA4K))
     {                                      /* Deletion of the key */
-      gpg_do_delete_prvkey (kk);
+      gpg_do_delete_prvkey (kk, CLEAN_SINGLE);
       return 1;
     }