/** * fit_image_process_sig- Process a single subnode of the images/ node * * Check each subnode and process accordingly. For signature nodes we * generate a signed hash of the supplised data and store it in the node. * * @keydir: Directory containing keys to use for signing * @keydest: Destination FDT blob to write public keys into * @fit: pointer to the FIT format image header * @image_name: name of image being processes (used to display errors) * @noffset: subnode offset * @data: data to process * @size: size of data in bytes * @comment: Comment to add to signature nodes * @require_keys: Mark all keys as 'required' * @engine_id: Engine to use for signing * @return 0 if ok, -1 on error */ static int fit_image_process_sig(const char *keydir, void *keydest, void *fit, const char *image_name, int noffset, const void *data, size_t size, const char *comment, int require_keys, const char *engine_id) { struct image_sign_info info; struct image_region region; const char *node_name; uint8_t *value; uint value_len; int ret; if (fit_image_setup_sig(&info, keydir, fit, image_name, noffset, require_keys ? "image" : NULL, engine_id)) return -1; node_name = fit_get_name(fit, noffset, NULL); region.data = data; region.size = size; ret = info.crypto->sign(&info, ®ion, 1, &value, &value_len); if (ret) { printf("Failed to sign '%s' signature node in '%s' image node: %d\n", node_name, image_name, ret); /* We allow keys to be missing */ if (ret == -ENOENT) return 0; return -1; } ret = fit_image_write_sig(fit, noffset, value, value_len, comment, NULL, 0); if (ret) { if (ret == -FDT_ERR_NOSPACE) return -ENOSPC; printf("Can't write signature for '%s' signature node in '%s' conf node: %s\n", node_name, image_name, fdt_strerror(ret)); return -1; } free(value); /* Get keyname again, as FDT has changed and invalidated our pointer */ info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL); /* * Write the public key into the supplied FDT file; this might fail * several times, since we try signing with successively increasing * size values */ if (keydest) { ret = info.crypto->add_verify_data(&info, keydest); if (ret) { printf("Failed to add verification data for '%s' signature node in '%s' image node\n", node_name, image_name); return ret; } } return 0; }
static int fit_config_process_sig(const char *keydir, void *keydest, void *fit, const char *conf_name, int conf_noffset, int noffset, const char *comment, int require_keys) { struct image_sign_info info; const char *node_name; struct image_region *region; char *region_prop; int region_proplen; int region_count; uint8_t *value; uint value_len; int ret; node_name = fit_get_name(fit, noffset, NULL); if (fit_config_get_data(fit, conf_noffset, noffset, ®ion, ®ion_count, ®ion_prop, ®ion_proplen)) return -1; if (fit_image_setup_sig(&info, keydir, fit, conf_name, noffset, require_keys ? "conf" : NULL)) return -1; ret = info.algo->sign(&info, region, region_count, &value, &value_len); free(region); if (ret) { printf("Failed to sign '%s' signature node in '%s' conf node\n", node_name, conf_name); /* We allow keys to be missing */ if (ret == -ENOENT) return 0; return -1; } if (fit_image_write_sig(fit, noffset, value, value_len, comment, region_prop, region_proplen)) { printf("Can't write signature for '%s' signature node in '%s' conf node\n", node_name, conf_name); return -1; } free(value); free(region_prop); /* Get keyname again, as FDT has changed and invalidated our pointer */ info.keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL); /* Write the public key into the supplied FDT file */ if (keydest && info.algo->add_verify_data(&info, keydest)) { printf("Failed to add verification data for '%s' signature node in '%s' image node\n", node_name, conf_name); return -1; } return 0; }