int fit_image_check_sig(const void *fit, int noffset, const void *data, size_t size, int required_keynode, char **err_msgp) { struct image_sign_info info; struct image_region region; uint8_t *fit_value; int fit_value_len; *err_msgp = NULL; if (fit_image_setup_verify(&info, fit, noffset, required_keynode, err_msgp)) return -1; if (fit_image_hash_get_value(fit, noffset, &fit_value, &fit_value_len)) { *err_msgp = "Can't get hash value property"; return -1; } region.data = data; region.size = size; if (info.algo->verify(&info, ®ion, 1, fit_value, fit_value_len)) { *err_msgp = "Verification failed"; return -1; } return 0; }
/** * fit_image_print_data() - prints out the hash node details * @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 * * This function avoid using puts() since it prints a newline on the host * but does not in U-Boot. * * returns: * no returned results */ static void fit_image_print_data(const void *fit, int noffset, const char *p, const char *type) { const char *keyname; uint8_t *value; int value_len; char *algo; int required; int ret, i; 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", 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 %s value: ", p, type); if (ret) { printf("unavailable\n"); } else { for (i = 0; i < value_len; i++) printf("%02x", value[i]); printf("\n"); } 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); } }
static int fit_image_check_hash(const void *fit, int noffset, const void *data, size_t size, char **err_msgp) { uint8_t value[FIT_MAX_HASH_LEN]; int value_len; char *algo; uint8_t *fit_value; int fit_value_len; int ignore; *err_msgp = NULL; if (fit_image_hash_get_algo(fit, noffset, &algo)) { *err_msgp = "Can't get hash algo property"; return -1; } printf("%s", algo); if (IMAGE_ENABLE_IGNORE) { fit_image_hash_get_ignore(fit, noffset, &ignore); if (ignore) { printf("-skipped "); return 0; } } if (fit_image_hash_get_value(fit, noffset, &fit_value, &fit_value_len)) { *err_msgp = "Can't get hash value property"; return -1; } if (calculate_hash(data, size, algo, value, &value_len)) { *err_msgp = "Unsupported hash algorithm"; return -1; } if (value_len != fit_value_len) { *err_msgp = "Bad hash value len"; return -1; } else if (memcmp(value, fit_value, value_len) != 0) { *err_msgp = "Bad hash value"; return -1; } return 0; }
int fit_config_check_sig(const void *fit, int noffset, int required_keynode, char **err_msgp) { char * const exc_prop[] = {"data"}; const char *prop, *end, *name; struct image_sign_info info; const uint32_t *strings; uint8_t *fit_value; int fit_value_len; int max_regions; int i, prop_len; char path[200]; int count; debug("%s: fdt=%p, conf='%s', sig='%s'\n", __func__, gd_fdt_blob(), fit_get_name(fit, noffset, NULL), fit_get_name(gd_fdt_blob(), required_keynode, NULL)); *err_msgp = NULL; if (fit_image_setup_verify(&info, fit, noffset, required_keynode, err_msgp)) return -1; if (fit_image_hash_get_value(fit, noffset, &fit_value, &fit_value_len)) { *err_msgp = "Can't get hash value property"; return -1; } /* Count the number of strings in the property */ prop = fdt_getprop(fit, noffset, "hashed-nodes", &prop_len); end = prop ? prop + prop_len : prop; for (name = prop, count = 0; name < end; name++) if (!*name) count++; if (!count) { *err_msgp = "Can't get hashed-nodes property"; return -1; } /* Add a sanity check here since we are using the stack */ if (count > IMAGE_MAX_HASHED_NODES) { *err_msgp = "Number of hashed nodes exceeds maximum"; return -1; } /* Create a list of node names from those strings */ char *node_inc[count]; debug("Hash nodes (%d):\n", count); for (name = prop, i = 0; name < end; name += strlen(name) + 1, i++) { debug(" '%s'\n", name); node_inc[i] = (char *)name; } /* * Each node can generate one region for each sub-node. Allow for * 7 sub-nodes (hash@1, signature@1, etc.) and some extra. */ max_regions = 20 + count * 7; struct fdt_region fdt_regions[max_regions]; /* Get a list of regions to hash */ count = fdt_find_regions(fit, node_inc, count, exc_prop, ARRAY_SIZE(exc_prop), fdt_regions, max_regions - 1, path, sizeof(path), 0); if (count < 0) { *err_msgp = "Failed to hash configuration"; return -1; } if (count == 0) { *err_msgp = "No data to hash"; return -1; } if (count >= max_regions - 1) { *err_msgp = "Too many hash regions"; return -1; } /* Add the strings */ strings = fdt_getprop(fit, noffset, "hashed-strings", NULL); if (strings) { fdt_regions[count].offset = fdt_off_dt_strings(fit) + fdt32_to_cpu(strings[0]); fdt_regions[count].size = fdt32_to_cpu(strings[1]); count++; } /* Allocate the region list on the stack */ struct image_region region[count]; fit_region_make_list(fit, fdt_regions, count, region); if (info.algo->verify(&info, region, count, fit_value, fit_value_len)) { *err_msgp = "Verification failed"; return -1; } return 0; }