summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/lib20/misc.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/firmware/lib20/misc.c b/firmware/lib20/misc.c
index 0fa80e1d..c81c3fed 100644
--- a/firmware/lib20/misc.c
+++ b/firmware/lib20/misc.c
@@ -73,7 +73,6 @@ vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx)
uint8_t *key_data;
uint32_t key_size;
- struct vb2_packed_key *packed_key;
struct vb2_public_key root_key;
struct vb2_keyblock *kb;
@@ -150,34 +149,33 @@ vb2_error_t vb2_load_fw_keyblock(struct vb2_context *ctx)
sd->fw_version = kb->data_key.key_version << 16;
+ /* Preamble follows the keyblock in the vblock. */
+ sd->vblock_preamble_offset = kb->keyblock_size;
+
/*
- * Save the data key in the work buffer. This overwrites the root key
+ * Save the data key in the work buffer. We'll overwrite the root key
* we read above. That's ok, because now that we have the data key we
- * no longer need the root key.
+ * no longer need the root key. First, let's double-check that it is
+ * well-formed though (although the keyblock was signed anyway).
*/
- packed_key = (struct vb2_packed_key *)key_data;
+ rv = vb2_verify_packed_key_inside(kb, block_size, &kb->data_key);
+ if (rv)
+ return rv;
- packed_key->algorithm = kb->data_key.algorithm;
- packed_key->key_version = kb->data_key.key_version;
- packed_key->key_size = kb->data_key.key_size;
+ /* Save the future offset and size while kb->data_key is still valid.
+ The check above made sure that key_offset and key_size are sane. */
+ sd->data_key_offset = vb2_offset_of(sd, key_data);
+ sd->data_key_size = kb->data_key.key_offset + kb->data_key.key_size;
/*
* Use memmove() instead of memcpy(). In theory, the destination will
* never overlap because with the source because the root key is likely
* to be at least as large as the data key, but there's no harm here in
- * being paranoid.
+ * being paranoid. Make sure we immediately invalidate 'kb' after the
+ * move to guarantee we won't try to access it anymore.
*/
- memmove(key_data + packed_key->key_offset,
- (uint8_t*)&kb->data_key + kb->data_key.key_offset,
- packed_key->key_size);
-
- /* Save the packed key offset and size */
- sd->data_key_offset = vb2_offset_of(sd, key_data);
- sd->data_key_size =
- packed_key->key_offset + packed_key->key_size;
-
- /* Preamble follows the keyblock in the vblock */
- sd->vblock_preamble_offset = kb->keyblock_size;
+ memmove(key_data, &kb->data_key, sd->data_key_size);
+ kb = NULL;
/*
* Data key will persist in the workbuf after we return.