1
0
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:
AKASHI Takahiro
2020-02-21 15:12:55 +09:00
committed by Tom Rini
parent d08b16edf8
commit b983cc2da0
11 changed files with 501 additions and 438 deletions

View File

@@ -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;
}
}
}