fix key page release
This commit is contained in:
@@ -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>
|
2014-12-12 Niibe Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
* src/Makefile.in (build/bignum.o): Specific OPT for this target.
|
* src/Makefile.in (build/bignum.o): Specific OPT for this target.
|
||||||
|
|||||||
79
README
79
README
@@ -1,14 +1,14 @@
|
|||||||
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
Gnuk - An Implementation of USB Cryptographic Token for GnuPG
|
||||||
|
|
||||||
Version 1.1.3
|
Version 1.1.4
|
||||||
2014-04-16
|
2014-12-1x
|
||||||
Niibe Yutaka
|
Niibe Yutaka
|
||||||
Free Software Initiative of Japan
|
Free Software Initiative of Japan
|
||||||
|
|
||||||
Warning
|
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
|
incompatible changes to Gnuk 1.0.x. Specifically, it now supports
|
||||||
overriding key import, but importing keys (or generating keys) results
|
overriding key import, but importing keys (or generating keys) results
|
||||||
password reset. Please update your documentation for Gnuk Token, so
|
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
|
EdDSA, but this feature is pretty much experimental, and it requires
|
||||||
development version of GnuPG with newest version of libgcrypt. You
|
development version of GnuPG with newest version of libgcrypt. You
|
||||||
will not able to keep using EdDSA keys, as the key format is subject
|
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?
|
What's Gnuk?
|
||||||
@@ -57,8 +58,9 @@ A0: Good points of Gnuk are:
|
|||||||
"for Free Software"; Gnuk supports GnuPG.
|
"for Free Software"; Gnuk supports GnuPG.
|
||||||
|
|
||||||
Q1: What kind of key algorithm is supported?
|
Q1: What kind of key algorithm is supported?
|
||||||
A1: Gnuk version 1.0 only supports 2048-bit RSA.
|
A1: Gnuk version 1.0 only supports RSA 2048.
|
||||||
Development version of Gnuk (1.1.x) supports 256-bit ECDSA and EdDSA.
|
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?
|
Q2: How long does it take for digital signing?
|
||||||
A2: It takes a second and a half or so.
|
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?
|
Q7: How much does it cost?
|
||||||
A7: Olimex STM32-H103 plus ARM-USB-TINY-H cost 70 Euro or so.
|
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?
|
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
|
A9: GnuPG's SCDaemon has problems for handling insertion/removal of
|
||||||
card/reader. When your newly inserted token is not found by
|
card/reader. When your newly inserted token is not found by
|
||||||
GnuPG, try killing scdaemon and let it to be invoked again. I do:
|
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
|
$ 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:
|
Ab: That's because gnome-keyring-daemon interferes GnuPG. Type:
|
||||||
|
|
||||||
$ gnome-session-properties
|
$ 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
|
Ac: ST-Link/V2 is cheap one. We have a tool/stlinkv2.py as flash ROM
|
||||||
writer program.
|
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
|
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
|
While it is daily use by its developer, some newly introduced features
|
||||||
(including ECDSA/EdDSA, key generation and firmware upgrade) should be
|
(including ECDSA/EdDSA, key generation and firmware upgrade) should be
|
||||||
considered experimental. ECDSA/EdDSA is really experimental. The
|
considered experimental. ECDSA/EdDSA is really experimental.
|
||||||
feature even requires manual edit of Makefile after 'configure'.
|
Further, EdDSA is much experimental. You won't be able to keep using
|
||||||
More, 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.
|
||||||
the EdDSA key, as it is subject to change.
|
|
||||||
|
|
||||||
Tested features are:
|
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
|
disable read from flash. For real use, please consider killing DfuSe
|
||||||
and enabling read protection using JTAG debugger.
|
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
|
For PIN-pad support, I connect a consumer IR receive module to FST-01,
|
||||||
is supported by this configuration. Yes, it is not secure at all,
|
and use controller for TV. PIN verification is supported by this
|
||||||
since it is very easy to monitor IR output of the controllers. It is
|
configuration. Yes, it is not secure at all, since it is very easy to
|
||||||
just an experiment. Note that hardware needed for this experiment is
|
monitor IR output of the controllers. It is just an experiment. Note
|
||||||
only a consumer IR receive module which is as cheap as 50 JPY.
|
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
|
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.
|
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.
|
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.
|
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
|
Flying Stone Tiny 01
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
If you are using Flying Stone Tiny 01, you need a SWD writer. I am
|
If you are using Flying Stone Tiny 01, you need a SWD writer.
|
||||||
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
|
|
||||||
$
|
|
||||||
|
|
||||||
OpenOCD 0.6.1 now supports ST-Link/V2. We can use it:
|
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
|
$ git clone git://gitorious.org/gnuk/gnuk.git
|
||||||
|
|
||||||
It's also available at: www.gniibe.org
|
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:
|
I put Chopstx as a submodule of Git. Please do this:
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* call-rsa.c -- Glue code between RSA computation and OpenPGP card protocol
|
* 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>
|
* Author: NIIBE Yutaka <gniibe@fsij.org>
|
||||||
*
|
*
|
||||||
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
* This file is a part of Gnuk, a GnuPG USB Token implementation.
|
||||||
|
|||||||
@@ -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 <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "bn.h"
|
#include "bn.h"
|
||||||
|
|||||||
18
src/flash.c
18
src/flash.c
@@ -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 *
|
uint8_t *
|
||||||
flash_key_alloc (enum kind_of_key kk)
|
flash_key_alloc (enum kind_of_key kk)
|
||||||
{
|
{
|
||||||
uint8_t *k0, *k;
|
uint8_t *k, *k0 = flash_key_getpage (kk);
|
||||||
int i;
|
int i;
|
||||||
int key_size = gpg_get_algo_attr_key_size (kk, GPG_KEY_STORAGE);
|
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. */
|
/* Seek free space in the page. */
|
||||||
for (k = k0; k < k0 + FLASH_PAGE_SIZE; k += key_size)
|
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);
|
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
|
void
|
||||||
flash_clear_halfword (uint32_t addr)
|
flash_clear_halfword (uint32_t addr)
|
||||||
|
|||||||
@@ -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);
|
const uint8_t *flash_do_write (uint8_t nr, const uint8_t *data, int len);
|
||||||
uint8_t *flash_key_alloc (enum kind_of_key);
|
uint8_t *flash_key_alloc (enum kind_of_key);
|
||||||
void flash_key_release (uint8_t *, int);
|
void flash_key_release (uint8_t *, int);
|
||||||
|
void flash_key_release_page (enum kind_of_key);
|
||||||
int flash_key_write (uint8_t *key_addr,
|
int flash_key_write (uint8_t *key_addr,
|
||||||
const uint8_t *key_data, int key_data_len,
|
const uint8_t *key_data, int key_data_len,
|
||||||
const uint8_t *pubkey, int pubkey_len);
|
const uint8_t *pubkey, int pubkey_len);
|
||||||
|
|||||||
@@ -36,6 +36,11 @@
|
|||||||
#include "polarssl/aes.h"
|
#include "polarssl/aes.h"
|
||||||
#include "sha512.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 */
|
#define PASSWORD_ERRORS_MAX 3 /* >= errors, it will be locked */
|
||||||
static const uint8_t *pw_err_counter_p[3];
|
static const uint8_t *pw_err_counter_p[3];
|
||||||
@@ -458,8 +463,15 @@ copy_tag (uint16_t tag)
|
|||||||
static int
|
static int
|
||||||
do_hist_bytes (uint16_t tag, int with_tag)
|
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);
|
copy_do_1 (tag, historical_bytes, with_tag);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -717,17 +729,15 @@ rw_algorithm_attr (uint16_t tag, int with_tag,
|
|||||||
return 0; /* Error */
|
return 0; /* Error */
|
||||||
else if (algo == ALGO_RSA2K && *algo_attr_pp != NULL)
|
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);
|
flash_enum_clear (algo_attr_pp);
|
||||||
if (*algo_attr_pp != NULL)
|
if (*algo_attr_pp != NULL)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (*algo_attr_pp == NULL || (*algo_attr_pp)[1] != algo)
|
else if (*algo_attr_pp == NULL || (*algo_attr_pp)[1] != algo)
|
||||||
{
|
{
|
||||||
int nr = kk_to_nr (kk);
|
gpg_do_delete_prvkey (kk, CLEAN_PAGE_FULL);
|
||||||
|
*algo_attr_pp = flash_enum_write (kk_to_nr (kk), algo);
|
||||||
// xxx: make sure there is no key registered
|
|
||||||
*algo_attr_pp = flash_enum_write (nr, algo);
|
|
||||||
if (*algo_attr_pp == NULL)
|
if (*algo_attr_pp == NULL)
|
||||||
return 0;
|
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 int8_t num_prv_keys;
|
||||||
|
|
||||||
static void
|
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);
|
uint8_t nr = get_do_ptr_nr_for_kk (kk);
|
||||||
const uint8_t *do_data = do_ptr[nr];
|
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);
|
int key_size = gpg_get_algo_attr_key_size (kk, GPG_KEY_STORAGE);
|
||||||
|
|
||||||
if (do_data == NULL)
|
if (do_data == NULL)
|
||||||
|
{
|
||||||
|
if (clean_page_full)
|
||||||
|
flash_key_release_page (kk);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
do_ptr[nr] = NULL;
|
do_ptr[nr] = NULL;
|
||||||
flash_do_release (do_data);
|
flash_do_release (do_data);
|
||||||
key_addr = (uint8_t *)kd[kk].pubkey - prvkey_len;
|
key_addr = (uint8_t *)kd[kk].pubkey - prvkey_len;
|
||||||
kd[kk].pubkey = NULL;
|
kd[kk].pubkey = NULL;
|
||||||
|
if (clean_page_full)
|
||||||
|
flash_key_release_page (kk);
|
||||||
|
else
|
||||||
flash_key_release (key_addr, key_size);
|
flash_key_release (key_addr, key_size);
|
||||||
|
|
||||||
if (admin_authorized == BY_ADMIN && kk == GPG_KEY_FOR_SIGNING)
|
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);
|
DEBUG_SHORT (prvkey_len);
|
||||||
|
|
||||||
/* Delete it first, if any. */
|
/* 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));
|
pd = (struct prvkey_data *)malloc (sizeof (struct prvkey_data));
|
||||||
if (pd == NULL)
|
if (pd == NULL)
|
||||||
@@ -1314,7 +1331,7 @@ proc_key_import (const uint8_t *data, int len)
|
|||||||
|| attr == ALGO_ED25519))
|
|| attr == ALGO_ED25519))
|
||||||
|| (len <= 22 && attr == ALGO_RSA2K) || (len <= 24 && attr == ALGO_RSA4K))
|
|| (len <= 22 && attr == ALGO_RSA2K) || (len <= 24 && attr == ALGO_RSA4K))
|
||||||
{ /* Deletion of the key */
|
{ /* Deletion of the key */
|
||||||
gpg_do_delete_prvkey (kk);
|
gpg_do_delete_prvkey (kk, CLEAN_SINGLE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user