diff --git a/ChangeLog b/ChangeLog index 1f4f25d..3ba722a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-11-04 NIIBE Yutaka + + * src/openpgp-do.c (DO_CMP_READ): Renamed. + (cmp_ch_data, cmp_app_data, cmp_ss_temp): Likewise. + (with_tag): Removed static global variable. + (do_hist_bytes, do_fp_all, do_cafp_all, do_kgtime_all) + (rw_pw_status, copy_do_1, copy_do, gpg_do_get_data): Added + 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/README b/README index 74184fc..ec79c78 100644 --- a/README +++ b/README @@ -55,6 +55,10 @@ It is known not-working well: * For some version of kernel and libccid, --enable-debug can't work well. Please disable DEBUG option if it doesn't work well. +Not (yet) supported feature(s): + + * card holder certificate (its size matters (> 1KiB?), if we support) + Targets ======= diff --git a/src/flash.c b/src/flash.c index 270115e..adc6e5e 100644 --- a/src/flash.c +++ b/src/flash.c @@ -262,7 +262,45 @@ flash_do_write (uint8_t nr, const uint8_t *data, int len) void flash_do_release (const uint8_t *do_data) { - (void)do_data; + uint32_t addr = (uint32_t)do_data; + int state = 0; + int i; + int len; + + /* Fill 0x0000 for "tag and check" word */ + if (flash_program_halfword (addr - 2, 0) != FLASH_COMPLETE) + 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 */ + for (i = 0; i < len/2; i ++) + { + if (flash_program_halfword (addr, 0) != FLASH_COMPLETE) + return; + addr += 2; + } + + if ((len & 1)) + { + if (flash_program_halfword (addr, 0) != FLASH_COMPLETE) + return; + addr += 2; + } } uint8_t * diff --git a/src/openpgp-do.c b/src/openpgp-do.c index 204c228..bd8472f 100644 --- a/src/openpgp-do.c +++ b/src/openpgp-do.c @@ -111,7 +111,7 @@ static const uint8_t do_pw_status_bytes_template[] __attribute__ ((aligned (1))) enum do_type { DO_FIXED, DO_VAR, - DO_CN_READ, + DO_CMP_READ, DO_PROC_READ, DO_PROC_WRITE, DO_PROC_READWRITE, @@ -126,9 +126,8 @@ struct do_table_entry { }; static uint8_t *res_p; -static int with_tag; -static void copy_do_1 (uint16_t tag, const uint8_t *do_data); +static void copy_do_1 (uint16_t tag, const uint8_t *do_data, int with_tag); static const struct do_table_entry *get_do_entry (uint16_t tag); #define GNUK_DO_PRVKEY_SIG 0xff01 @@ -243,11 +242,11 @@ copy_tag (uint16_t tag) } static int -do_hist_bytes (uint16_t tag) +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 */ - copy_do_1 (tag, historical_bytes); + copy_do_1 (tag, historical_bytes, with_tag); return 0; } @@ -255,7 +254,7 @@ do_hist_bytes (uint16_t tag) #define SIZE_KGTIME 4 static int -do_fp_all (uint16_t tag) +do_fp_all (uint16_t tag, int with_tag) { const uint8_t *data; @@ -290,7 +289,7 @@ do_fp_all (uint16_t tag) } static int -do_cafp_all (uint16_t tag) +do_cafp_all (uint16_t tag, int with_tag) { const uint8_t *data; @@ -325,7 +324,7 @@ do_cafp_all (uint16_t tag) } static int -do_kgtime_all (uint16_t tag) +do_kgtime_all (uint16_t tag, int with_tag) { const uint8_t *data; @@ -359,7 +358,8 @@ do_kgtime_all (uint16_t tag) } static int -rw_pw_status (uint16_t tag, const uint8_t *data, int len, int is_write) +rw_pw_status (uint16_t tag, int with_tag, + const uint8_t *data, int len, int is_write) { const uint8_t *do_data = do_ptr[NR_DO_PW_STATUS]; @@ -784,14 +784,14 @@ proc_key_import (const uint8_t *data, int len) GPG_SUCCESS (); } -static const uint16_t const cn_ch_data[] = { +static const uint16_t const cmp_ch_data[] = { 3, GPG_DO_NAME, GPG_DO_LANGUAGE, GPG_DO_SEX, }; -static const uint16_t const cn_app_data[] = { +static const uint16_t const cmp_app_data[] = { 10, GPG_DO_AID, GPG_DO_HIST_BYTES, @@ -802,7 +802,7 @@ static const uint16_t const cn_app_data[] = { GPG_DO_FP_ALL, GPG_DO_CAFP_ALL, GPG_DO_KGTIME_ALL }; -static const uint16_t const cn_ss_temp[] = { 1, GPG_DO_DS_COUNT }; +static const uint16_t const cmp_ss_temp[] = { 1, GPG_DO_DS_COUNT }; static const struct do_table_entry gpg_do_table[] = { @@ -848,9 +848,9 @@ gpg_do_table[] = { { GPG_DO_ALG_DEC, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr }, { GPG_DO_ALG_AUT, DO_FIXED, AC_ALWAYS, AC_NEVER, algorithm_attr }, /* Compound data: Read access only */ - { GPG_DO_CH_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_ch_data }, - { GPG_DO_APP_DATA, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_app_data }, - { GPG_DO_SS_TEMP, DO_CN_READ, AC_ALWAYS, AC_NEVER, cn_ss_temp }, + { GPG_DO_CH_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ch_data }, + { GPG_DO_APP_DATA, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_app_data }, + { GPG_DO_SS_TEMP, DO_CMP_READ, AC_ALWAYS, AC_NEVER, cmp_ss_temp }, /* Simple data: write access only */ { GPG_DO_RESETTING_CODE, DO_PROC_WRITE, AC_NEVER, AC_ADMIN_AUTHORIZED, proc_resetting_code }, @@ -934,7 +934,7 @@ get_do_entry (uint16_t tag) } static void -copy_do_1 (uint16_t tag, const uint8_t *do_data) +copy_do_1 (uint16_t tag, const uint8_t *do_data, int with_tag) { int len; @@ -973,7 +973,7 @@ copy_do_1 (uint16_t tag, const uint8_t *do_data) } static int -copy_do (const struct do_table_entry *do_p) +copy_do (const struct do_table_entry *do_p, int with_tag) { if (do_p == NULL) return 0; @@ -989,7 +989,7 @@ copy_do (const struct do_table_entry *do_p) if (do_data == NULL) return 0; else - copy_do_1 (do_p->tag, do_data); + copy_do_1 (do_p->tag, do_data, with_tag); break; } case DO_VAR: @@ -998,30 +998,29 @@ copy_do (const struct do_table_entry *do_p) if (do_data == NULL) return 0; else - copy_do_1 (do_p->tag, do_data); + copy_do_1 (do_p->tag, do_data, with_tag); break; } - case DO_CN_READ: + case DO_CMP_READ: { int i; - const uint16_t *cn_data = (const uint16_t *)do_p->obj; - int num_components = cn_data[0]; + const uint16_t *cmp_data = (const uint16_t *)do_p->obj; + int num_components = cmp_data[0]; uint8_t *len_p; copy_tag (do_p->tag); - *res_p++ = 0x81; + *res_p++ = 0x81; /* Assume it's less than 256 */ len_p = res_p; *res_p++ = 0; /* for now */ - with_tag = 1; for (i = 0; i < num_components; i++) { uint16_t tag0; const struct do_table_entry *do0_p; - tag0 = cn_data[i+1]; + tag0 = cmp_data[i+1]; do0_p = get_do_entry (tag0); - if (copy_do (do0_p) < 0) + if (copy_do (do0_p, 1) < 0) return -1; } @@ -1030,16 +1029,16 @@ copy_do (const struct do_table_entry *do_p) } case DO_PROC_READ: { - int (*do_func)(uint16_t) = (int (*)(uint16_t))do_p->obj; + int (*do_func)(uint16_t, int) = (int (*)(uint16_t, int))do_p->obj; - return do_func (do_p->tag); + return do_func (do_p->tag, with_tag); } case DO_PROC_READWRITE: { - int (*rw_func)(uint16_t, uint8_t *, int, int) - = (int (*)(uint16_t, uint8_t *, int, int))do_p->obj; + int (*rw_func)(uint16_t, int, uint8_t *, int, int) + = (int (*)(uint16_t, int, uint8_t *, int, int))do_p->obj; - return rw_func (do_p->tag, NULL, 0, 0); + return rw_func (do_p->tag, with_tag, NULL, 0, 0); } case DO_PROC_WRITE: return -1; @@ -1058,14 +1057,13 @@ gpg_do_get_data (uint16_t tag) const struct do_table_entry *do_p = get_do_entry (tag); res_p = res_APDU; - with_tag = 0; DEBUG_INFO (" "); DEBUG_SHORT (tag); if (do_p) { - if (copy_do (do_p) < 0) + if (copy_do (do_p, 0) < 0) /* Overwriting partially written result */ GPG_SECURITY_FAILURE (); else @@ -1098,7 +1096,7 @@ gpg_do_put_data (uint16_t tag, const uint8_t *data, int len) switch (do_p->do_type) { case DO_FIXED: - case DO_CN_READ: + case DO_CMP_READ: case DO_PROC_READ: GPG_SECURITY_FAILURE (); break; @@ -1112,6 +1110,8 @@ gpg_do_put_data (uint16_t tag, const uint8_t *data, int len) if (len == 0) /* make DO empty */ *do_data_p = NULL; + else if (len > 255) + GPG_MEMORY_FAILURE(); else { uint8_t nr = do_tag_to_nr (tag); @@ -1126,10 +1126,10 @@ gpg_do_put_data (uint16_t tag, const uint8_t *data, int len) } case DO_PROC_READWRITE: { - int (*rw_func)(uint16_t, const uint8_t *, int, int) - = (int (*)(uint16_t, const uint8_t *, int, int))do_p->obj; + int (*rw_func)(uint16_t, int, const uint8_t *, int, int) + = (int (*)(uint16_t, int, const uint8_t *, int, int))do_p->obj; - rw_func (tag, data, len, 1); + rw_func (tag, 0, data, len, 1); break; } case DO_PROC_WRITE: