Bug fix for flash ROM garbage collection

This commit is contained in:
NIIBE Yutaka
2013-10-10 13:46:18 +09:00
parent e0d7045239
commit e73ebbe33f
3 changed files with 37 additions and 18 deletions

View File

@@ -1,5 +1,11 @@
2013-10-10 Niibe Yutaka <gniibe@fsij.org> 2013-10-10 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp-do.c (gpg_do_write_prvkey): Two phase write to
work with garbage collection.
* src/openpgp.c (cmd_change_password): Call gpg_do_write_simple
after accessing the data object (it may cause garbage collection).
* polarssl/library/bignum.c (mpi_montred): Constant time for * polarssl/library/bignum.c (mpi_montred): Constant time for
carry propagation. Bug fix for carry propagation. carry propagation. Bug fix for carry propagation.
(mpi_exp_mod): Bug fix. Shrink the size of RR as same as X. (mpi_exp_mod): Bug fix. Shrink the size of RR as same as X.

View File

@@ -890,37 +890,46 @@ gpg_do_write_prvkey (enum kind_of_key kk, const uint8_t *key_data, int key_len,
if (++num_prv_keys == NUM_ALL_PRV_KEYS) /* All keys are registered. */ if (++num_prv_keys == NUM_ALL_PRV_KEYS) /* All keys are registered. */
{ {
uint8_t ks_info[KS_META_SIZE]; uint8_t ks_info0[KS_META_SIZE];
uint8_t ks_info1[KS_META_SIZE];
/* Remove contents of keystrings from DO, but length, salt, and iter. */ /* Remove contents of keystrings from DO, but length, salt, and iter. */
if ((ks_pw1_len & PW_LEN_KEYSTRING_BIT)) if ((ks_pw1_len & PW_LEN_KEYSTRING_BIT))
{ {
ks_pw1_len &= PW_LEN_MASK; ks_info0[0] = ks_pw1_len & PW_LEN_MASK;
ks_info[0] = ks_pw1_len; memcpy (KS_GET_SALT (ks_info0), KS_GET_SALT (ks_pw1), SALT_SIZE);
memcpy (KS_GET_SALT (ks_info), KS_GET_SALT (ks_pw1), SALT_SIZE); ks_info0[KEYSTRING_PASSLEN_SIZE+KEYSTRING_SALT_SIZE] = S2K_ITER;
ks_info[KEYSTRING_PASSLEN_SIZE+KEYSTRING_SALT_SIZE] = S2K_ITER;
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, ks_info, KS_META_SIZE);
} }
if ((ks_rc_len & PW_LEN_KEYSTRING_BIT)) if ((ks_rc_len & PW_LEN_KEYSTRING_BIT))
{ {
ks_rc_len &= PW_LEN_MASK; ks_info1[0] = ks_rc_len & PW_LEN_MASK;
ks_info[0] = ks_rc_len; memcpy (KS_GET_SALT (ks_info1), KS_GET_SALT (ks_rc), SALT_SIZE);
memcpy (KS_GET_SALT (ks_info), KS_GET_SALT (ks_rc), SALT_SIZE); ks_info1[KEYSTRING_PASSLEN_SIZE+KEYSTRING_SALT_SIZE] = S2K_ITER;
ks_info[KEYSTRING_PASSLEN_SIZE+KEYSTRING_SALT_SIZE] = S2K_ITER;
gpg_do_write_simple (NR_DO_KEYSTRING_RC, ks_info, KS_META_SIZE);
} }
/*
* Note that gpg_do_write_simple may result garbage collection
* for flash ROM. Thus, it must be two phase.
*/
if ((ks_pw1_len & PW_LEN_KEYSTRING_BIT))
gpg_do_write_simple (NR_DO_KEYSTRING_PW1, ks_info0, KS_META_SIZE);
if ((ks_rc_len & PW_LEN_KEYSTRING_BIT))
gpg_do_write_simple (NR_DO_KEYSTRING_RC, ks_info1, KS_META_SIZE);
if (keystring_admin) if (keystring_admin)
{ {
const uint8_t *ks_admin = gpg_do_read_simple (NR_DO_KEYSTRING_PW3); const uint8_t *ks_admin = gpg_do_read_simple (NR_DO_KEYSTRING_PW3);
if (ks_admin != NULL) if (ks_admin != NULL)
{ {
ks_info[0] = ks_admin[0] & PW_LEN_MASK; ks_info0[0] = ks_admin[0] & PW_LEN_MASK;
memcpy (KS_GET_SALT (ks_info), KS_GET_SALT (ks_admin), SALT_SIZE); memcpy (KS_GET_SALT (ks_info0), KS_GET_SALT (ks_admin),
ks_info[KEYSTRING_PASSLEN_SIZE+KEYSTRING_SALT_SIZE] = S2K_ITER; SALT_SIZE);
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, ks_info, KS_META_SIZE); ks_info0[KEYSTRING_PASSLEN_SIZE+KEYSTRING_SALT_SIZE] = S2K_ITER;
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, ks_info0, KS_META_SIZE);
} }
else else
{ {

View File

@@ -355,7 +355,6 @@ cmd_change_password (void)
{ {
newpw_len = strlen (OPENPGP_CARD_INITIAL_PW3); newpw_len = strlen (OPENPGP_CARD_INITIAL_PW3);
memcpy (newpw, OPENPGP_CARD_INITIAL_PW3, newpw_len); memcpy (newpw, OPENPGP_CARD_INITIAL_PW3, newpw_len);
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, NULL, 0);
newsalt_len = 0; newsalt_len = 0;
pw3_null = 1; pw3_null = 1;
} }
@@ -405,15 +404,20 @@ cmd_change_password (void)
} }
else if (r > 0 && who == BY_ADMIN) else if (r > 0 && who == BY_ADMIN)
{ {
if (!pw3_null) if (pw3_null)
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, NULL, 0);
else
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, new_ks0, KS_META_SIZE); gpg_do_write_simple (NR_DO_KEYSTRING_PW3, new_ks0, KS_META_SIZE);
ac_reset_admin (); ac_reset_admin ();
DEBUG_INFO ("Changed length of DO_KEYSTRING_PW3.\r\n"); DEBUG_INFO ("Changed length of DO_KEYSTRING_PW3.\r\n");
GPG_SUCCESS (); GPG_SUCCESS ();
} }
else /* r == 0 && who == BY_ADMIN */ /* no prvkey */ else /* r == 0 && who == BY_ADMIN */ /* no prvkey */
{ {
if (!pw3_null) if (pw3_null)
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, NULL, 0);
else
{ {
new_ks0[0] |= PW_LEN_KEYSTRING_BIT; new_ks0[0] |= PW_LEN_KEYSTRING_BIT;
gpg_do_write_simple (NR_DO_KEYSTRING_PW3, new_ks0, KEYSTRING_SIZE); gpg_do_write_simple (NR_DO_KEYSTRING_PW3, new_ks0, KEYSTRING_SIZE);