Change DO format in flash
This commit is contained in:
@@ -1,5 +1,12 @@
|
||||
2010-11-04 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
* src/flash.c (flash_warning): New.
|
||||
(flash_do_pool): Added header for DO pool.
|
||||
(flash_do_release): Fill zero.
|
||||
(flash_do_write): Change DO format in flash.
|
||||
* src/openpgp-do.c (gpg_do_table_init, copy_do_1)
|
||||
(gpg_do_read_simple): Follow the change of DO format in flash.
|
||||
|
||||
* src/openpgp-do.c (DO_CMP_READ): Renamed.
|
||||
(cmp_ch_data, cmp_app_data, cmp_ss_temp): Likewise.
|
||||
(with_tag): Removed static global variable.
|
||||
@@ -8,8 +15,6 @@
|
||||
with_tag argument.
|
||||
(gpg_do_put_data): length > 255 will be error.
|
||||
|
||||
* src/flash.c (flash_do_release): Fill zero.
|
||||
|
||||
2010-11-03 NIIBE Yutaka <gniibe@fsij.org>
|
||||
|
||||
Bug fixes.
|
||||
|
||||
131
src/flash.c
131
src/flash.c
@@ -21,6 +21,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* We assume single DO size is less than 256.
|
||||
*
|
||||
* NOTE: When we will support "Card holder certificate"
|
||||
* (which size is larger than 256), it will not be put into DO pool.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note: Garbage collection and page management with flash erase
|
||||
* is *NOT YET* implemented
|
||||
@@ -136,11 +143,13 @@ const uint8_t const flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
|
||||
0xff, 0xff, 0xff, 0xff
|
||||
};
|
||||
|
||||
/* Linker set this symbol */
|
||||
extern uint8_t _do_pool;
|
||||
|
||||
void
|
||||
flash_init (void)
|
||||
{
|
||||
const uint8_t *p;
|
||||
extern uint8_t _do_pool;
|
||||
extern uint8_t _keystore_pool;
|
||||
|
||||
do_pool = &_do_pool;
|
||||
@@ -156,10 +165,27 @@ flash_init (void)
|
||||
flash_unlock ();
|
||||
}
|
||||
|
||||
/*
|
||||
* DO pool managenent
|
||||
*
|
||||
* DO pool consists of two part:
|
||||
* 2-byte header
|
||||
* contents
|
||||
*
|
||||
* Format of a DO pool content:
|
||||
* NR: 8-bit tag_number
|
||||
* LEN: 8-bit length
|
||||
* DATA: data * LEN
|
||||
* PAD: optional byte for 16-bit alignment
|
||||
*/
|
||||
#define FLASH_DO_POOL_HEADER_SIZE 2
|
||||
#define FLASH_DO_POOL_SIZE 1024*3
|
||||
#define FLASH_PAGE_SIZE 1024
|
||||
|
||||
const uint8_t *
|
||||
flash_do_pool (void)
|
||||
{
|
||||
return do_pool;
|
||||
return do_pool + FLASH_DO_POOL_HEADER_SIZE;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -174,45 +200,19 @@ flash_do_write (uint8_t nr, const uint8_t *data, int len)
|
||||
const uint8_t *p = last_p;
|
||||
uint16_t hw;
|
||||
uint32_t addr;
|
||||
int state = 0;
|
||||
int i;
|
||||
|
||||
if (last_p - do_pool + len + 2 + 3 > 1024*3)
|
||||
return NULL;
|
||||
if (last_p - do_pool + len + FLASH_DO_POOL_HEADER_SIZE + 2 > FLASH_PAGE_SIZE)
|
||||
return NULL; /* gc/erase/.../ */
|
||||
|
||||
DEBUG_INFO ("flash DO\r\n");
|
||||
|
||||
addr = (uint32_t)last_p;
|
||||
hw = nr | (0xff << 8);
|
||||
hw = nr | (len << 8);
|
||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||
return NULL;
|
||||
addr += 2;
|
||||
|
||||
if (len < 128)
|
||||
{
|
||||
hw = len;
|
||||
state = 1;
|
||||
}
|
||||
else if (len < 256)
|
||||
{
|
||||
hw = 0x81 | (len << 8);
|
||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||
return NULL;
|
||||
addr += 2;
|
||||
state = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
hw = 0x82 | ((len >> 8) << 8);
|
||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||
return NULL;
|
||||
addr += 2;
|
||||
hw = (len & 0xff);
|
||||
state = 1;
|
||||
}
|
||||
|
||||
if (state == 0)
|
||||
{
|
||||
for (i = 0; i < len/2; i ++)
|
||||
{
|
||||
hw = data[i*2] | (data[i*2+1]<<8);
|
||||
@@ -228,79 +228,54 @@ flash_do_write (uint8_t nr, const uint8_t *data, int len)
|
||||
return NULL;
|
||||
addr += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hw |= (data[0]<<8);
|
||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||
return NULL;
|
||||
addr += 2;
|
||||
|
||||
for (i = 0; i < (len - 1)/2; i ++)
|
||||
{
|
||||
hw = data[i*2+1] | (data[i*2+2]<<8);
|
||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||
return NULL;
|
||||
addr += 2;
|
||||
}
|
||||
|
||||
if (((len - 1) & 1))
|
||||
{
|
||||
hw = data[i*2+1] | 0xff00;
|
||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||
return NULL;
|
||||
addr += 2;
|
||||
}
|
||||
}
|
||||
|
||||
last_p = (const uint8_t *)addr;
|
||||
|
||||
DEBUG_INFO ("flash DO...done\r\n");
|
||||
return p + 2;
|
||||
return p + 1;
|
||||
}
|
||||
|
||||
static void
|
||||
flash_warning (const char *msg)
|
||||
{
|
||||
(void)msg;
|
||||
DEBUG_INFO ("FLASH: ");
|
||||
DEBUG_INFO (msg);
|
||||
DEBUG_INFO ("\r\n");
|
||||
}
|
||||
|
||||
void
|
||||
flash_do_release (const uint8_t *do_data)
|
||||
{
|
||||
uint32_t addr = (uint32_t)do_data;
|
||||
int state = 0;
|
||||
uint32_t addr = (uint32_t)do_data - 1;
|
||||
uint32_t addr_tag = addr;
|
||||
int i;
|
||||
int len;
|
||||
int len = do_data[0];
|
||||
|
||||
/* Fill 0x0000 for "tag and check" word */
|
||||
if (flash_program_halfword (addr - 2, 0) != FLASH_COMPLETE)
|
||||
/* Don't filling zero for data in code (such as ds_count_initial_value) */
|
||||
if (do_data < &_do_pool || do_data > &_do_pool + FLASH_DO_POOL_SIZE)
|
||||
return;
|
||||
|
||||
if (do_data[0] < 127)
|
||||
{
|
||||
len = do_data[0] - 1;
|
||||
addr += 2;
|
||||
}
|
||||
else if (do_data[0] == 0x81)
|
||||
{
|
||||
len = do_data[1];
|
||||
addr += 2;
|
||||
}
|
||||
else /* 0x82 */
|
||||
{
|
||||
len = ((do_data[1] << 8) | do_data[2]) - 1;
|
||||
addr += 4;
|
||||
}
|
||||
|
||||
/* Fill zero */
|
||||
/* Fill zero for content and pad */
|
||||
for (i = 0; i < len/2; i ++)
|
||||
{
|
||||
if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
|
||||
return;
|
||||
flash_warning ("fill-zero failure");
|
||||
addr += 2;
|
||||
}
|
||||
|
||||
if ((len & 1))
|
||||
{
|
||||
if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
|
||||
return;
|
||||
flash_warning ("fill-zero pad failure");
|
||||
addr += 2;
|
||||
}
|
||||
|
||||
/* Fill 0x0000 for "tag_number and length" word */
|
||||
if (flash_program_halfword (addr_tag, 0) != FLASH_COMPLETE)
|
||||
flash_warning ("fill-zero tag_nr failure");
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
|
||||
@@ -421,7 +421,7 @@ proc_resetting_code (const uint8_t *data, int len)
|
||||
newpw = data;
|
||||
sha1 (newpw, newpw_len, new_ks);
|
||||
new_ks0[0] = newpw_len;
|
||||
r = gpg_change_keystring (3, old_ks, 2, new_ks);
|
||||
r = gpg_change_keystring (BY_ADMIN, old_ks, BY_RESETCODE, new_ks);
|
||||
if (r < -2)
|
||||
{
|
||||
DEBUG_INFO ("memory error.\r\n");
|
||||
@@ -868,7 +868,7 @@ int
|
||||
gpg_do_table_init (void)
|
||||
{
|
||||
const uint8_t *p, *p_start;
|
||||
int i, len;
|
||||
int i;
|
||||
|
||||
do_ptr[NR_DO_DS_COUNT] = do_ds_count_initial_value;
|
||||
do_ptr[NR_DO_PW_STATUS] = do_pw_status_bytes_template;
|
||||
@@ -879,29 +879,19 @@ gpg_do_table_init (void)
|
||||
while (*p != 0xff)
|
||||
{
|
||||
uint8_t nr = *p++;
|
||||
uint8_t check = *p++;
|
||||
uint8_t len = *p;
|
||||
|
||||
if (check == 0xff)
|
||||
if (len == 0x00)
|
||||
p++;
|
||||
else
|
||||
{
|
||||
do_ptr[nr] = p;
|
||||
p += len + 1;
|
||||
|
||||
if (*p < 128)
|
||||
len = *p++;
|
||||
else if (*p == 0x81)
|
||||
{
|
||||
p++;
|
||||
len = *p++;
|
||||
}
|
||||
else /* 0x82 */
|
||||
{
|
||||
p++;
|
||||
len = (*p << 8) + *(p+1);
|
||||
p += 2;
|
||||
}
|
||||
|
||||
p += len;
|
||||
if (((uint32_t)p & 1))
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
flash_set_do_pool_last (p);
|
||||
|
||||
@@ -942,31 +932,16 @@ copy_do_1 (uint16_t tag, const uint8_t *do_data, int with_tag)
|
||||
{
|
||||
copy_tag (tag);
|
||||
|
||||
if (do_data[0] < 127)
|
||||
if (do_data[0] >= 128)
|
||||
*res_p++ = 0x81;
|
||||
|
||||
len = do_data[0] + 1;
|
||||
else if (do_data[0] == 0x81)
|
||||
len = do_data[1] + 2;
|
||||
else /* 0x82 */
|
||||
len = ((do_data[1] << 8) | do_data[2]) + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (do_data[0] < 127)
|
||||
{
|
||||
len = do_data[0];
|
||||
do_data++;
|
||||
}
|
||||
else if (do_data[0] == 0x81)
|
||||
{
|
||||
len = do_data[1];
|
||||
do_data += 2;
|
||||
}
|
||||
else /* 0x82 */
|
||||
{
|
||||
len = ((do_data[1] << 8) | do_data[2]);
|
||||
do_data += 3;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy (res_p, do_data, len);
|
||||
res_p += len;
|
||||
@@ -1209,12 +1184,7 @@ gpg_do_read_simple (uint8_t nr)
|
||||
if (do_data == NULL)
|
||||
return NULL;
|
||||
|
||||
if (do_data[0] < 128)
|
||||
return do_data+1;
|
||||
else if (do_data[0] == 0x81)
|
||||
return do_data+2;
|
||||
else /* 0x82 */
|
||||
return do_data+3;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -1259,6 +1229,7 @@ gpg_do_increment_digital_signature_counter (void)
|
||||
count_data[1] = (count >> 8) & 0xff;
|
||||
count_data[2] = count & 0xff;
|
||||
|
||||
if (do_data)
|
||||
flash_do_release (do_data);
|
||||
do_ptr[NR_DO_DS_COUNT] = flash_do_write (NR_DO_DS_COUNT, count_data,
|
||||
SIZE_DIGITAL_SIGNATURE_COUNTER);
|
||||
|
||||
Reference in New Issue
Block a user