*/
#include "mkimage.h"
+#include <bootm.h>
#include <image.h>
#include <version.h>
printf("Can't set hash '%s' property for '%s' node(%s)\n",
FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL),
fdt_strerror(ret));
- return -1;
+ return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -EIO;
}
return 0;
const char *node_name;
int value_len;
char *algo;
+ int ret;
node_name = fit_get_name(fit, noffset, NULL);
if (fit_image_hash_get_algo(fit, noffset, &algo)) {
printf("Can't get hash algo property for '%s' hash node in '%s' image node\n",
node_name, image_name);
- return -1;
+ return -ENOENT;
}
if (calculate_hash(data, size, algo, value, &value_len)) {
printf("Unsupported hash algorithm (%s) for '%s' hash node in '%s' image node\n",
algo, node_name, image_name);
- return -1;
+ return -EPROTONOSUPPORT;
}
- if (fit_set_hash_value(fit, noffset, value, value_len)) {
+ ret = fit_set_hash_value(fit, noffset, value, value_len);
+ if (ret) {
printf("Can't set hash value for '%s' hash node in '%s' image node\n",
node_name, image_name);
- return -1;
+ return ret;
}
return 0;
static int fit_image_setup_sig(struct image_sign_info *info,
const char *keydir, void *fit, const char *image_name,
- int noffset, const char *require_keys)
+ int noffset, const char *require_keys, const char *engine_id)
{
const char *node_name;
char *algo_name;
info->keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
info->fit = fit;
info->node_offset = noffset;
- info->algo = image_get_sig_algo(algo_name);
+ info->name = algo_name;
+ info->checksum = image_get_checksum_algo(algo_name);
+ info->crypto = image_get_crypto_algo(algo_name);
info->require_keys = require_keys;
- if (!info->algo) {
+ info->engine_id = engine_id;
+ if (!info->checksum || !info->crypto) {
printf("Unsupported signature algorithm (%s) for '%s' signature node in '%s' image node\n",
algo_name, node_name, image_name);
return -1;
* @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 *comment, int require_keys, const char *engine_id)
{
struct image_sign_info info;
struct image_region region;
int ret;
if (fit_image_setup_sig(&info, keydir, fit, image_name, noffset,
- require_keys ? "image" : NULL))
+ require_keys ? "image" : NULL, engine_id))
return -1;
node_name = fit_get_name(fit, noffset, NULL);
region.data = data;
region.size = size;
- ret = info.algo->sign(&info, ®ion, 1, &value, &value_len);
+ 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);
ret = fit_image_write_sig(fit, noffset, value, value_len, comment,
NULL, 0);
if (ret) {
- printf("Can't write signature for '%s' signature node in '%s' image node: %s\n",
+ 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;
}
/* 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, image_name);
+ if (keydest)
+ ret = info.crypto->add_verify_data(&info, keydest);
+ else
return -1;
- }
+
+ /*
+ * 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)
+ return ret;
return 0;
}
* @image_noffset: Requested component image node
* @comment: Comment to add to signature nodes
* @require_keys: Mark all keys as 'required'
+ * @engine_id: Engine to use for signing
* @return: 0 on success, <0 on failure
*/
int fit_image_add_verification_data(const char *keydir, void *keydest,
void *fit, int image_noffset, const char *comment,
- int require_keys)
+ int require_keys, const char *engine_id)
{
const char *image_name;
const void *data;
strlen(FIT_SIG_NODENAME))) {
ret = fit_image_process_sig(keydir, keydest,
fit, image_name, noffset, data, size,
- comment, require_keys);
+ comment, require_keys, engine_id);
}
if (ret)
- return -1;
+ 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)
+ int noffset, const char *comment, int require_keys,
+ const char *engine_id)
{
struct image_sign_info info;
const char *node_name;
return -1;
if (fit_image_setup_sig(&info, keydir, fit, conf_name, noffset,
- require_keys ? "conf" : NULL))
+ require_keys ? "conf" : NULL, engine_id))
return -1;
- ret = info.algo->sign(&info, region, region_count, &value, &value_len);
+ ret = info.crypto->sign(&info, region, region_count, &value,
+ &value_len);
free(region);
if (ret) {
printf("Failed to sign '%s' signature node in '%s' conf node\n",
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);
+ ret = fit_image_write_sig(fit, noffset, value, value_len, comment,
+ region_prop, region_proplen);
+ 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, conf_name, fdt_strerror(ret));
return -1;
}
free(value);
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;
+ if (keydest) {
+ ret = info.crypto->add_verify_data(&info, keydest);
+ if (ret == -ENOSPC)
+ return -ENOSPC;
+ if (ret) {
+ printf("Failed to add verification data for '%s' signature node in '%s' image node\n",
+ node_name, conf_name);
+ }
+ return ret;
}
return 0;
static int fit_config_add_verification_data(const char *keydir, void *keydest,
void *fit, int conf_noffset, const char *comment,
- int require_keys)
+ int require_keys, const char *engine_id)
{
const char *conf_name;
int noffset;
strlen(FIT_SIG_NODENAME))) {
ret = fit_config_process_sig(keydir, keydest,
fit, conf_name, conf_noffset, noffset, comment,
- require_keys);
+ require_keys, engine_id);
}
if (ret)
return ret;
}
int fit_add_verification_data(const char *keydir, void *keydest, void *fit,
- const char *comment, int require_keys)
+ const char *comment, int require_keys,
+ const char *engine_id)
{
int images_noffset, confs_noffset;
int noffset;
* i.e. component image node.
*/
ret = fit_image_add_verification_data(keydir, keydest,
- fit, noffset, comment, require_keys);
+ fit, noffset, comment, require_keys, engine_id);
if (ret)
return ret;
}
confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
if (confs_noffset < 0) {
printf("Can't find images parent node '%s' (%s)\n",
- FIT_IMAGES_PATH, fdt_strerror(confs_noffset));
+ FIT_CONFS_PATH, fdt_strerror(confs_noffset));
return -ENOENT;
}
noffset = fdt_next_subnode(fit, noffset)) {
ret = fit_config_add_verification_data(keydir, keydest,
fit, noffset, comment,
- require_keys);
+ require_keys,
+ engine_id);
if (ret)
return ret;
}
return 0;
}
+
+#ifdef CONFIG_FIT_SIGNATURE
+int fit_check_sign(const void *fit, const void *key)
+{
+ int cfg_noffset;
+ int ret;
+
+ cfg_noffset = fit_conf_get_node(fit, NULL);
+ if (!cfg_noffset)
+ return -1;
+
+ printf("Verifying Hash Integrity ... ");
+ ret = fit_config_verify(fit, cfg_noffset);
+ if (ret)
+ return ret;
+ ret = bootm_host_load_images(fit, cfg_noffset);
+
+ return ret;
+}
+#endif