summaryrefslogtreecommitdiff
path: root/futility/cmd_show.c
diff options
context:
space:
mode:
Diffstat (limited to 'futility/cmd_show.c')
-rw-r--r--futility/cmd_show.c68
1 files changed, 60 insertions, 8 deletions
diff --git a/futility/cmd_show.c b/futility/cmd_show.c
index 6ed15435..4b11b50f 100644
--- a/futility/cmd_show.c
+++ b/futility/cmd_show.c
@@ -22,6 +22,7 @@
#include "2common.h"
#include "2sha.h"
#include "2sysincludes.h"
+#include "cbfstool.h"
#include "file_type_bios.h"
#include "file_type.h"
#include "fmap.h"
@@ -181,6 +182,53 @@ done:
return retval;
}
+static int fw_show_metadata_hash(const char *name, enum bios_component body_c,
+ struct vb2_fw_preamble *pre)
+{
+ struct vb2_hash real_hash;
+ struct vb2_hash *body_hash =
+ (struct vb2_hash *)vb2_signature_data(&pre->body_signature);
+ const uint32_t bhsize = vb2_digest_size(body_hash->algo);
+
+ if (!bhsize || pre->body_signature.sig_size <
+ offsetof(struct vb2_hash, raw) + bhsize) {
+ fprintf(stderr, "Body signature data is too small to "
+ "fit metadata hash.\n");
+ return 1;
+ }
+
+ printf(" Body metadata hash: %s",
+ vb2_get_hash_algorithm_name(body_hash->algo));
+ if (vb2_digest_size(body_hash->algo)) {
+ putchar(':');
+ print_bytes((uint8_t *)body_hash->raw,
+ vb2_digest_size(body_hash->algo));
+ }
+ putchar('\n');
+
+ if (cbfstool_get_metadata_hash(name, fmap_name[body_c], &real_hash) !=
+ VB2_SUCCESS ||
+ real_hash.algo == VB2_HASH_INVALID) {
+ fprintf(stderr, "Failed to get metadata hash. Firmware body is"
+ " corrupted or is not a valid CBFS.\n");
+ return 1;
+ }
+
+ if (body_hash->algo != real_hash.algo ||
+ !vb2_digest_size(body_hash->algo) ||
+ memcmp(body_hash->raw, real_hash.raw,
+ vb2_digest_size(body_hash->algo))) {
+ printf(" MISMATCH! Real hash: %s:",
+ vb2_get_hash_algorithm_name(real_hash.algo));
+ print_bytes(&real_hash.raw, vb2_digest_size(real_hash.algo));
+ putchar('\n');
+ fprintf(stderr, "Signature hash does not match with"
+ " real metadata hash.\n");
+ return 1;
+ }
+ return 0;
+}
+
int show_fw_preamble_buf(const char *name, uint8_t *buf, uint32_t len,
void *data)
{
@@ -190,6 +238,7 @@ int show_fw_preamble_buf(const char *name, uint8_t *buf, uint32_t len,
uint8_t *fv_data = show_option.fv;
uint64_t fv_size = show_option.fv_size;
struct bios_area_s *fw_body_area = 0;
+ enum bios_component body_c;
int good_sig = 0;
int retval = 0;
@@ -217,9 +266,8 @@ int show_fw_preamble_buf(const char *name, uint8_t *buf, uint32_t len,
}
/* Identify the firmware body for this VBLOCK */
- enum bios_component body_c = state->c == BIOS_FMAP_VBLOCK_A
- ? BIOS_FMAP_FW_MAIN_A
- : BIOS_FMAP_FW_MAIN_B;
+ body_c = state->c == BIOS_FMAP_VBLOCK_A ? BIOS_FMAP_FW_MAIN_A
+ : BIOS_FMAP_FW_MAIN_B;
fw_body_area = &state->area[body_c];
}
@@ -288,11 +336,15 @@ int show_fw_preamble_buf(const char *name, uint8_t *buf, uint32_t len,
return 0;
}
- if (VB2_SUCCESS !=
- vb2_verify_data(fv_data, fv_size, &pre2->body_signature,
- &data_key, &wb)) {
- fprintf(stderr, "Error verifying firmware body.\n");
- return 1;
+ if (pre2->body_signature.data_size) {
+ if (vb2_verify_data(fv_data, fv_size, &pre2->body_signature,
+ &data_key, &wb) != VB2_SUCCESS) {
+ fprintf(stderr, "Error verifying firmware body.\n");
+ return 1;
+ }
+ } else if (state) { /* Only works for images with at least FW_MAIN_A */
+ if (fw_show_metadata_hash(name, body_c, pre2))
+ return 1;
}
done: