Implement GC for data pool in flash memory.
This commit is contained in:
21
ChangeLog
21
ChangeLog
@@ -1,10 +1,27 @@
|
|||||||
2010-11-08 NIIBE Yutaka <gniibe@fsij.org>
|
2010-11-08 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
|
Implement GC for data pool in flash memory.
|
||||||
|
* src/openpgp-do.c (gpg_write_digital_signature_counter): New.
|
||||||
|
(gpg_increment_digital_signature_counter): Fix for GC.
|
||||||
|
(gpg_data_scan): Rename from gpg_do_table_init.
|
||||||
|
(gpg_data_copy): New function for copying GC.
|
||||||
|
* src/main.c (main): Call gpg_data_scan with the address which
|
||||||
|
flash_init returns.
|
||||||
|
* src/flash.c (flash_erase_page): New function.
|
||||||
|
(FLASH_DATA_POOL_SIZE): data_pool is 2KiB now.
|
||||||
|
(flash_data): Put a header (GC generation).
|
||||||
|
(flash_init): Implement choosing a data pool page.
|
||||||
|
(flash_data_pool): Removed.
|
||||||
|
(flash_copying_gc): New function.
|
||||||
|
(flash_data_pool_allocate): Call flash_copying_gc when full.
|
||||||
|
(flash_do_write_internal, flash_put_data_internal)
|
||||||
|
(flash_bool_write_internal, flash_cnt123_write_internal): New
|
||||||
|
* src/gnuk.ld.in (gnuk_flash): data_pool is 2KiB now.
|
||||||
|
|
||||||
|
Bug fixes.
|
||||||
* src/openpgp.c (cmd_change_password, cmd_reset_user_password):
|
* src/openpgp.c (cmd_change_password, cmd_reset_user_password):
|
||||||
Write to APDU correctly.
|
Write to APDU correctly.
|
||||||
|
|
||||||
* src/flash.c (flash_warning): Make it public.
|
* src/flash.c (flash_warning): Make it public.
|
||||||
|
|
||||||
* src/openpgp-do.c (do_hist_bytes, do_fp_all, do_cafp_all)
|
* src/openpgp-do.c (do_hist_bytes, do_fp_all, do_cafp_all)
|
||||||
(do_kgtime_all, do_ds_count): Fix return value.
|
(do_kgtime_all, do_ds_count): Fix return value.
|
||||||
(rw_pw_status): Correctly return value.
|
(rw_pw_status): Correctly return value.
|
||||||
|
|||||||
193
src/flash.c
193
src/flash.c
@@ -29,11 +29,6 @@
|
|||||||
* be implemented by its own flash page.
|
* be implemented by its own flash page.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
* Note: Garbage collection and page management with flash erase
|
|
||||||
* is *NOT YET* implemented
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
@@ -90,7 +85,8 @@ flash_wait_for_last_operation (uint32_t timeout)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FLASH_PROGRAM_TIMEOUT 0x10000
|
#define FLASH_PROGRAM_TIMEOUT 0x00010000
|
||||||
|
#define FLASH_ERASE_TIMEOUT 0x01000000
|
||||||
|
|
||||||
static int
|
static int
|
||||||
flash_program_halfword (uint32_t addr, uint16_t data)
|
flash_program_halfword (uint32_t addr, uint16_t data)
|
||||||
@@ -115,6 +111,29 @@ flash_program_halfword (uint32_t addr, uint16_t data)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
flash_erase_page (uint32_t addr)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
||||||
|
|
||||||
|
chSysLock ();
|
||||||
|
if (status == FLASH_COMPLETE)
|
||||||
|
{
|
||||||
|
FLASH->CR |= FLASH_CR_PER;
|
||||||
|
FLASH->AR = addr;
|
||||||
|
FLASH->CR |= FLASH_CR_STRT;
|
||||||
|
|
||||||
|
status = flash_wait_for_last_operation (FLASH_ERASE_TIMEOUT);
|
||||||
|
if (status != FLASH_TIMEOUT)
|
||||||
|
FLASH->CR &= ~FLASH_CR_PER;
|
||||||
|
}
|
||||||
|
chSysUnlock ()
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flash memory map
|
* Flash memory map
|
||||||
*
|
*
|
||||||
@@ -129,10 +148,13 @@ flash_program_halfword (uint32_t addr, uint16_t data)
|
|||||||
*
|
*
|
||||||
* 1-KiB align padding
|
* 1-KiB align padding
|
||||||
*
|
*
|
||||||
* 1-KiB data pool * 3
|
* 1-KiB data pool * 2
|
||||||
*
|
*
|
||||||
* 3-KiB Key store (512-byte (p, q and N) key-store * 6)
|
* 3-KiB Key store (512-byte (p, q and N) key-store * 6)
|
||||||
*/
|
*/
|
||||||
|
#define FLASH_DATA_POOL_HEADER_SIZE 2
|
||||||
|
#define FLASH_DATA_POOL_SIZE (1024*2)
|
||||||
|
#define FLASH_PAGE_SIZE 1024
|
||||||
|
|
||||||
static const uint8_t *data_pool;
|
static const uint8_t *data_pool;
|
||||||
static const uint8_t *keystore_pool;
|
static const uint8_t *keystore_pool;
|
||||||
@@ -140,20 +162,35 @@ static const uint8_t *keystore_pool;
|
|||||||
static uint8_t *last_p;
|
static uint8_t *last_p;
|
||||||
static const uint8_t *keystore;
|
static const uint8_t *keystore;
|
||||||
|
|
||||||
|
/* The first halfward is generation for the data page (little endian) */
|
||||||
const uint8_t const flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
|
const uint8_t const flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
|
||||||
0xff, 0xff, 0xff, 0xff
|
0x01, 0x00, 0xff, 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Linker set this symbol */
|
/* Linker set this symbol */
|
||||||
extern uint8_t _data_pool;
|
extern uint8_t _data_pool;
|
||||||
|
|
||||||
void
|
const uint8_t *
|
||||||
flash_init (void)
|
flash_init (void)
|
||||||
{
|
{
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
extern uint8_t _keystore_pool;
|
extern uint8_t _keystore_pool;
|
||||||
|
uint16_t gen0, gen1;
|
||||||
|
uint16_t *gen0_p = (uint16_t *)&_data_pool;
|
||||||
|
uint16_t *gen1_p = (uint16_t *)(&_data_pool + FLASH_PAGE_SIZE);
|
||||||
|
|
||||||
|
/* Check data pool generation and choose the page */
|
||||||
|
gen0 = *gen0_p;
|
||||||
|
gen1 = *gen1_p;
|
||||||
|
if (gen0 == 0xffff)
|
||||||
|
data_pool = &_data_pool + FLASH_PAGE_SIZE;
|
||||||
|
else if (gen1 == 0xffff)
|
||||||
|
data_pool = &_data_pool;
|
||||||
|
else if (gen1 > gen0)
|
||||||
|
data_pool = &_data_pool + FLASH_PAGE_SIZE;
|
||||||
|
else
|
||||||
|
data_pool = &_data_pool;
|
||||||
|
|
||||||
data_pool = &_data_pool;
|
|
||||||
keystore_pool = &_keystore_pool;
|
keystore_pool = &_keystore_pool;
|
||||||
|
|
||||||
/* Seek empty keystore */
|
/* Seek empty keystore */
|
||||||
@@ -164,6 +201,7 @@ flash_init (void)
|
|||||||
keystore = p;
|
keystore = p;
|
||||||
|
|
||||||
flash_unlock ();
|
flash_unlock ();
|
||||||
|
return data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -187,15 +225,6 @@ flash_init (void)
|
|||||||
* DATA: data * LEN
|
* DATA: data * LEN
|
||||||
* PAD: optional byte for 16-bit alignment
|
* PAD: optional byte for 16-bit alignment
|
||||||
*/
|
*/
|
||||||
#define FLASH_DATA_POOL_HEADER_SIZE 2
|
|
||||||
#define FLASH_DATA_POOL_SIZE (1024*3)
|
|
||||||
#define FLASH_PAGE_SIZE 1024
|
|
||||||
|
|
||||||
const uint8_t *
|
|
||||||
flash_data_pool (void)
|
|
||||||
{
|
|
||||||
return data_pool + FLASH_DATA_POOL_HEADER_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
flash_set_data_pool_last (const uint8_t *p)
|
flash_set_data_pool_last (const uint8_t *p)
|
||||||
@@ -203,27 +232,90 @@ flash_set_data_pool_last (const uint8_t *p)
|
|||||||
last_p = (uint8_t *)p;
|
last_p = (uint8_t *)p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We use two pages
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
flash_copying_gc (void)
|
||||||
|
{
|
||||||
|
uint8_t *src, *dst;
|
||||||
|
uint16_t generation;
|
||||||
|
|
||||||
|
if (data_pool == &_data_pool)
|
||||||
|
{
|
||||||
|
src = &_data_pool;
|
||||||
|
dst = &_data_pool + FLASH_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src = &_data_pool + FLASH_PAGE_SIZE;
|
||||||
|
dst = &_data_pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
generation = *(uint16_t *)src;
|
||||||
|
data_pool = dst;
|
||||||
|
gpg_data_copy (data_pool + FLASH_DATA_POOL_HEADER_SIZE);
|
||||||
|
flash_erase_page ((uint32_t)src);
|
||||||
|
flash_program_halfword ((uint32_t)dst, generation);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_data_pool_full (size_t size)
|
||||||
|
{
|
||||||
|
return last_p + size > data_pool + FLASH_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t *
|
static uint8_t *
|
||||||
flash_data_pool_allocate (size_t size)
|
flash_data_pool_allocate (size_t size)
|
||||||
{
|
{
|
||||||
uint8_t *p = last_p;
|
uint8_t *p;
|
||||||
|
|
||||||
size = (size + 1) & ~1; /* allocation unit is 1-halfword (2-byte) */
|
size = (size + 1) & ~1; /* allocation unit is 1-halfword (2-byte) */
|
||||||
|
|
||||||
if (last_p + size > data_pool - FLASH_DATA_POOL_HEADER_SIZE + FLASH_PAGE_SIZE)
|
if (is_data_pool_full (size))
|
||||||
return NULL; /* XXX: here invoke gc/erase page/.../ */
|
if (flash_copying_gc () < 0 || /*still*/ is_data_pool_full (size))
|
||||||
|
fatal ();
|
||||||
|
|
||||||
|
p = last_p;
|
||||||
last_p += size;
|
last_p += size;
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len)
|
||||||
|
{
|
||||||
|
uint16_t hw;
|
||||||
|
uint32_t addr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
addr = (uint32_t)p;
|
||||||
|
hw = nr | (len << 8);
|
||||||
|
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||||
|
flash_warning ("DO WRITE ERROR");
|
||||||
|
addr += 2;
|
||||||
|
|
||||||
|
for (i = 0; i < len/2; i ++)
|
||||||
|
{
|
||||||
|
hw = data[i*2] | (data[i*2+1]<<8);
|
||||||
|
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||||
|
flash_warning ("DO WRITE ERROR");
|
||||||
|
addr += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((len & 1))
|
||||||
|
{
|
||||||
|
hw = data[i*2] | 0xff00;
|
||||||
|
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||||
|
flash_warning ("DO WRITE ERROR");
|
||||||
|
addr += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const uint8_t *
|
const uint8_t *
|
||||||
flash_do_write (uint8_t nr, const uint8_t *data, int len)
|
flash_do_write (uint8_t nr, const uint8_t *data, int len)
|
||||||
{
|
{
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
uint16_t hw;
|
|
||||||
uint32_t addr;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
DEBUG_INFO ("flash DO\r\n");
|
DEBUG_INFO ("flash DO\r\n");
|
||||||
|
|
||||||
@@ -234,28 +326,7 @@ flash_do_write (uint8_t nr, const uint8_t *data, int len)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = (uint32_t)p;
|
flash_do_write_internal (p, nr, data, len);
|
||||||
hw = nr | (len << 8);
|
|
||||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
|
||||||
return NULL;
|
|
||||||
addr += 2;
|
|
||||||
|
|
||||||
for (i = 0; i < len/2; i ++)
|
|
||||||
{
|
|
||||||
hw = data[i*2] | (data[i*2+1]<<8);
|
|
||||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
|
||||||
return NULL;
|
|
||||||
addr += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((len & 1))
|
|
||||||
{
|
|
||||||
hw = data[i*2] | 0xff00;
|
|
||||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
|
||||||
return NULL;
|
|
||||||
addr += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG_INFO ("flash DO...done\r\n");
|
DEBUG_INFO ("flash DO...done\r\n");
|
||||||
return p + 1;
|
return p + 1;
|
||||||
}
|
}
|
||||||
@@ -353,6 +424,12 @@ flash_clear_halfword (uint32_t addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
flash_put_data_internal (const uint8_t *p, uint16_t hw)
|
||||||
|
{
|
||||||
|
flash_program_halfword ((uint32_t)p, hw);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
flash_put_data (uint16_t hw)
|
flash_put_data (uint16_t hw)
|
||||||
{
|
{
|
||||||
@@ -380,6 +457,12 @@ flash_bool_clear (const uint8_t **addr_p)
|
|||||||
*addr_p = NULL;
|
*addr_p = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
flash_bool_write_internal (const uint8_t *p, int nr)
|
||||||
|
{
|
||||||
|
flash_program_halfword ((uint32_t)p, nr);
|
||||||
|
}
|
||||||
|
|
||||||
const uint8_t *
|
const uint8_t *
|
||||||
flash_bool_write (uint8_t nr)
|
flash_bool_write (uint8_t nr)
|
||||||
{
|
{
|
||||||
@@ -423,6 +506,22 @@ flash_cnt123_get_value (const uint8_t *p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
flash_cnt123_write_internal (const uint8_t *p, int which, int v)
|
||||||
|
{
|
||||||
|
uint16_t hw;
|
||||||
|
|
||||||
|
hw = NR_COUNTER_123 | (which << 8);
|
||||||
|
flash_program_halfword ((uint32_t)p, hw);
|
||||||
|
|
||||||
|
if (v == 1)
|
||||||
|
return;
|
||||||
|
else if (v == 2)
|
||||||
|
flash_program_halfword ((uint32_t)p+2, 0xc3c3);
|
||||||
|
else /* v == 3 */
|
||||||
|
flash_program_halfword ((uint32_t)p+2, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
flash_cnt123_increment (uint8_t which, const uint8_t **addr_p)
|
flash_cnt123_increment (uint8_t which, const uint8_t **addr_p)
|
||||||
{
|
{
|
||||||
|
|||||||
11
src/gnuk.h
11
src/gnuk.h
@@ -72,7 +72,8 @@ extern void write_res_apdu (const uint8_t *p, int len,
|
|||||||
uint8_t sw1, uint8_t sw2);
|
uint8_t sw1, uint8_t sw2);
|
||||||
uint16_t data_objects_number_of_bytes;
|
uint16_t data_objects_number_of_bytes;
|
||||||
|
|
||||||
extern int gpg_do_table_init (void);
|
extern void gpg_data_scan (const uint8_t *p);
|
||||||
|
extern void gpg_data_copy (const uint8_t *p);
|
||||||
extern void gpg_do_get_data (uint16_t tag);
|
extern void gpg_do_get_data (uint16_t tag);
|
||||||
extern void gpg_do_put_data (uint16_t tag, const uint8_t *data, int len);
|
extern void gpg_do_put_data (uint16_t tag, const uint8_t *data, int len);
|
||||||
extern void gpg_do_public_key (uint8_t kk_byte);
|
extern void gpg_do_public_key (uint8_t kk_byte);
|
||||||
@@ -85,12 +86,11 @@ enum kind_of_key {
|
|||||||
GPG_KEY_FOR_AUTHENTICATION,
|
GPG_KEY_FOR_AUTHENTICATION,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void flash_init (void);
|
extern const uint8_t *flash_init (void);
|
||||||
extern void flash_do_release (const uint8_t *);
|
extern void flash_do_release (const uint8_t *);
|
||||||
extern const uint8_t *flash_do_write (uint8_t nr, const uint8_t *data, int len);
|
extern const uint8_t *flash_do_write (uint8_t nr, const uint8_t *data, int len);
|
||||||
extern uint8_t *flash_key_alloc (void);
|
extern uint8_t *flash_key_alloc (void);
|
||||||
extern void flash_key_release (const uint8_t *);
|
extern void flash_key_release (const uint8_t *);
|
||||||
extern const uint8_t *flash_data_pool (void);
|
|
||||||
extern void flash_set_data_pool_last (const uint8_t *p);
|
extern void flash_set_data_pool_last (const uint8_t *p);
|
||||||
extern void flash_clear_halfword (uint32_t addr);
|
extern void flash_clear_halfword (uint32_t addr);
|
||||||
extern void flash_increment_counter (uint8_t counter_tag_nr);
|
extern void flash_increment_counter (uint8_t counter_tag_nr);
|
||||||
@@ -286,3 +286,8 @@ extern void flash_cnt123_increment (uint8_t which, const uint8_t **addr_p);
|
|||||||
extern void flash_cnt123_clear (const uint8_t **addr_p);
|
extern void flash_cnt123_clear (const uint8_t **addr_p);
|
||||||
extern void flash_put_data (uint16_t hw);
|
extern void flash_put_data (uint16_t hw);
|
||||||
extern void flash_warning (const char *msg);
|
extern void flash_warning (const char *msg);
|
||||||
|
|
||||||
|
extern void flash_put_data_internal (const uint8_t *p, uint16_t hw);
|
||||||
|
extern void flash_bool_write_internal (const uint8_t *p, int nr);
|
||||||
|
extern void flash_cnt123_write_internal (const uint8_t *p, int which, int v);
|
||||||
|
extern void flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len);
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ SECTIONS
|
|||||||
KEEP(*(.gnuk_data))
|
KEEP(*(.gnuk_data))
|
||||||
FILL(0xffffffff);
|
FILL(0xffffffff);
|
||||||
. = ALIGN(1024);
|
. = ALIGN(1024);
|
||||||
. += 1024*2;
|
. += 1024;
|
||||||
_keystore_pool = .;
|
_keystore_pool = .;
|
||||||
FILL(0xffffffff);
|
FILL(0xffffffff);
|
||||||
. += 1024*3;
|
. += 1024*3;
|
||||||
|
|||||||
@@ -176,14 +176,15 @@ main (int argc, char **argv)
|
|||||||
eventmask_t m;
|
eventmask_t m;
|
||||||
uint8_t led_state = 0;
|
uint8_t led_state = 0;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
const uint8_t *flash_data_start;
|
||||||
|
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
|
|
||||||
blinker_thread = chThdSelf ();
|
blinker_thread = chThdSelf ();
|
||||||
|
|
||||||
flash_init ();
|
flash_data_start = flash_init ();
|
||||||
gpg_do_table_init ();
|
gpg_data_scan (flash_data_start);
|
||||||
|
|
||||||
usb_lld_init ();
|
usb_lld_init ();
|
||||||
USB_Init();
|
USB_Init();
|
||||||
|
|||||||
@@ -34,30 +34,47 @@
|
|||||||
|
|
||||||
static uint32_t digital_signature_counter;
|
static uint32_t digital_signature_counter;
|
||||||
|
|
||||||
|
static const uint8_t *
|
||||||
|
gpg_write_digital_signature_counter (const uint8_t *p, uint32_t dsc)
|
||||||
|
{
|
||||||
|
uint16_t hw0, hw1;
|
||||||
|
|
||||||
|
if ((dsc >> 10) == 0)
|
||||||
|
{ /* no upper bits */
|
||||||
|
hw1 = NR_COUNTER_DS_LSB | ((dsc & 0x0300) >> 8) | ((dsc & 0x00ff) << 8);
|
||||||
|
flash_put_data_internal (p, hw1);
|
||||||
|
return p+2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hw0 = NR_COUNTER_DS | ((dsc & 0xfc0000) >> 18) | ((dsc & 0x03fc00) >> 2);
|
||||||
|
hw1 = NR_COUNTER_DS_LSB;
|
||||||
|
flash_put_data_internal (p, hw0);
|
||||||
|
flash_put_data_internal (p+2, hw1);
|
||||||
|
return p+4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gpg_increment_digital_signature_counter (void)
|
gpg_increment_digital_signature_counter (void)
|
||||||
{
|
{
|
||||||
uint16_t hw0, hw1;
|
uint16_t hw0, hw1;
|
||||||
|
uint32_t dsc = (digital_signature_counter + 1) & 0x00ffffff;
|
||||||
|
|
||||||
digital_signature_counter++;
|
if ((dsc & 0x03ff) == 0)
|
||||||
digital_signature_counter &= 0x00ffffff;
|
|
||||||
|
|
||||||
if ((digital_signature_counter & 0x03ff) == 0)
|
|
||||||
{ /* carry occurs from l10 to h14 */
|
{ /* carry occurs from l10 to h14 */
|
||||||
hw0 = NR_COUNTER_DS
|
hw0 = NR_COUNTER_DS | ((dsc & 0xfc0000) >> 18) | ((dsc & 0x03fc00) >> 2);
|
||||||
| ((digital_signature_counter & 0x00fc0000) >> 18)
|
hw1 = NR_COUNTER_DS_LSB; /* zero */
|
||||||
| ((digital_signature_counter & 0x0003fc00) >> 2);
|
|
||||||
hw1 = NR_COUNTER_DS_LSB;
|
|
||||||
flash_put_data (hw0);
|
flash_put_data (hw0);
|
||||||
flash_put_data (hw1);
|
flash_put_data (hw1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hw1 = NR_COUNTER_DS_LSB
|
hw1 = NR_COUNTER_DS_LSB | ((dsc & 0x0300) >> 8) | ((dsc & 0x00ff) << 8);
|
||||||
| ((digital_signature_counter & 0x0300) >> 8)
|
|
||||||
| ((digital_signature_counter & 0x00ff) << 8);
|
|
||||||
flash_put_data (hw1);
|
flash_put_data (hw1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
digital_signature_counter = dsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PASSWORD_ERRORS_MAX 3 /* >= errors, it will be locked */
|
#define PASSWORD_ERRORS_MAX 3 /* >= errors, it will be locked */
|
||||||
@@ -901,16 +918,14 @@ gpg_do_table[] = {
|
|||||||
/*
|
/*
|
||||||
* Reading data from Flash ROM, initialize DO_PTR, PW_ERR_COUNTERS, etc.
|
* Reading data from Flash ROM, initialize DO_PTR, PW_ERR_COUNTERS, etc.
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
gpg_do_table_init (void)
|
gpg_data_scan (const uint8_t *p_start)
|
||||||
{
|
{
|
||||||
const uint8_t *p, *p_start;
|
const uint8_t *p;
|
||||||
int i;
|
int i;
|
||||||
const uint8_t *dsc_h14_p, *dsc_l10_p;
|
const uint8_t *dsc_h14_p, *dsc_l10_p;
|
||||||
int dsc_h14, dsc_l10;
|
int dsc_h14, dsc_l10;
|
||||||
|
|
||||||
p_start = flash_data_pool ();
|
|
||||||
|
|
||||||
dsc_h14_p = dsc_l10_p = NULL;
|
dsc_h14_p = dsc_l10_p = NULL;
|
||||||
pw1_lifetime_p = NULL;
|
pw1_lifetime_p = NULL;
|
||||||
pw_err_counter_p[PW_ERR_PW1] = NULL;
|
pw_err_counter_p[PW_ERR_PW1] = NULL;
|
||||||
@@ -999,7 +1014,46 @@ gpg_do_table_init (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
digital_signature_counter = (dsc_h14 << 10) | dsc_l10;
|
digital_signature_counter = (dsc_h14 << 10) | dsc_l10;
|
||||||
return 0;
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gpg_data_copy (const uint8_t *p_start)
|
||||||
|
{
|
||||||
|
const uint8_t *p;
|
||||||
|
int i;
|
||||||
|
int v;
|
||||||
|
|
||||||
|
p = gpg_write_digital_signature_counter (p_start, digital_signature_counter);
|
||||||
|
|
||||||
|
if (pw1_lifetime_p != NULL)
|
||||||
|
{
|
||||||
|
flash_bool_write_internal (p, NR_BOOL_PW1_LIFETIME);
|
||||||
|
pw1_lifetime_p = p;
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
if ((v = flash_cnt123_get_value (pw_err_counter_p[i])) != 0)
|
||||||
|
{
|
||||||
|
flash_cnt123_write_internal (p, i, v);
|
||||||
|
pw_err_counter_p[i] = p + 2;
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_objects_number_of_bytes = 0;
|
||||||
|
for (i = NR_DO__FIRST__; i < NR_DO__LAST__; i++)
|
||||||
|
if (do_ptr[i - NR_DO__FIRST__] != NULL)
|
||||||
|
{
|
||||||
|
const uint8_t *do_data = do_ptr[i - NR_DO__FIRST__];
|
||||||
|
int len = do_data[0];
|
||||||
|
|
||||||
|
flash_do_write_internal (p, i, &do_data[1], len);
|
||||||
|
do_ptr[i - NR_DO__FIRST__] = p + 1;
|
||||||
|
p += 2 + ((len + 1) & ~1);
|
||||||
|
data_objects_number_of_bytes += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
flash_set_data_pool_last (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct do_table_entry *
|
static const struct do_table_entry *
|
||||||
|
|||||||
Reference in New Issue
Block a user