fix key page release

This commit is contained in:
NIIBE Yutaka
2014-12-13 21:57:38 +09:00
parent 3cca2798b0
commit d6e70ab0f4
7 changed files with 90 additions and 65 deletions

View File

@@ -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.

79
README
View File

@@ -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:

View 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.

View File

@@ -21,6 +21,12 @@
*
*/
/*
* 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"

View 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)

View 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);

View File

@@ -36,6 +36,11 @@
#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,12 +966,19 @@ 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)
{
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;
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)
@@ -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;
}