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,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,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;
}