From 1744861b5252514859e44b39b4d01ac331e11eb6 Mon Sep 17 00:00:00 2001 From: NIIBE Yutaka Date: Thu, 4 Nov 2010 13:57:42 +0900 Subject: [PATCH] Change DO format in flash --- ChangeLog | 9 ++- src/flash.c | 143 +++++++++++++++++++---------------------------- src/openpgp-do.c | 71 +++++++---------------- 3 files changed, 87 insertions(+), 136 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ba722a..a789f3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,12 @@ 2010-11-04 NIIBE Yutaka + * 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 Bug fixes. diff --git a/src/flash.c b/src/flash.c index adc6e5e..193c1a5 100644 --- a/src/flash.c +++ b/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,133 +200,82 @@ 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) + for (i = 0; i < len/2; i ++) { - hw = len; - state = 1; - } - else if (len < 256) - { - hw = 0x81 | (len << 8); + hw = data[i*2] | (data[i*2+1]<<8); if (flash_program_halfword (addr, hw) != FLASH_COMPLETE) return NULL; 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) 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); - 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; 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; - } + addr += 2; - /* 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 * diff --git a/src/openpgp-do.c b/src/openpgp-do.c index bd8472f..cfbeaaf 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -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,28 +879,18 @@ gpg_do_table_init (void) while (*p != 0xff) { uint8_t nr = *p++; - uint8_t check = *p++; + uint8_t len = *p; - if (check == 0xff) - 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)) + if (len == 0x00) p++; + else + { + do_ptr[nr] = p; + p += len + 1; + + if (((uint32_t)p & 1)) + 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); - if (do_data[0] < 127) - 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; + if (do_data[0] >= 128) + *res_p++ = 0x81; + + len = do_data[0] + 1; } 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; - } + len = do_data[0]; + do_data++; } memcpy (res_p, do_data, 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; + return do_data+1; } void @@ -1259,7 +1229,8 @@ gpg_do_increment_digital_signature_counter (void) count_data[1] = (count >> 8) & 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, SIZE_DIGITAL_SIGNATURE_COUNTER); }