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
@@ -18,6 +18,16 @@ if RSA
|
||||
config SPL_RSA
|
||||
bool "Use RSA Library within SPL"
|
||||
|
||||
config SPL_RSA_VERIFY
|
||||
bool
|
||||
help
|
||||
Add RSA signature verification support in SPL.
|
||||
|
||||
config RSA_VERIFY
|
||||
bool
|
||||
help
|
||||
Add RSA signature verification support.
|
||||
|
||||
config RSA_SOFTWARE_EXP
|
||||
bool "Enable driver for RSA Modular Exponentiation in software"
|
||||
depends on DM
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
# (C) Copyright 2000-2007
|
||||
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||
|
||||
obj-$(CONFIG_$(SPL_)FIT_SIGNATURE) += rsa-verify.o rsa-checksum.o
|
||||
obj-$(CONFIG_$(SPL_)RSA_VERIFY) += rsa-verify.o rsa-checksum.o
|
||||
obj-$(CONFIG_RSA_SOFTWARE_EXP) += rsa-mod-exp.o
|
||||
|
||||
@@ -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