From: "Marko Mäkelä" <marko.makela@iki.fi>
To: u-boot@lists.denx.de
Subject: Re: How to use ECDSA for signature verification?
Date: Sat, 8 Nov 2025 19:24:00 +0200 [thread overview]
Message-ID: <aQ98sHenb3G1MQDi@kehys.lan> (raw)
In-Reply-To: <aO1GvGrXUw-co84_@kehys.lan>
Hi all,
I am new to u-boot, please bear with me. I got CONFIG_FIT_SIGNATURE=y to
work with the RSA algorithm, but not with ECDSA.
My two main questions are:
Is CONFIG_ECDSA_VERIFY only implemented for the two targets:
rom_api_ops in arch/arm/mach-stm32mp/ecdsa_romapi.c
cptra_ecdsa_ops in drivers/crypto/aspeed/cptra_ecdsa.c.
Is it feasible to support something more modern than RSA signatures on a
reasonably high-end target, such as ARMv8? Are there any suggestions or
git commits that you would suggest as a reference?
Mon, Oct 13, 2025 at 09:36:50PM +0300, Marko Mäkelä wrote:
>Hi all,
>
>Yesterday, I successfully built the u-boot master branch with
>CONFIG_FIT_SIGNATURE=y and CONFIG_RSA=y and got the signature
>verification working with sha256,rsa2048.
>
>Today, I wanted to try out CONFIG_ECDSA=y, but I am facing some
>trouble. I am generating the key and trying to add its public part to
>the device tree blob as with fdt_add_pubkey as follows:
I got a bit further with this, using the algorithm sha256,ecdsa256.
With a patch and some work-arounds, I think I understood the host-side
workflow. However, the signature check on my target (TI Sitara am62x) is
failing.
Unlike with RSA, the mkimage command expects the ECDSA private key in a
file like dev.pem, not dev.key. I successfully created a private key and
constructed a signed FIT image with the following commands:
openssl ecparam -name prime256v1 -genkey -noout -out dev.pem
mkimage -k . -f fitImage.its fitImage
I verified the presence of a signature by running the following command,
which produced the signature in a "value" subnode:
dtc -I dtb fitImage|grep -A10 signature
For the algorithm sha256,ecdsa256 that I chose, the fdt_add_pubkey tool
requires a patch to avoid SIGSEGV, which I am copying below from my
previous message:
diff --git a/tools/fdt_add_pubkey.c b/tools/fdt_add_pubkey.c
index 5582d7a8efe..4f7028cc15c 100644
--- a/tools/fdt_add_pubkey.c
+++ b/tools/fdt_add_pubkey.c
@@ -73,9 +73,10 @@ static void reset_info(struct image_sign_info *info)
info->keyname = keyname;
info->name = algo_name;
info->require_keys = require_keys;
+ info->checksum = image_get_checksum_algo(algo_name);
info->crypto = image_get_crypto_algo(algo_name);
- if (!info->crypto) {
+ if (!info->checksum || !info->crypto) {
fprintf(stderr, "Unsupported signature algorithm '%s'\n",
algo_name);
exit(EXIT_FAILURE);
Unlike with RSA, fdt_add_pubkey does not accept a public key:
fdt_add_pubkey: Cannot add public key to FIT blob: Unknown error -5
I am able to work around this by invoking the tool on a _private_ key
dev.pem that the fitImage had been signed with.
I don't know if there is a cleaner way, but here's how I am embedding
the public key to the image. I first build U-boot from the scratch,
modify the generated u-boot.dtb, and finally rebuild to have the
modified DTB included:
make clean
make -j$(nproc) CROSS_COMPILE=aarch64-linux-gnu- ...
cp u-boot.dtb u-boot-pubkey.dtb
fdt_add_pubkey -a sha256,ecdsa256 -n dev -k . -r conf u-boot-pubkey.dtb
fit_check_sign -f fitImage -k u-boot-pubkey.dtb
make EXT_DTB=u-boot-pubkey.dtb \
-j$(nproc) CROSS_COMPILE=aarch64-linux-gnu- ...
Even though fit_check_sign passes on the host system, the signature
check would fail on the target system (TI AM62x) as follows:
8304957 bytes read in 346 ms (22.9 MiB/s)
## Executing script at 90000000
sha256,ecdsa256:dev- error!
Unknown signature algorithm for '<NULL>' hash node in 'conf-1' config node
Failed to verify required signature 'dev'
Boot failed (err=1)
It turns out that for ECDSA signature verification, at least three
configuration options will be needed:
CONFIG_FIT_SIGNATURE=y
CONFIG_ECDSA=y
CONFIG_ECDSA_VERIFY=y
Rebuilding with CONFIG_ECDSA_VERIFY=y changed the error message to the
following:
sha256,ecdsa256:dev- error!
Verification failed for '<NULL>' hash node in 'conf-1' config node
Failed to verify required signature 'dev'
I did not attach a debugger to the target, but I am rather sure that the
verification fails because of the following:
static int ecdsa_verify_hash(struct udevice *dev,
const struct image_sign_info *info,
const void *hash, const void *sig, uint sig_len)
{
const struct ecdsa_ops *ops = device_get_ops(dev);
const struct checksum_algo *algo = info->checksum;
struct ecdsa_public_key key;
int sig_node, key_node, ret;
if (!ops || !ops->verify)
return -ENODEV;
I found only two definitions of ecdsa_ops, and it does not look like
either one should be available on my target system.
The cosmetic error <NULL> in the error message occurs because the local
variable "noffset" in fit_image_verify_sig() will only be valid if the
for loop is executing "goto error". This bug is tricky to fix, because
as far as I understand, we want to allow multiple signatures to be
verified.
One more thing that I noticed is that the function fit_check_sign() has
an unused parameter:
diff --git a/tools/fit_check_sign.c b/tools/fit_check_sign.c
index ab3266aff20..3d1e66f2b58 100644
--- a/tools/fit_check_sign.c
+++ b/tools/fit_check_sign.c
@@ -80,7 +80,7 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
image_set_host_blob(key_blob);
- ret = fit_check_sign(fit_blob, key_blob, config_name);
+ ret = fit_check_sign(fit_blob, NULL, config_name);
if (!ret) {
ret = EXIT_SUCCESS;
fprintf(stderr, "Signature check OK\n");
The above patch shows the only caller of the function. It also shows
that the caller is invoking image_set_host_blob() on that parameter,
which is why the check is able to work. Maybe that call should be made
part of fit_check_sign() itself? Anyway, this code does not execute on
the target.
With best regards,
Marko Mäkelä
next prev parent reply other threads:[~2025-11-08 17:24 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-13 18:36 How to use ECDSA for signature verification? Marko Mäkelä
2025-11-08 17:24 ` Marko Mäkelä [this message]
2025-11-11 4:22 ` Anshul Dalal
2025-11-11 15:56 ` Marko Mäkelä
2026-02-03 5:32 ` Anshul Dalal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aQ98sHenb3G1MQDi@kehys.lan \
--to=marko.makela@iki.fi \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.