mirror of
https://xff.cz/git/u-boot/
synced 2025-11-02 03:17:29 +01:00
lib: rsa: decouple rsa from FIT image verification
Introduce new configuration, CONFIG_RSA_VERIFY which will decouple building RSA functions from FIT verification and allow for adding a RSA-based signature verification for other file formats, in particular PE file for UEFI secure boot. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
committed by
Tom Rini
parent
d08b16edf8
commit
b983cc2da0
@@ -271,6 +271,7 @@ out:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(FIT_SIGNATURE)
|
||||
/**
|
||||
* rsa_verify_key() - Verify a signature against some data using RSA Key
|
||||
*
|
||||
@@ -342,7 +343,9 @@ static int rsa_verify_key(struct image_sign_info *info,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(FIT_SIGNATURE)
|
||||
/**
|
||||
* rsa_verify_with_keynode() - Verify a signature against some data using
|
||||
* information in node with prperties of RSA Key like modulus, exponent etc.
|
||||
@@ -396,18 +399,22 @@ static int rsa_verify_with_keynode(struct image_sign_info *info,
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
static int rsa_verify_with_keynode(struct image_sign_info *info,
|
||||
const void *hash, uint8_t *sig,
|
||||
uint sig_len, int node)
|
||||
{
|
||||
return -EACCES;
|
||||
}
|
||||
#endif
|
||||
|
||||
int rsa_verify(struct image_sign_info *info,
|
||||
const struct image_region region[], int region_count,
|
||||
uint8_t *sig, uint sig_len)
|
||||
{
|
||||
const void *blob = info->fdt_blob;
|
||||
/* Reserve memory for maximum checksum-length */
|
||||
uint8_t hash[info->crypto->key_len];
|
||||
int ndepth, noffset;
|
||||
int sig_node, node;
|
||||
char name[100];
|
||||
int ret;
|
||||
int ret = -EACCES;
|
||||
|
||||
/*
|
||||
* Verify that the checksum-length does not exceed the
|
||||
@@ -420,12 +427,6 @@ int rsa_verify(struct image_sign_info *info,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
|
||||
if (sig_node < 0) {
|
||||
debug("%s: No signature node found\n", __func__);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* Calculate checksum with checksum-algorithm */
|
||||
ret = info->checksum->calculate(info->checksum->name,
|
||||
region, region_count, hash);
|
||||
@@ -434,29 +435,44 @@ int rsa_verify(struct image_sign_info *info,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* See if we must use a particular key */
|
||||
if (info->required_keynode != -1) {
|
||||
ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
|
||||
info->required_keynode);
|
||||
return ret;
|
||||
}
|
||||
if (CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
|
||||
const void *blob = info->fdt_blob;
|
||||
int ndepth, noffset;
|
||||
int sig_node, node;
|
||||
char name[100];
|
||||
|
||||
/* Look for a key that matches our hint */
|
||||
snprintf(name, sizeof(name), "key-%s", info->keyname);
|
||||
node = fdt_subnode_offset(blob, sig_node, name);
|
||||
ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node);
|
||||
if (!ret)
|
||||
return ret;
|
||||
sig_node = fdt_subnode_offset(blob, 0, FIT_SIG_NODENAME);
|
||||
if (sig_node < 0) {
|
||||
debug("%s: No signature node found\n", __func__);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/* No luck, so try each of the keys in turn */
|
||||
for (ndepth = 0, noffset = fdt_next_node(info->fit, sig_node, &ndepth);
|
||||
(noffset >= 0) && (ndepth > 0);
|
||||
noffset = fdt_next_node(info->fit, noffset, &ndepth)) {
|
||||
if (ndepth == 1 && noffset != node) {
|
||||
/* See if we must use a particular key */
|
||||
if (info->required_keynode != -1) {
|
||||
ret = rsa_verify_with_keynode(info, hash, sig, sig_len,
|
||||
noffset);
|
||||
if (!ret)
|
||||
break;
|
||||
info->required_keynode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Look for a key that matches our hint */
|
||||
snprintf(name, sizeof(name), "key-%s", info->keyname);
|
||||
node = fdt_subnode_offset(blob, sig_node, name);
|
||||
ret = rsa_verify_with_keynode(info, hash, sig, sig_len, node);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
/* No luck, so try each of the keys in turn */
|
||||
for (ndepth = 0, noffset = fdt_next_node(info->fit, sig_node,
|
||||
&ndepth);
|
||||
(noffset >= 0) && (ndepth > 0);
|
||||
noffset = fdt_next_node(info->fit, noffset, &ndepth)) {
|
||||
if (ndepth == 1 && noffset != node) {
|
||||
ret = rsa_verify_with_keynode(info, hash,
|
||||
sig, sig_len,
|
||||
noffset);
|
||||
if (!ret)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user