Merge branch 'wip/dueno/memcmp' into 'master'

secret-file-collection: Make MAC comparison constant time

See merge request GNOME/libsecret!60
This commit is contained in:
Daiki Ueno 2020-10-04 15:43:01 +00:00
commit 8b4016bd31

View File

@ -130,6 +130,26 @@ do_calculate_mac (SecretFileCollection *self,
return ret; return ret;
} }
static gboolean
do_verify_mac (SecretFileCollection *self,
const guint8 *value, gsize n_value,
const guint8 *data)
{
guint8 buffer[MAC_SIZE];
guint8 status = 0;
gsize i;
if (!do_calculate_mac (self, value, n_value, buffer)) {
return FALSE;
}
for (i = 0; i < MAC_SIZE; i++) {
status |= data[i] ^ buffer[i];
}
return status == 0;
}
static gboolean static gboolean
do_decrypt (SecretFileCollection *self, do_decrypt (SecretFileCollection *self,
guint8 *data, guint8 *data,
@ -479,7 +499,6 @@ hashed_attributes_match (SecretFileCollection *self,
GVariant *hashed_attribute = NULL; GVariant *hashed_attribute = NULL;
gpointer key; gpointer key;
gpointer value; gpointer value;
guint8 buffer[MAC_SIZE];
g_hash_table_iter_init (&iter, attributes); g_hash_table_iter_init (&iter, attributes);
while (g_hash_table_iter_next (&iter, &key, &value)) { while (g_hash_table_iter_next (&iter, &key, &value)) {
@ -497,12 +516,7 @@ hashed_attributes_match (SecretFileCollection *self,
return FALSE; return FALSE;
} }
if (!do_calculate_mac (self, value, strlen ((char *)value), buffer)) { if (!do_verify_mac (self, value, strlen ((char *)value), data)) {
g_variant_unref (hashed_attribute);
return FALSE;
}
if (memcmp (data, buffer, MAC_SIZE) != 0) {
g_variant_unref (hashed_attribute); g_variant_unref (hashed_attribute);
return FALSE; return FALSE;
} }
@ -673,7 +687,6 @@ _secret_file_item_decrypt (GVariant *encrypted,
guint8 *data; guint8 *data;
SecretFileItem *item; SecretFileItem *item;
GVariant *serialized_item; GVariant *serialized_item;
guint8 mac[MAC_SIZE];
g_variant_get (encrypted, "(a{say}@ay)", NULL, &blob); g_variant_get (encrypted, "(a{say}@ay)", NULL, &blob);
@ -691,9 +704,9 @@ _secret_file_item_decrypt (GVariant *encrypted,
"couldn't calculate mac"); "couldn't calculate mac");
return FALSE; return FALSE;
} }
n_padded -= IV_SIZE + MAC_SIZE;
if (!do_calculate_mac (collection, data, n_padded + IV_SIZE, mac)) { n_padded -= MAC_SIZE;
if (!do_verify_mac (collection, data, n_padded, data + n_padded)) {
egg_secure_free (data); egg_secure_free (data);
g_set_error (error, g_set_error (error,
SECRET_ERROR, SECRET_ERROR,
@ -702,15 +715,7 @@ _secret_file_item_decrypt (GVariant *encrypted,
return FALSE; return FALSE;
} }
if (memcmp (data + n_padded + IV_SIZE, mac, MAC_SIZE) != 0) { n_padded -= IV_SIZE;
egg_secure_free (data);
g_set_error (error,
SECRET_ERROR,
SECRET_ERROR_PROTOCOL,
"mac doesn't match");
return FALSE;
}
if (!do_decrypt (collection, data, n_padded)) { if (!do_decrypt (collection, data, n_padded)) {
egg_secure_free (data); egg_secure_free (data);
g_set_error (error, g_set_error (error,