Bug fix for flash ROM garbage collection
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user