Change DO format in flash
This commit is contained in:
@@ -1,5 +1,12 @@
|
|||||||
2010-11-04 NIIBE Yutaka <gniibe@fsij.org>
|
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.
|
* src/openpgp-do.c (DO_CMP_READ): Renamed.
|
||||||
(cmp_ch_data, cmp_app_data, cmp_ss_temp): Likewise.
|
(cmp_ch_data, cmp_app_data, cmp_ss_temp): Likewise.
|
||||||
(with_tag): Removed static global variable.
|
(with_tag): Removed static global variable.
|
||||||
@@ -8,8 +15,6 @@
|
|||||||
with_tag argument.
|
with_tag argument.
|
||||||
(gpg_do_put_data): length > 255 will be error.
|
(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>
|
2010-11-03 NIIBE Yutaka <gniibe@fsij.org>
|
||||||
|
|
||||||
Bug fixes.
|
Bug fixes.
|
||||||
|
|||||||
143
src/flash.c
143
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
|
* Note: Garbage collection and page management with flash erase
|
||||||
* is *NOT YET* implemented
|
* is *NOT YET* implemented
|
||||||
@@ -136,11 +143,13 @@ const uint8_t const flash_data[4] __attribute__ ((section (".gnuk_data"))) = {
|
|||||||
0xff, 0xff, 0xff, 0xff
|
0xff, 0xff, 0xff, 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Linker set this symbol */
|
||||||
|
extern uint8_t _do_pool;
|
||||||
|
|
||||||
void
|
void
|
||||||
flash_init (void)
|
flash_init (void)
|
||||||
{
|
{
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
extern uint8_t _do_pool;
|
|
||||||
extern uint8_t _keystore_pool;
|
extern uint8_t _keystore_pool;
|
||||||
|
|
||||||
do_pool = &_do_pool;
|
do_pool = &_do_pool;
|
||||||
@@ -156,10 +165,27 @@ flash_init (void)
|
|||||||
flash_unlock ();
|
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 *
|
const uint8_t *
|
||||||
flash_do_pool (void)
|
flash_do_pool (void)
|
||||||
{
|
{
|
||||||
return do_pool;
|
return do_pool + FLASH_DO_POOL_HEADER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -174,133 +200,82 @@ flash_do_write (uint8_t nr, const uint8_t *data, int len)
|
|||||||
const uint8_t *p = last_p;
|
const uint8_t *p = last_p;
|
||||||
uint16_t hw;
|
uint16_t hw;
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
int state = 0;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (last_p - do_pool + len + 2 + 3 > 1024*3)
|
if (last_p - do_pool + len + FLASH_DO_POOL_HEADER_SIZE + 2 > FLASH_PAGE_SIZE)
|
||||||
return NULL;
|
return NULL; /* gc/erase/.../ */
|
||||||
|
|
||||||
DEBUG_INFO ("flash DO\r\n");
|
DEBUG_INFO ("flash DO\r\n");
|
||||||
|
|
||||||
addr = (uint32_t)last_p;
|
addr = (uint32_t)last_p;
|
||||||
hw = nr | (0xff << 8);
|
hw = nr | (len << 8);
|
||||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||||
return NULL;
|
return NULL;
|
||||||
addr += 2;
|
addr += 2;
|
||||||
|
|
||||||
if (len < 128)
|
for (i = 0; i < len/2; i ++)
|
||||||
{
|
{
|
||||||
hw = len;
|
hw = data[i*2] | (data[i*2+1]<<8);
|
||||||
state = 1;
|
|
||||||
}
|
|
||||||
else if (len < 256)
|
|
||||||
{
|
|
||||||
hw = 0x81 | (len << 8);
|
|
||||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||||
return NULL;
|
return NULL;
|
||||||
addr += 2;
|
addr += 2;
|
||||||
state = 0;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if ((len & 1))
|
||||||
{
|
{
|
||||||
hw = 0x82 | ((len >> 8) << 8);
|
hw = data[i*2] | 0xff00;
|
||||||
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
|
||||||
return NULL;
|
return NULL;
|
||||||
addr += 2;
|
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);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
last_p = (const uint8_t *)addr;
|
||||||
|
|
||||||
DEBUG_INFO ("flash DO...done\r\n");
|
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
|
void
|
||||||
flash_do_release (const uint8_t *do_data)
|
flash_do_release (const uint8_t *do_data)
|
||||||
{
|
{
|
||||||
uint32_t addr = (uint32_t)do_data;
|
uint32_t addr = (uint32_t)do_data - 1;
|
||||||
int state = 0;
|
uint32_t addr_tag = addr;
|
||||||
int i;
|
int i;
|
||||||
int len;
|
int len = do_data[0];
|
||||||
|
|
||||||
/* Fill 0x0000 for "tag and check" word */
|
/* Don't filling zero for data in code (such as ds_count_initial_value) */
|
||||||
if (flash_program_halfword (addr - 2, 0) != FLASH_COMPLETE)
|
if (do_data < &_do_pool || do_data > &_do_pool + FLASH_DO_POOL_SIZE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (do_data[0] < 127)
|
addr += 2;
|
||||||
{
|
|
||||||
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 ++)
|
for (i = 0; i < len/2; i ++)
|
||||||
{
|
{
|
||||||
if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
|
if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
|
||||||
return;
|
flash_warning ("fill-zero failure");
|
||||||
addr += 2;
|
addr += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((len & 1))
|
if ((len & 1))
|
||||||
{
|
{
|
||||||
if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
|
if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
|
||||||
return;
|
flash_warning ("fill-zero pad failure");
|
||||||
addr += 2;
|
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 *
|
uint8_t *
|
||||||
|
|||||||
@@ -421,7 +421,7 @@ proc_resetting_code (const uint8_t *data, int len)
|
|||||||
newpw = data;
|
newpw = data;
|
||||||
sha1 (newpw, newpw_len, new_ks);
|
sha1 (newpw, newpw_len, new_ks);
|
||||||
new_ks0[0] = newpw_len;
|
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)
|
if (r < -2)
|
||||||
{
|
{
|
||||||
DEBUG_INFO ("memory error.\r\n");
|
DEBUG_INFO ("memory error.\r\n");
|
||||||
@@ -868,7 +868,7 @@ int
|
|||||||
gpg_do_table_init (void)
|
gpg_do_table_init (void)
|
||||||
{
|
{
|
||||||
const uint8_t *p, *p_start;
|
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_DS_COUNT] = do_ds_count_initial_value;
|
||||||
do_ptr[NR_DO_PW_STATUS] = do_pw_status_bytes_template;
|
do_ptr[NR_DO_PW_STATUS] = do_pw_status_bytes_template;
|
||||||
@@ -879,28 +879,18 @@ gpg_do_table_init (void)
|
|||||||
while (*p != 0xff)
|
while (*p != 0xff)
|
||||||
{
|
{
|
||||||
uint8_t nr = *p++;
|
uint8_t nr = *p++;
|
||||||
uint8_t check = *p++;
|
uint8_t len = *p;
|
||||||
|
|
||||||
if (check == 0xff)
|
if (len == 0x00)
|
||||||
do_ptr[nr] = p;
|
|
||||||
|
|
||||||
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++;
|
p++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do_ptr[nr] = p;
|
||||||
|
p += len + 1;
|
||||||
|
|
||||||
|
if (((uint32_t)p & 1))
|
||||||
|
p++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flash_set_do_pool_last (p);
|
flash_set_do_pool_last (p);
|
||||||
@@ -942,30 +932,15 @@ copy_do_1 (uint16_t tag, const uint8_t *do_data, int with_tag)
|
|||||||
{
|
{
|
||||||
copy_tag (tag);
|
copy_tag (tag);
|
||||||
|
|
||||||
if (do_data[0] < 127)
|
if (do_data[0] >= 128)
|
||||||
len = do_data[0] + 1;
|
*res_p++ = 0x81;
|
||||||
else if (do_data[0] == 0x81)
|
|
||||||
len = do_data[1] + 2;
|
len = do_data[0] + 1;
|
||||||
else /* 0x82 */
|
|
||||||
len = ((do_data[1] << 8) | do_data[2]) + 3;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (do_data[0] < 127)
|
len = do_data[0];
|
||||||
{
|
do_data++;
|
||||||
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);
|
memcpy (res_p, do_data, len);
|
||||||
@@ -1209,12 +1184,7 @@ gpg_do_read_simple (uint8_t nr)
|
|||||||
if (do_data == NULL)
|
if (do_data == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (do_data[0] < 128)
|
return do_data+1;
|
||||||
return do_data+1;
|
|
||||||
else if (do_data[0] == 0x81)
|
|
||||||
return do_data+2;
|
|
||||||
else /* 0x82 */
|
|
||||||
return do_data+3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1259,7 +1229,8 @@ gpg_do_increment_digital_signature_counter (void)
|
|||||||
count_data[1] = (count >> 8) & 0xff;
|
count_data[1] = (count >> 8) & 0xff;
|
||||||
count_data[2] = count & 0xff;
|
count_data[2] = count & 0xff;
|
||||||
|
|
||||||
flash_do_release (do_data);
|
if (do_data)
|
||||||
|
flash_do_release (do_data);
|
||||||
do_ptr[NR_DO_DS_COUNT] = flash_do_write (NR_DO_DS_COUNT, count_data,
|
do_ptr[NR_DO_DS_COUNT] = flash_do_write (NR_DO_DS_COUNT, count_data,
|
||||||
SIZE_DIGITAL_SIGNATURE_COUNTER);
|
SIZE_DIGITAL_SIGNATURE_COUNTER);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user