After checking hashes, also check signatures of FIT images.
Signed-off-by: Simon Glass
---
common/image-fit.c | 80
common/image-sig.c | 148
include/image.h| 37 +
3 files changed, 243 insertions(+), 22 deletions(-)
diff --git a/common/image-fit.c b/common/image-fit.c
index ed98460..d255595 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -31,6 +31,8 @@
#include
#else
#include
+#include
+DECLARE_GLOBAL_DATA_PTR;
#endif /* !USE_HOSTCC*/
#include
@@ -235,42 +237,42 @@ void fit_print_contents(const void *fit)
* @fit: pointer to the FIT format image header
* @noffset: offset of the hash node
* @p: pointer to prefix string
+ * @type: Type of information to print ("hash" or "sign")
*
* fit_image_print_data() lists properies for the processed hash node
*
* returns:
* no returned results
*/
-static void fit_image_print_data(const void *fit, int noffset, const char *p)
+static void fit_image_print_data(const void *fit, int noffset, const char *p,
+const char *type)
{
- char *algo;
+ const char *keyname;
uint8_t *value;
int value_len;
- int i, ret;
-
- /*
-* Check subnode name, must be equal to "hash".
-* Multiple hash nodes require unique unit node
-* names, e.g. hash@1, hash@2, etc.
-*/
- if (strncmp(fit_get_name(fit, noffset, NULL),
- FIT_HASH_NODENAME,
- strlen(FIT_HASH_NODENAME)) != 0)
- return;
-
- debug("%s Hash node:'%s'\n", p,
- fit_get_name(fit, noffset, NULL));
+ char *algo;
+ int required;
+ int ret, i;
- printf("%s Hash algo:", p);
+ debug("%s %s node:'%s'\n", p, type,
+ fit_get_name(fit, noffset, NULL));
+ printf("%s %s algo:", p, type);
if (fit_image_hash_get_algo(fit, noffset, &algo)) {
printf("invalid/unsupported\n");
return;
}
- printf("%s\n", algo);
+ printf("%s", algo);
+ keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
+ required = fdt_getprop(fit, noffset, "required", NULL) != NULL;
+ if (keyname)
+ printf(":%s", keyname);
+ if (required)
+ printf(" (required)");
+ printf("\n");
ret = fit_image_hash_get_value(fit, noffset, &value,
&value_len);
- printf("%s Hash value: ", p);
+ printf("%s %s value: ", p, type);
if (ret) {
printf("unavailable\n");
} else {
@@ -279,7 +281,18 @@ static void fit_image_print_data(const void *fit, int
noffset, const char *p)
printf("\n");
}
- debug("%s Hash len: %d\n", p, value_len);
+ debug("%s %s len: %d\n", p, type, value_len);
+
+ /* Signatures have a time stamp */
+ if (IMAGE_ENABLE_TIMESTAMP && keyname) {
+ time_t timestamp;
+
+ printf("%s Timestamp:", p);
+ if (fit_get_timestamp(fit, noffset, ×tamp))
+ printf("unavailable\n");
+ else
+ genimg_print_time(timestamp);
+ }
}
/**
@@ -304,8 +317,12 @@ static void fit_image_print_verification_data(const void
*fit, int noffset,
* names, e.g. hash@1, hash@2, signature@1, signature@2, etc.
*/
name = fit_get_name(fit, noffset, NULL);
- if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME)))
- fit_image_print_data(fit, noffset, p);
+ if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
+ fit_image_print_data(fit, noffset, p, "Hash");
+ } else if (!strncmp(name, FIT_SIG_NODENAME,
+ strlen(FIT_SIG_NODENAME))) {
+ fit_image_print_data(fit, noffset, p, "Sign");
+ }
}
/**
@@ -952,6 +969,8 @@ int fit_image_verify(const void *fit, int image_noffset)
int noffset;
int ndepth;
char*err_msg = "";
+ int verify_all = 1;
+ int ret;
/* Get image data and data length */
if (fit_image_get_data(fit, image_noffset, &data, &size)) {
@@ -959,6 +978,14 @@ int fit_image_verify(const void *fit, int image_noffset)
return 0;
}
+ /* Verify all required signatures */
+ if (IMAGE_ENABLE_VERIFY &&
+ fit_image_verify_required_sigs(fit, image_noffset,
+ data, size, gd_fdt_blob(), &verify_all)) {
+ err_msg = "Unable to verify required signature";
+ goto error;
+ }
+
/* Process all hash subnodes of the component image node */
for (ndepth = 0,
noffset