* [PATCH v9 00/15] add software ecdsa support
@ 2026-09-03 8:16 Philippe Reynes
2026-09-03 8:16 ` [PATCH v9 01/15] ecdsa: fix support of secp521r1 Philippe Reynes
` (15 more replies)
0 siblings, 16 replies; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes
This series adds the support of ecdsa with software
using mbedtls. So boards without ecdsa hardware may
also use signature with ecdsa.
To achieve this goal, several changes are done:
- fix the support of secp521r1
- enable support of ecdsa in mbedtls
- add software ecdsa signature check using mbedtls
- add support of ecdsa for internal fit signature
- add test for ecdsa for internal fit signature in vboot
- add support of ecdsa for pre-load signature
- add test for ecdsa for pre-load signature in vboot
- enable software ecdsa signature check in sandbox
To test this new feature, just follow those steps:
0) build u-boot using sandbox_defconfig and adding those options:
CONFIG_ECDSA_MBEDTLS=y
CONFIG_ECDSA_VERIFY_MBEDTLS=y
CONFIG_ECDSA=y
CONFIG_ECDSA_VERIFY=y
1) add a signature node to an its file
signature-256 {
algo = "sha256,ecdsa256";
key-name-hint = "private-key-256";
};
2) generate an ecdsa key
openssl ecparam -name prime256v1 -genkey -noout -out private-key-256.pem
3) create the itb file
./tools/mkimage -f <file.its> -k . -K arch/sandbox/dts/test.dtb <file.itb>
4) launch sandbox u-boot
./u-boot -d arch/sandbox/dts/test.dtb
5) on sandbox u-boot prompt, load the itb and launch bootm on it
=> host load hostfs - 1000000 uboot-ecdsa.itb
4628674 bytes read in 1 ms (4.3 GiB/s)
=> bootm 1000000
...
...
Verifying Hash Integrity ... sha256,ecdsa256:private-key-256+ OK
Changes in v2:
- move ECDSA_MBEDTLS to MBEDTLS_LIB_X509
- rename lib/mbedtls/sw_ecdsa.c to lib/mbedtls/ecdsa.c
- enhance dependencies for ECDSA_MBEDTLS
- fix support of ecdsa521/secp521r1
- add vboot test using ecdsa
Changes in v3:
- do not use _MBEDTLS in mbedtls_def_config.h
- check returns and remove mem leak in lib/mbedtls/ecdsa.c
- remove useless field *k in struct ecdsa_test_vector_s
- check returns in test/lib/ecdsa.c
- fix third parameter when calling sha*_csum_wd()
- add support of ecdsa in pre-load header
Changes in v4:
- change some dependencies to enable ecc
- use ECDSA_MBEDTLS to build the ecdsa driver
- support ecdsa521 and secp521r1
- add a test calling ecdsa_verify for the ecdsa class
- merge patch 10 and 11 (support ecdsa pre-load for binman and tests)
- several code cleanup
Change in v5:
- fix ecdsa 521 in the first patch (instead of the 5th patch)
- mbedtls: ecdsa is only compiled when ECDSA_MBEDTLS is enabled
- fit_image_setup_sig: required_keynode is initiazed to -1 instead of 0
- avoid hardcoded value for ecdsa sig and point size
- check pointer before using them
- free ecdsa keys when key are not found/used
Change in v6:
- fix dependencies for ecdsa
- ecdsa is no more mandatory for tls
- remove include u-boot/ecdsa.h in ecdsa-sw.c
- do not use fdt_stderror with -1
-
Change in v7:
- change uint8_t to u8 in test/dm/ecdsa.c
- change info->required_keynode >= 0 in lib/ecdsa/ecdsa-verify.c
- set required_keynode to -1 in test/dm/ecdsa.c
Change in v8:
- check exact size of data read in dtb in function fdt_get_key
- enhance commit message to explain patch 2 (enable ecc)
- no longer use macro CHECK with goto inside macro
- some code cleanup
Change in v9:
- rebase on next
- update cover letter
Philippe Reynes (15):
ecdsa: fix support of secp521r1
mbedtls: enable support of ecc
ecdsa: initial support of ecdsa using mbedtls
test: lib: ecdsa: add initial test
drivers: crypto: add software ecdsa support
test: dm: ecdsa.c: clean this test as software ecdsa is now
implemented
test: py: vboot: prepare integration test for ecdsa
test: vboot: add test for ecdsa
tools: fit_image_setup_sig: set required_keynode to -1
tools: mkimage: pre-load: add support of ecdsa
tools: binman: pre-load: add support of ecdsa
boot: pre-load: add support of ecdsa
tools: preload_check_sign: add support of ecdsa
test: py: vboot: prepare test for global signature with ecdsa
test: py: vboot: add test for global signature with ecdsa
boot/image-pre-load.c | 53 +-
configs/sandbox_defconfig | 2 +
drivers/crypto/Makefile | 1 +
drivers/crypto/ecdsa/Makefile | 6 +
drivers/crypto/ecdsa/ecdsa-sw.c | 32 ++
include/crypto/ecdsa-uclass.h | 15 +-
include/crypto/internal/ecdsa.h | 39 ++
lib/ecdsa/Kconfig | 1 +
lib/ecdsa/ecdsa-libcrypto.c | 104 +++-
lib/ecdsa/ecdsa-verify.c | 73 ++-
lib/fdt-libcrypto.c | 2 +-
lib/mbedtls/Kconfig | 24 +
lib/mbedtls/Makefile | 20 +-
lib/mbedtls/ecdsa.c | 152 ++++++
lib/mbedtls/mbedtls_def_config.h | 41 +-
test/dm/ecdsa.c | 107 +++-
test/lib/Makefile | 1 +
test/lib/ecdsa.c | 456 ++++++++++++++++++
test/py/tests/test_fit_ecdsa.py | 2 +-
test/py/tests/test_vboot.py | 148 +++---
.../tests/vboot/sandbox-binman-ecdsa256.dts | 24 +
.../tests/vboot/sandbox-binman-ecdsa384.dts | 24 +
.../tests/vboot/sandbox-binman-ecdsa521.dts | 24 +
...pss.dts => sandbox-binman-rsa2048-pss.dts} | 0
...-binman.dts => sandbox-binman-rsa2048.dts} | 0
.../vboot/sandbox-u-boot-global-ecdsa256.dts | 27 ++
.../vboot/sandbox-u-boot-global-ecdsa384.dts | 27 ++
.../vboot/sandbox-u-boot-global-ecdsa521.dts | 27 ++
... => sandbox-u-boot-global-rsa2048-pss.dts} | 0
....dts => sandbox-u-boot-global-rsa2048.dts} | 0
....its => sign-configs-sha1-rsa2048-pss.its} | 0
...sha1.its => sign-configs-sha1-rsa2048.its} | 0
.../vboot/sign-configs-sha256-ecdsa256.its | 44 ++
.../vboot/sign-configs-sha256-ecdsa384.its | 44 ++
.../vboot/sign-configs-sha256-ecdsa521.its | 44 ++
... sign-configs-sha256-rsa2048-pss-prod.its} | 0
...ts => sign-configs-sha256-rsa2048-pss.its} | 0
...56.its => sign-configs-sha256-rsa2048.its} | 0
...84.its => sign-configs-sha384-rsa3072.its} | 0
...s.its => sign-images-sha1-rsa2048-pss.its} | 0
...-sha1.its => sign-images-sha1-rsa2048.its} | 0
.../vboot/sign-images-sha256-ecdsa256.its | 42 ++
.../vboot/sign-images-sha256-ecdsa384.its | 42 ++
.../vboot/sign-images-sha256-ecdsa521.its | 42 ++
...its => sign-images-sha256-rsa2048-pss.its} | 0
...256.its => sign-images-sha256-rsa2048.its} | 0
...384.its => sign-images-sha384-rsa3072.its} | 0
tools/binman/etype/pre_load.py | 78 ++-
tools/binman/ftest.py | 50 ++
tools/binman/test/ecdsa521.pem | 7 +
tools/binman/test/security/pre_load_ecdsa.dts | 22 +
.../security/pre_load_ecdsa_invalid_algo.dts | 22 +
.../security/pre_load_ecdsa_invalid_key.dts | 22 +
.../security/pre_load_ecdsa_invalid_sha.dts | 22 +
tools/image-host.c | 93 +++-
tools/image-sig-host.c | 7 +
tools/preload_check_sign.c | 30 ++
57 files changed, 1893 insertions(+), 150 deletions(-)
create mode 100644 drivers/crypto/ecdsa/Makefile
create mode 100644 drivers/crypto/ecdsa/ecdsa-sw.c
create mode 100644 include/crypto/internal/ecdsa.h
create mode 100644 lib/mbedtls/ecdsa.c
create mode 100644 test/lib/ecdsa.c
create mode 100644 test/py/tests/vboot/sandbox-binman-ecdsa256.dts
create mode 100644 test/py/tests/vboot/sandbox-binman-ecdsa384.dts
create mode 100644 test/py/tests/vboot/sandbox-binman-ecdsa521.dts
rename test/py/tests/vboot/{sandbox-binman-pss.dts => sandbox-binman-rsa2048-pss.dts} (100%)
rename test/py/tests/vboot/{sandbox-binman.dts => sandbox-binman-rsa2048.dts} (100%)
create mode 100644 test/py/tests/vboot/sandbox-u-boot-global-ecdsa256.dts
create mode 100644 test/py/tests/vboot/sandbox-u-boot-global-ecdsa384.dts
create mode 100644 test/py/tests/vboot/sandbox-u-boot-global-ecdsa521.dts
rename test/py/tests/vboot/{sandbox-u-boot-global-pss.dts => sandbox-u-boot-global-rsa2048-pss.dts} (100%)
rename test/py/tests/vboot/{sandbox-u-boot-global.dts => sandbox-u-boot-global-rsa2048.dts} (100%)
rename test/py/tests/vboot/{sign-configs-sha1-pss.its => sign-configs-sha1-rsa2048-pss.its} (100%)
rename test/py/tests/vboot/{sign-configs-sha1.its => sign-configs-sha1-rsa2048.its} (100%)
create mode 100644 test/py/tests/vboot/sign-configs-sha256-ecdsa256.its
create mode 100644 test/py/tests/vboot/sign-configs-sha256-ecdsa384.its
create mode 100644 test/py/tests/vboot/sign-configs-sha256-ecdsa521.its
rename test/py/tests/vboot/{sign-configs-sha256-pss-prod.its => sign-configs-sha256-rsa2048-pss-prod.its} (100%)
rename test/py/tests/vboot/{sign-configs-sha256-pss.its => sign-configs-sha256-rsa2048-pss.its} (100%)
rename test/py/tests/vboot/{sign-configs-sha256.its => sign-configs-sha256-rsa2048.its} (100%)
rename test/py/tests/vboot/{sign-configs-sha384.its => sign-configs-sha384-rsa3072.its} (100%)
rename test/py/tests/vboot/{sign-images-sha1-pss.its => sign-images-sha1-rsa2048-pss.its} (100%)
rename test/py/tests/vboot/{sign-images-sha1.its => sign-images-sha1-rsa2048.its} (100%)
create mode 100644 test/py/tests/vboot/sign-images-sha256-ecdsa256.its
create mode 100644 test/py/tests/vboot/sign-images-sha256-ecdsa384.its
create mode 100644 test/py/tests/vboot/sign-images-sha256-ecdsa521.its
rename test/py/tests/vboot/{sign-images-sha256-pss.its => sign-images-sha256-rsa2048-pss.its} (100%)
rename test/py/tests/vboot/{sign-images-sha256.its => sign-images-sha256-rsa2048.its} (100%)
rename test/py/tests/vboot/{sign-images-sha384.its => sign-images-sha384-rsa3072.its} (100%)
create mode 100644 tools/binman/test/ecdsa521.pem
create mode 100644 tools/binman/test/security/pre_load_ecdsa.dts
create mode 100644 tools/binman/test/security/pre_load_ecdsa_invalid_algo.dts
create mode 100644 tools/binman/test/security/pre_load_ecdsa_invalid_key.dts
create mode 100644 tools/binman/test/security/pre_load_ecdsa_invalid_sha.dts
--
2.43.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v9 01/15] ecdsa: fix support of secp521r1
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
@ 2026-09-03 8:16 ` Philippe Reynes
2026-09-03 14:30 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 02/15] mbedtls: enable support of ecc Philippe Reynes
` (14 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes
Current implementation of ecdsa only supports key len aligned on
8 bits. But the curve secp521r1 uses a key of 521 bits which is not
aligned on 8 bits. In this commit, we update the keys management
for ecdsa to support keys that are not aligned on 8 bits.
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v2:
- intitial version
v3:
- fix typo in comments
v4:
- fix commit message
- clean code with DIV_ROUND_UP-
- duplicate data before shifting
- support ecdsa521 and secp521r1
- clean code
v5:
- check that x and y are not null before using them
- free keys when keys not found
-v6:
- free x and y if x and y are not null
- do not free key when an error has occured
v7:
- no change
v8:
- check the exact size read in the dtb instead of doing a simple
test on the expected size
- change memdup api to use the same as in the header include/linux/string.h
- code cleanup
v9:
- no change
lib/ecdsa/ecdsa-libcrypto.c | 75 ++++++++++++++++++++++++++++++++++++-
lib/ecdsa/ecdsa-verify.c | 71 +++++++++++++++++++++++++++++++++--
lib/fdt-libcrypto.c | 2 +-
tools/image-sig-host.c | 7 ++++
4 files changed, 148 insertions(+), 7 deletions(-)
diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c
index c4bfb2cec61..b3fc75fac48 100644
--- a/lib/ecdsa/ecdsa-libcrypto.c
+++ b/lib/ecdsa/ecdsa-libcrypto.c
@@ -26,6 +26,8 @@
#include <openssl/ec.h>
#include <openssl/bn.h>
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+
/* Image signing context for openssl-libcrypto */
struct signer {
EVP_PKEY *evp_key; /* Pointer to EVP_PKEY object */
@@ -41,10 +43,36 @@ struct ecdsa_public_key {
int size_bits;
};
+/*
+ * This function returns a valid pointer so
+ * the caller must then free this pointer.
+ */
+static char *memdup(const void *src, size_t len)
+{
+ char *p;
+
+ p = malloc(len);
+ if (!p)
+ return NULL;
+
+ memcpy(p, src, len);
+
+ return p;
+}
+
+/*
+ * This function fills keys with valid pointers (x and y) so
+ * the caller must then free those pointers with fdt_free_key().
+ */
static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
{
+ const char *x;
+ const char *y;
int x_len;
int y_len;
+ int expected_len;
+
+ memset(key, 0, sizeof(*key));
key->curve_name = fdt_getprop(fdt, node, "ecdsa,curve", NULL);
if (!key->curve_name)
@@ -54,6 +82,8 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
key->size_bits = 256;
else if (!strcmp(key->curve_name, "secp384r1"))
key->size_bits = 384;
+ else if (!strcmp(key->curve_name, "secp521r1"))
+ key->size_bits = 521;
else
return -EINVAL;
@@ -63,12 +93,45 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
if (!key->x || !key->y)
return -EINVAL;
- if (x_len != key->size_bits / 8 || y_len != key->size_bits / 8)
+ /*
+ * The public key is stored as an array of u32, so if the key size is
+ * not a multiple of 32 (for example 521), we may have extra bytes.
+ * To avoid any issue later, we shift the x and y pointer to the first
+ * useful byte.
+ */
+ expected_len = DIV_ROUND_UP(key->size_bits, 8);
+
+ if (x_len < expected_len || y_len < expected_len)
return -EINVAL;
+ x = memdup(key->x + (x_len - expected_len), expected_len);
+ if (!x) {
+ fprintf(stderr, "Cannot allocate memory for point X");
+ return -ENOMEM;
+ }
+ key->x = (const uint8_t *)x;
+
+ y = memdup(key->y + (y_len - expected_len), expected_len);
+ if (!y) {
+ fprintf(stderr, "Cannot allocate memory for point Y");
+ free((char *)x);
+ return -ENOMEM;
+ }
+ key->y = (const uint8_t *)y;
+
return 0;
}
+static void fdt_free_key(struct ecdsa_public_key *key)
+{
+ if (!key)
+ return;
+ if (key->x)
+ free((char *)key->x);
+ if (key->y)
+ free((char *)key->y);
+}
+
static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
{
struct ecdsa_public_key pubkey;
@@ -89,8 +152,11 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
nid = NID_X9_62_prime256v1;
} else if (!strcmp(pubkey.curve_name, "secp384r1")) {
nid = NID_secp384r1;
+ } else if (!strcmp(pubkey.curve_name, "secp521r1")) {
+ nid = NID_secp521r1;
} else {
fprintf(stderr, "Unsupported curve name: '%s'\n", pubkey.curve_name);
+ fdt_free_key(&pubkey);
return -EINVAL;
}
@@ -100,6 +166,7 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
ec_key = EC_KEY_new_by_curve_name(nid);
if (!ec_key) {
fprintf(stderr, "Failed to allocate EC_KEY for curve %s\n", pubkey.curve_name);
+ fdt_free_key(&pubkey);
return -ENOMEM;
}
@@ -108,10 +175,11 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
if (!point) {
fprintf(stderr, "Failed to allocate EC_POINT\n");
EC_KEY_free(ec_key);
+ fdt_free_key(&pubkey);
return -ENOMEM;
}
- len = pubkey.size_bits / 8;
+ len = DIV_ROUND_UP(pubkey.size_bits, 8);
uint8_t buf[1 + len * 2];
@@ -123,6 +191,7 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
fprintf(stderr, "Failed to convert (x,y) point to EC_POINT\n");
EC_POINT_free(point);
EC_KEY_free(ec_key);
+ fdt_free_key(&pubkey);
return -EINVAL;
}
@@ -130,11 +199,13 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
fprintf(stderr, "Failed to set EC_POINT as public key\n");
EC_POINT_free(point);
EC_KEY_free(ec_key);
+ fdt_free_key(&pubkey);
return -EINVAL;
}
fprintf(stderr, "Successfully loaded ECDSA key from FDT node %d\n", node);
EC_POINT_free(point);
+ fdt_free_key(&pubkey);
ctx->ecdsa_key = ec_key;
return 0;
diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c
index 629b662cf6c..494b60b4ab0 100644
--- a/lib/ecdsa/ecdsa-verify.c
+++ b/lib/ecdsa/ecdsa-verify.c
@@ -10,6 +10,7 @@
#include <crypto/ecdsa-uclass.h>
#include <dm/uclass.h>
+#include <malloc.h>
#include <u-boot/ecdsa.h>
/*
@@ -24,13 +25,23 @@ static int ecdsa_key_size(const char *curve_name)
return 256;
else if (!strcmp(curve_name, "secp384r1"))
return 384;
+ else if (!strcmp(curve_name, "secp521r1"))
+ return 521;
return 0;
}
+/*
+ * This function fills keys with valid pointers (x and y) so
+ * the caller must then free those pointers with fdt_free_key().
+ */
static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
{
- int x_len, y_len;
+ int expected_read, expected_len, x_len, y_len;
+ const char *x;
+ const char *y;
+
+ memset(key, 0, sizeof(*key));
key->curve_name = fdt_getprop(fdt, node, "ecdsa,curve", NULL);
if (!key->curve_name) {
@@ -50,15 +61,50 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
if (!key->x || !key->y)
return -EINVAL;
- if (x_len != (key->size_bits / 8) || y_len != (key->size_bits / 8)) {
+ expected_read = DIV_ROUND_UP(key->size_bits, 32) * 4;
+ if (x_len != expected_read || y_len != expected_read) {
printf("%s: node=%d, curve@%p x@%p+%i y@%p+%i\n", __func__,
node, key->curve_name, key->x, x_len, key->y, y_len);
return -EINVAL;
}
+ /*
+ * The public key is stored as an array of u32, so if the key size is
+ * not a multiple of 32 (for example 521), we may have extra bytes.
+ * To avoid any issue later, we shift the x and y pointer to the first
+ * useful byte.
+ */
+ expected_len = DIV_ROUND_UP(key->size_bits, 8);
+
+ x = memdup(key->x + (x_len - expected_len), expected_len);
+ if (!x) {
+ debug("Cannot allocate memory for point X\n");
+ return -ENOMEM;
+ }
+ key->x = (const uint8_t *)x;
+
+ y = memdup(key->y + (y_len - expected_len), expected_len);
+ if (!y) {
+ debug("Cannot allocate memory for point Y\n");
+ free((char *)x);
+ key->x = NULL;
+ return -ENOMEM;
+ }
+ key->y = (const uint8_t *)y;
+
return 0;
}
+static void fdt_free_key(struct ecdsa_public_key *key)
+{
+ if (!key)
+ return;
+ if (key->x)
+ free((char *)key->x);
+ if (key->y)
+ free((char *)key->y);
+}
+
static int ecdsa_verify_hash(struct udevice *dev,
const struct image_sign_info *info,
const void *hash, const void *sig, uint sig_len)
@@ -76,8 +122,11 @@ static int ecdsa_verify_hash(struct udevice *dev,
if (ret < 0)
return ret;
- return ops->verify(dev, &key, hash, algo->checksum_len,
- sig, sig_len);
+ ret = ops->verify(dev, &key, hash, algo->checksum_len,
+ sig, sig_len);
+ fdt_free_key(&key);
+
+ return ret;
}
sig_node = fdt_subnode_offset(info->fdt_blob, 0, FIT_SIG_NODENAME);
@@ -93,6 +142,8 @@ static int ecdsa_verify_hash(struct udevice *dev,
ret = ops->verify(dev, &key, hash, algo->checksum_len,
sig, sig_len);
+ fdt_free_key(&key);
+
/* On success, don't worry about remaining keys */
if (!ret)
return 0;
@@ -135,6 +186,18 @@ U_BOOT_CRYPTO_ALGO(ecdsa384) = {
.verify = ecdsa_verify,
};
+U_BOOT_CRYPTO_ALGO(ecdsa521) = {
+ .name = "ecdsa521",
+ .key_len = ECDSA521_BYTES,
+ .verify = ecdsa_verify,
+};
+
+U_BOOT_CRYPTO_ALGO(secp521r1) = {
+ .name = "secp521r1",
+ .key_len = ECDSA521_BYTES,
+ .verify = ecdsa_verify,
+};
+
/*
* uclass definition for ECDSA API
*
diff --git a/lib/fdt-libcrypto.c b/lib/fdt-libcrypto.c
index ecb0344c8f6..090246b44e9 100644
--- a/lib/fdt-libcrypto.c
+++ b/lib/fdt-libcrypto.c
@@ -10,7 +10,7 @@
int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
BIGNUM *num, int num_bits)
{
- int nwords = num_bits / 32;
+ int nwords = (num_bits + 31) / 32;
int size;
uint32_t *buf, *ptr;
BIGNUM *tmp, *big2, *big32, *big2_32;
diff --git a/tools/image-sig-host.c b/tools/image-sig-host.c
index 5285263c616..285547994ca 100644
--- a/tools/image-sig-host.c
+++ b/tools/image-sig-host.c
@@ -83,6 +83,13 @@ struct crypto_algo crypto_algos[] = {
.add_verify_data = ecdsa_add_verify_data,
.verify = ecdsa_verify,
},
+ {
+ .name = "ecdsa521",
+ .key_len = ECDSA521_BYTES,
+ .sign = ecdsa_sign,
+ .add_verify_data = ecdsa_add_verify_data,
+ .verify = ecdsa_verify,
+ },
{
.name = "secp521r1",
.key_len = ECDSA521_BYTES,
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 02/15] mbedtls: enable support of ecc
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
2026-09-03 8:16 ` [PATCH v9 01/15] ecdsa: fix support of secp521r1 Philippe Reynes
@ 2026-09-03 8:16 ` Philippe Reynes
2026-09-03 14:31 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 03/15] ecdsa: initial support of ecdsa using mbedtls Philippe Reynes
` (13 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes
Prepares the support of ecdsa signature check
using MbedTLS. It introduces the option ECDSA_MBEDTLS
to enable (or not) the support of ecdsa in MbedTLS.
So now, ecdsa is no longer supported by default in the lib TLS.
To get it, the option ECDSA_MBEDTLS must be enabled.
The option ECDSA_MBEDTLS only enables the ecdsa support
in MbedTLS, it doesn't provide any API to use it for
signature check. It will be done in another commit
by adding the option ECDSA_VERIFY_MBEDTLS.
Two internal options are also added BIGNUM_MBEDTLS
and ECC_MBEDTLS. Those options are used to share code
between different option and avoid duplication.
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v2:
- move ecdsa to MBEDTLS_LIB_X509
- enhance depencendies
v3:
- do not use _MBEDTLS in mbedtls_def_config.h
v4:
- do not select ECDSA on some configs
- remove duplicated MBEDTLS_ECP_DP_SECP256K1_ENABLED
- change dependencies for ECDSA configs
v5:
- MBEDTLS_LIB_TLS depends en ECDSA_MBEDTLS
- update some configs according to previous change
- build of ecdsa is conditionned by ECDSA_MBEDTLS
v6:
- fix dependencies for ecdsa and ecc on mbedtls
- ecdsa is no longer mandatory for tls
v7:
- no change
v8:
- enhance the commit message
- use /* */ instead of //
v9:
- no change
configs/sandbox_defconfig | 1 +
lib/ecdsa/Kconfig | 1 +
lib/mbedtls/Kconfig | 17 +++++++++++++
lib/mbedtls/Makefile | 17 +++++++------
lib/mbedtls/mbedtls_def_config.h | 41 +++++++++++++++++++++-----------
5 files changed, 56 insertions(+), 21 deletions(-)
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index 5c97418783f..b9991d269d9 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -389,6 +389,7 @@ CONFIG_PMBUS=y
CONFIG_CMD_DHRYSTONE=y
CONFIG_MBEDTLS_LIB=y
CONFIG_HKDF_MBEDTLS=y
+CONFIG_ECDSA_MBEDTLS=y
CONFIG_ECDSA=y
CONFIG_ECDSA_VERIFY=y
CONFIG_RSASSA_PSS=y
diff --git a/lib/ecdsa/Kconfig b/lib/ecdsa/Kconfig
index ca13b6bfa1f..dac8bcf23dd 100644
--- a/lib/ecdsa/Kconfig
+++ b/lib/ecdsa/Kconfig
@@ -1,6 +1,7 @@
config ECDSA
bool "Enable ECDSA support"
depends on DM
+ select ASN1_DECODER
help
This enables the ECDSA (elliptic curve signature) algorithm for FIT
image verification in U-Boot. The ECDSA algorithm is implemented
diff --git a/lib/mbedtls/Kconfig b/lib/mbedtls/Kconfig
index 789721ee6cd..e019f17d6bd 100644
--- a/lib/mbedtls/Kconfig
+++ b/lib/mbedtls/Kconfig
@@ -247,6 +247,12 @@ config MBEDTLS_LIB_X509
if MBEDTLS_LIB_X509
+config BIGNUM_MBEDTLS
+ bool
+
+config ECC_MBEDTLS
+ bool
+
config ASN1_DECODER_MBEDTLS
bool "ASN1 decoder with MbedTLS certificate library"
depends on MBEDTLS_LIB_X509 && ASN1_DECODER
@@ -264,6 +270,7 @@ config RSA_PUBLIC_KEY_PARSER_MBEDTLS
bool "RSA public key parser with MbedTLS certificate library"
depends on ASYMMETRIC_PUBLIC_KEY_MBEDTLS
select ASN1_DECODER_MBEDTLS
+ select BIGNUM_MBEDTLS
help
This option chooses MbedTLS certificate library for RSA public key
parser.
@@ -292,6 +299,15 @@ config MSCODE_PARSER_MBEDTLS
This option chooses MbedTLS certificate library for MS authenticode
parser.
+config ECDSA_MBEDTLS
+ bool "Enable ECDSA support with MbedTLS certificate library"
+ depends on MBEDTLS_LIB_X509 && ASN1_DECODER_MBEDTLS
+ select BIGNUM_MBEDTLS
+ select ECC_MBEDTLS
+ help
+ This option enables support of ECDSA with the MbedTLS certificate
+ library.
+
endif # MBEDTLS_LIB_X509
config MBEDTLS_LIB_TLS
@@ -301,6 +317,7 @@ config MBEDTLS_LIB_TLS
depends on ASYMMETRIC_PUBLIC_KEY_MBEDTLS
depends on ASN1_DECODER_MBEDTLS
depends on MBEDTLS_LIB
+ select ECC_MBEDTLS
help
Enable MbedTLS TLS library. Required for HTTPs support
in wget
diff --git a/lib/mbedtls/Makefile b/lib/mbedtls/Makefile
index c5b445bd85c..0c86c90d15a 100644
--- a/lib/mbedtls/Makefile
+++ b/lib/mbedtls/Makefile
@@ -39,13 +39,21 @@ mbedtls_lib_crypto-$(CONFIG_$(PHASE_)HKDF_MBEDTLS) += \
# MbedTLS X509 library
obj-$(CONFIG_$(XPL_)MBEDTLS_LIB_X509) += mbedtls_lib_x509.o
mbedtls_lib_x509-y := $(MBEDTLS_LIB_DIR)/x509.o
+mbedtls_lib_x509-$(CONFIG_$(PHASE_)ECC_MBEDTLS) += \
+ $(MBEDTLS_LIB_DIR)/ecp.o \
+ $(MBEDTLS_LIB_DIR)/ecp_curves.o \
+ $(MBEDTLS_LIB_DIR)/ecp_curves_new.o \
+ $(MBEDTLS_LIB_DIR)/pk_ecc.o
+mbedtls_lib_x509-$(CONFIG_$(PHASE_)ECDSA_MBEDTLS) += \
+ $(MBEDTLS_LIB_DIR)/ecdsa.o
+mbedtls_lib_x509-$(CONFIG_$(PHASE_)BIGNUM_MBEDTLS) += \
+ $(MBEDTLS_LIB_DIR)/bignum.o \
+ $(MBEDTLS_LIB_DIR)/bignum_core.o
mbedtls_lib_x509-$(CONFIG_$(PHASE_)ASN1_DECODER_MBEDTLS) += \
$(MBEDTLS_LIB_DIR)/asn1parse.o \
$(MBEDTLS_LIB_DIR)/asn1write.o \
$(MBEDTLS_LIB_DIR)/oid.o
mbedtls_lib_x509-$(CONFIG_$(PHASE_)RSA_PUBLIC_KEY_PARSER_MBEDTLS) += \
- $(MBEDTLS_LIB_DIR)/bignum.o \
- $(MBEDTLS_LIB_DIR)/bignum_core.o \
$(MBEDTLS_LIB_DIR)/rsa.o \
$(MBEDTLS_LIB_DIR)/rsa_alt_helpers.o
mbedtls_lib_x509-$(CONFIG_$(PHASE_)ASYMMETRIC_PUBLIC_KEY_MBEDTLS) += \
@@ -64,7 +72,6 @@ mbedtls_lib_tls-y := \
$(MBEDTLS_LIB_DIR)/mps_reader.o \
$(MBEDTLS_LIB_DIR)/mps_trace.o \
$(MBEDTLS_LIB_DIR)/net_sockets.o \
- $(MBEDTLS_LIB_DIR)/pk_ecc.o \
$(MBEDTLS_LIB_DIR)/ssl_cache.o \
$(MBEDTLS_LIB_DIR)/ssl_ciphersuites.o \
$(MBEDTLS_LIB_DIR)/ssl_client.o \
@@ -82,8 +89,4 @@ mbedtls_lib_tls-y := \
$(MBEDTLS_LIB_DIR)/cipher.o \
$(MBEDTLS_LIB_DIR)/cipher_wrap.o \
$(MBEDTLS_LIB_DIR)/ecdh.o \
- $(MBEDTLS_LIB_DIR)/ecdsa.o \
- $(MBEDTLS_LIB_DIR)/ecp.o \
- $(MBEDTLS_LIB_DIR)/ecp_curves.o \
- $(MBEDTLS_LIB_DIR)/ecp_curves_new.o \
$(MBEDTLS_LIB_DIR)/gcm.o \
diff --git a/lib/mbedtls/mbedtls_def_config.h b/lib/mbedtls/mbedtls_def_config.h
index dda3f4dd6e4..d55f31acfda 100644
--- a/lib/mbedtls/mbedtls_def_config.h
+++ b/lib/mbedtls/mbedtls_def_config.h
@@ -62,6 +62,25 @@
#if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
+#if CONFIG_IS_ENABLED(BIGNUM_MBEDTLS)
+#define MBEDTLS_BIGNUM_C
+#endif
+
+#if CONFIG_IS_ENABLED(ECC_MBEDTLS)
+#define MBEDTLS_ECP_C
+#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+#define MBEDTLS_ECP_DP_BP256R1_ENABLED
+#define MBEDTLS_ECP_DP_BP384R1_ENABLED
+#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+#endif
+
#if CONFIG_IS_ENABLED(X509_CERTIFICATE_PARSER)
#define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C
@@ -74,7 +93,6 @@
#endif
#if CONFIG_IS_ENABLED(RSA_PUBLIC_KEY_PARSER)
-#define MBEDTLS_BIGNUM_C
#define MBEDTLS_RSA_C
#define MBEDTLS_PKCS1_V15
#endif
@@ -89,6 +107,10 @@
#define MBEDTLS_ASN1_WRITE_C
#endif
+#if CONFIG_IS_ENABLED(ECDSA_MBEDTLS)
+#define MBEDTLS_ECDSA_C
+#endif
+
#endif /* #if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509) */
#if CONFIG_IS_ENABLED(MBEDTLS_LIB_TLS)
@@ -122,7 +144,9 @@
/* ECDSA */
#if CONFIG_IS_ENABLED(ASN1_DECODER)
+#if CONFIG_IS_ENABLED(ECDSA_MBEDTLS)
#define MBEDTLS_ECDSA_C
+#endif /* #if CONFIG_IS_ENABLED(ECDSA_MBEDTLS) */
#define MBEDTLS_ECP_C
#define MBEDTLS_ECDH_C
#endif
@@ -130,24 +154,13 @@
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_CAN_ECDH
+#if CONFIG_IS_ENABLED(ECDSA_MBEDTLS)
#define MBEDTLS_PK_CAN_ECDSA_SIGN
#if CONFIG_IS_ENABLED(X509_CERTIFICATE_PARSER)
#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
#endif
-
-#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
-#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
-#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
-#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
-#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
-#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
-#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
-#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
-#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
-#define MBEDTLS_ECP_DP_BP256R1_ENABLED
-#define MBEDTLS_ECP_DP_BP384R1_ENABLED
-#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+#endif /* #if CONFIG_IS_ENABLED(ECDSA_MBEDTLS) */
#endif /* #if CONFIG_IS_ENABLED(MBEDTLS_LIB_TLS) */
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 03/15] ecdsa: initial support of ecdsa using mbedtls
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
2026-09-03 8:16 ` [PATCH v9 01/15] ecdsa: fix support of secp521r1 Philippe Reynes
2026-09-03 8:16 ` [PATCH v9 02/15] mbedtls: enable support of ecc Philippe Reynes
@ 2026-09-03 8:16 ` Philippe Reynes
2026-09-03 14:31 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 04/15] test: lib: ecdsa: add initial test Philippe Reynes
` (12 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes
Adds an initial support of ecdsa verify using mbedtls.
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v2:
- rename sw_ecdsa.c to ecdsa.c
v3:
- rename sw_ecdsa_verify to ecdsa_hash_verify
- stop on first group found
- check signature len
- use debug instead of printf
- check function returns
- fix memleaks in ecdsa_hash_verify
v4:
- move struct ecdsa_public_key from ecdsa-u-class.h to internal/ecdsa.h
- use DIV_ROUND_UP
- some code cleanup
v5:
- add kerneldoc header for ecdsa_hash_verify
- read error when setting Q.Z
v6:
- add ECDSA_VERIFY_MBEDTLS
- fix kerneldoc: doc not add a space before :
v7:
- no change
v8:
- add some useful comments
- avoid using label such as out1, out2, out3 ...
- code cleanup
v9:
- no change
configs/sandbox_defconfig | 1 +
include/crypto/ecdsa-uclass.h | 15 +---
include/crypto/internal/ecdsa.h | 39 ++++++++
lib/mbedtls/Kconfig | 7 ++
lib/mbedtls/Makefile | 3 +
lib/mbedtls/ecdsa.c | 152 ++++++++++++++++++++++++++++++++
6 files changed, 203 insertions(+), 14 deletions(-)
create mode 100644 include/crypto/internal/ecdsa.h
create mode 100644 lib/mbedtls/ecdsa.c
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index b9991d269d9..63682ef0e74 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -390,6 +390,7 @@ CONFIG_CMD_DHRYSTONE=y
CONFIG_MBEDTLS_LIB=y
CONFIG_HKDF_MBEDTLS=y
CONFIG_ECDSA_MBEDTLS=y
+CONFIG_ECDSA_VERIFY_MBEDTLS=y
CONFIG_ECDSA=y
CONFIG_ECDSA_VERIFY=y
CONFIG_RSASSA_PSS=y
diff --git a/include/crypto/ecdsa-uclass.h b/include/crypto/ecdsa-uclass.h
index 189843820a0..047a5eda2fc 100644
--- a/include/crypto/ecdsa-uclass.h
+++ b/include/crypto/ecdsa-uclass.h
@@ -4,20 +4,7 @@
*/
#include <dm/device.h>
-
-/**
- * struct ecdsa_public_key - ECDSA public key properties
- *
- * The struct has pointers to the (x, y) curve coordinates to an ECDSA public
- * key, as well as the name of the ECDSA curve. The size of the key is inferred
- * from the 'curve_name'
- */
-struct ecdsa_public_key {
- const char *curve_name; /* Name of curve, e.g. "prime256v1" */
- const void *x; /* x coordinate of public key */
- const void *y; /* y coordinate of public key */
- unsigned int size_bits; /* key size in bits, derived from curve name */
-};
+#include <crypto/internal/ecdsa.h>
struct ecdsa_ops {
/**
diff --git a/include/crypto/internal/ecdsa.h b/include/crypto/internal/ecdsa.h
new file mode 100644
index 00000000000..244a07d1f1f
--- /dev/null
+++ b/include/crypto/internal/ecdsa.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2026, Philippe Reynes <philippe.reynes@softathome.com>
+ */
+#ifndef _ECDSA_HELPER_
+#define _ECDSA_HELPER_
+
+#include <linux/types.h>
+
+/**
+ * struct ecdsa_public_key - ECDSA public key properties
+ *
+ * The struct has pointers to the (x, y) curve coordinates to an ECDSA public
+ * key, as well as the name of the ECDSA curve. The size of the key is inferred
+ * from the 'curve_name'
+ */
+struct ecdsa_public_key {
+ const char *curve_name; /* Name of curve, e.g. "prime256v1" */
+ const void *x; /* x coordinate of public key */
+ const void *y; /* y coordinate of public key */
+ unsigned int size_bits; /* key size in bits, derived from curve name */
+};
+
+/**
+ * ecdsa_hash_verify() - Verify the ecdsa signature of a hash
+ *
+ * @pubkey: ecdsa public key
+ * @hash: Hash
+ * @hash_len: Size of the hash
+ * @signature: Signature
+ * @sig_len: Size of the signature
+ *
+ * Return: 0 if all verified ok, <0 on error
+ */
+int ecdsa_hash_verify(const struct ecdsa_public_key *pubkey,
+ const void *hash, size_t hash_len,
+ const void *signature, size_t sig_len);
+
+#endif
diff --git a/lib/mbedtls/Kconfig b/lib/mbedtls/Kconfig
index e019f17d6bd..66bc16db451 100644
--- a/lib/mbedtls/Kconfig
+++ b/lib/mbedtls/Kconfig
@@ -308,6 +308,13 @@ config ECDSA_MBEDTLS
This option enables support of ECDSA with the MbedTLS certificate
library.
+config ECDSA_VERIFY_MBEDTLS
+ bool "Enable ECDSA verify"
+ depends on ECDSA_MBEDTLS && ECDSA_VERIFY
+ help
+ This option enables support of ECDSA signature check with
+ MbedTLS certificate library.
+
endif # MBEDTLS_LIB_X509
config MBEDTLS_LIB_TLS
diff --git a/lib/mbedtls/Makefile b/lib/mbedtls/Makefile
index 0c86c90d15a..b96db812afc 100644
--- a/lib/mbedtls/Makefile
+++ b/lib/mbedtls/Makefile
@@ -11,6 +11,9 @@ obj-$(CONFIG_$(PHASE_)SHA1_MBEDTLS) += sha1.o
obj-$(CONFIG_$(PHASE_)SHA256_MBEDTLS) += sha256.o
obj-$(CONFIG_$(PHASE_)SHA512_MBEDTLS) += sha512.o
+# shim layer for ecdsa verify
+obj-$(CONFIG_$(PHASE_)ECDSA_VERIFY_MBEDTLS) += ecdsa.o
+
# x509 libraries
obj-$(CONFIG_$(PHASE_)ASYMMETRIC_PUBLIC_KEY_MBEDTLS) += \
public_key.o
diff --git a/lib/mbedtls/ecdsa.c b/lib/mbedtls/ecdsa.c
new file mode 100644
index 00000000000..ca4e572e638
--- /dev/null
+++ b/lib/mbedtls/ecdsa.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
+ */
+
+#include <log.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <crypto/internal/ecdsa.h>
+
+#include "mbedtls_options.h" /* required to access private fields */
+#include <mbedtls/ecdsa.h>
+#include <mbedtls/ecp.h>
+
+static mbedtls_ecp_group_id ecdsa_search_group_id(const char *curve_name)
+{
+ mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
+ const mbedtls_ecp_curve_info *info;
+
+ if (!curve_name)
+ return MBEDTLS_ECP_DP_NONE;
+
+ /*
+ * This curve name is read in the FIT metadata.
+ * When this FIT metadata are filled by mkimage (or binman),
+ * the curve name is the alias/name provided by OpenSSL.
+ * And for secp256r1, OpenSSL uses the alias prime256v1.
+ * So here, we have to manage this OpenSSL alias.
+ */
+ if (!strcmp(curve_name, "prime256v1"))
+ return MBEDTLS_ECP_DP_SECP256R1;
+
+ info = mbedtls_ecp_curve_list();
+ while (info && info->name) {
+ if (!strcmp(curve_name, info->name)) {
+ grp_id = info->grp_id;
+ break;
+ }
+ info++;
+ }
+
+ return grp_id;
+}
+
+int ecdsa_hash_verify(const struct ecdsa_public_key *pubkey,
+ const void *hash, size_t hash_len,
+ const void *signature, size_t sig_len)
+{
+ mbedtls_ecp_group_id grp_id;
+ mbedtls_ecp_group grp;
+ mbedtls_ecp_point Q;
+ mbedtls_mpi r, s;
+ int key_len;
+ int err;
+
+ key_len = DIV_ROUND_UP(pubkey->size_bits, 8);
+
+ /* check the signature len */
+ if (sig_len != 2 * key_len) {
+ log_debug("sig len should be twice the key len (sig len = %zu, key len = %d)\n",
+ sig_len, key_len);
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* search the group */
+ grp_id = ecdsa_search_group_id(pubkey->curve_name);
+ if (grp_id == MBEDTLS_ECP_DP_NONE) {
+ log_debug("curve name %s not found\n", pubkey->curve_name);
+ err = -EINVAL;
+ goto out;
+ }
+
+ /* init and load the group */
+ mbedtls_ecp_group_init(&grp);
+ err = mbedtls_ecp_group_load(&grp, grp_id);
+ if (err) {
+ err = -EINVAL;
+ goto free_grp;
+ }
+
+ /* prepare the pubkey */
+ mbedtls_ecp_point_init(&Q);
+ err = mbedtls_mpi_read_binary(&Q.X, pubkey->x, key_len);
+ if (err) {
+ log_debug("could not read value x of the public key (err = %d)\n",
+ err);
+ err = -EINVAL;
+ goto free_q;
+ }
+ err = mbedtls_mpi_read_binary(&Q.Y, pubkey->y, key_len);
+ if (err) {
+ log_debug("could not read value y of the public key (err = %d)\n",
+ err);
+ err = -EINVAL;
+ goto free_q;
+ }
+ err = mbedtls_mpi_lset(&Q.Z, 1);
+ if (err) {
+ log_debug("could not set value z of the public key (err = %d)\n",
+ err);
+ err = -EINVAL;
+ goto free_q;
+ }
+
+ /* check if the pubkey is valid */
+ err = mbedtls_ecp_check_pubkey(&grp, &Q);
+ if (err) {
+ log_debug("public key is invalid (err = %d)\n", err);
+ err = -EKEYREJECTED;
+ goto free_q;
+ }
+
+ /* compute r */
+ mbedtls_mpi_init(&r);
+ err = mbedtls_mpi_read_binary(&r, signature, key_len);
+ if (err) {
+ log_debug("could not read value r of the signature (err = %d)\n",
+ err);
+ err = -EINVAL;
+ goto free_r;
+ }
+
+ /* compute s */
+ mbedtls_mpi_init(&s);
+ err = mbedtls_mpi_read_binary(&s, signature + key_len, key_len);
+ if (err) {
+ log_debug("could not read value s of the signature (err = %d)\n",
+ err);
+ err = -EINVAL;
+ goto free_s;
+ }
+
+ /* check the signature */
+ err = mbedtls_ecdsa_verify(&grp, hash, hash_len, &Q, &r, &s);
+ if (err)
+ err = -EINVAL;
+
+ free_s:
+ mbedtls_mpi_free(&s);
+ free_r:
+ mbedtls_mpi_free(&r);
+ free_q:
+ mbedtls_ecp_point_free(&Q);
+ free_grp:
+ mbedtls_ecp_group_free(&grp);
+ out:
+
+ return err;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 04/15] test: lib: ecdsa: add initial test
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (2 preceding siblings ...)
2026-09-03 8:16 ` [PATCH v9 03/15] ecdsa: initial support of ecdsa using mbedtls Philippe Reynes
@ 2026-09-03 8:16 ` Philippe Reynes
2026-09-03 14:32 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 05/15] drivers: crypto: add software ecdsa support Philippe Reynes
` (11 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
Adds tests to check that the function ecdsa_hash_verify
using mbedtls is valid.
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v2:
- little change to only use test with sha enabled
v3:
- remove useless field *k in struct ecdsa_test_vector_s
- change expected value on error (don't use mbedtls error)
- manage function returns
- update third parameter of sha*_csum_wd
v4:
- define SHA256_DEF_CHUNK_SZ, SHA384_DEF_CHUNK_SZ and SHA512_DEF_CHUNK_SZ
- report skipped tests
- add const on some variables
- code cleanup
v5:
- do not define SHA256_DEF_CHUNK_SZ, SHA384_DEF_CHUNK_SZ and SHA512_DEF_CHUNK_SZ
- use CHUNKSZ_SHA256, CHUNKSZ_SHA384 and CHUNKSZ_SHA521
- do not use 528 to compule ecdsa 521 sig size but compute it
- use ut_reportf instead of ut_failf
v6:
- no change
v7:
- no change
v8:
- no change
v9:
- no change
test/lib/Makefile | 1 +
test/lib/ecdsa.c | 456 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 457 insertions(+)
create mode 100644 test/lib/ecdsa.c
diff --git a/test/lib/Makefile b/test/lib/Makefile
index f25383a40e5..e9c779a7b47 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_$(PHASE_)UT_COMPRESSION) += compression.o
ifeq ($(CONFIG_XPL_BUILD),)
obj-y += abuf.o
obj-y += alist.o
+obj-$(CONFIG_ECDSA_VERIFY_MBEDTLS) += ecdsa.o
obj-$(CONFIG_EFI_LOADER) += efi_device_path.o efi_memory.o
obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
ifdef CONFIG_RISCV
diff --git a/test/lib/ecdsa.c b/test/lib/ecdsa.c
new file mode 100644
index 00000000000..bc7737837e5
--- /dev/null
+++ b/test/lib/ecdsa.c
@@ -0,0 +1,456 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
+ */
+
+#include <command.h>
+#include <image.h>
+#include <test/lib.h>
+#include <test/test.h>
+#include <test/ut.h>
+#include <crypto/ecdsa-uclass.h>
+#include <crypto/internal/ecdsa.h>
+
+#define ECDSA_POINT_SIZE (DIV_ROUND_UP(521, 8) * 2)
+#define ECDSA_SIGNATURE_SIZE (ECDSA_POINT_SIZE * 2)
+
+struct ecdsa_test_vector_s {
+ const char *test_name;
+ const char *curve_name;
+ const char *x;
+ const char *y;
+ int size_bits;
+ const char *hash_type;
+ const char *hash_message;
+ const char *r;
+ const char *s;
+ int expected;
+};
+
+/*
+ * Those data come from RFC6979
+ */
+
+static const struct ecdsa_test_vector_s ecdsa_test_vector[] = {
+ /*
+ * secp192r1
+ */
+ {
+ .test_name = "secp192r1 sha1",
+ .curve_name = "secp192r1",
+ .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
+ .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
+ .size_bits = 192,
+ .hash_type = "sha-1",
+ .hash_message = "sample",
+ .r = "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF",
+ .s = "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp192r1 sha256",
+ .curve_name = "secp192r1",
+ .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
+ .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
+ .size_bits = 192,
+ .hash_type = "sha-256",
+ .hash_message = "sample",
+ .r = "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55",
+ .s = "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp192r1 sha384",
+ .curve_name = "secp192r1",
+ .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
+ .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
+ .size_bits = 192,
+ .hash_type = "sha-384",
+ .hash_message = "sample",
+ .r = "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5",
+ .s = "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp192r1 sha512",
+ .curve_name = "secp192r1",
+ .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
+ .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
+ .size_bits = 192,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8",
+ .s = "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp192r1 sha512 error",
+ .curve_name = "secp192r1",
+ .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
+ .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
+ .size_bits = 192,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8",
+ .s = "0F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67",
+ .expected = -EINVAL,
+ },
+ /*
+ * secp224r1
+ */
+ {
+ .test_name = "secp224r1 sha1",
+ .curve_name = "secp224r1",
+ .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
+ .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
+ .size_bits = 224,
+ .hash_type = "sha-1",
+ .hash_message = "sample",
+ .r = "22226F9D40A96E19C4A301CE5B74B115303C0F3A4FD30FC257FB57AC",
+ .s = "66D1CDD83E3AF75605DD6E2FEFF196D30AA7ED7A2EDF7AF475403D69",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp224r1 sha256",
+ .curve_name = "secp224r1",
+ .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
+ .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
+ .size_bits = 224,
+ .hash_type = "sha-256",
+ .hash_message = "sample",
+ .r = "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA",
+ .s = "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp224r1 sha384",
+ .curve_name = "secp224r1",
+ .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
+ .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
+ .size_bits = 224,
+ .hash_type = "sha-384",
+ .hash_message = "sample",
+ .r = "0B115E5E36F0F9EC81F1325A5952878D745E19D7BB3EABFABA77E953",
+ .s = "830F34CCDFE826CCFDC81EB4129772E20E122348A2BBD889A1B1AF1D",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp224r1 sha512",
+ .curve_name = "secp224r1",
+ .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
+ .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
+ .size_bits = 224,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397",
+ .s = "A4CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp224r1 sha512 error",
+ .curve_name = "secp224r1",
+ .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
+ .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
+ .size_bits = 224,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397",
+ .s = "04CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084",
+ .expected = -EINVAL,
+ },
+ /*
+ * secp256r1
+ */
+ {
+ .test_name = "secp256r1 sha1",
+ .curve_name = "secp256r1",
+ .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
+ .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
+ .size_bits = 256,
+ .hash_type = "sha-1",
+ .hash_message = "sample",
+ .r = "61340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D32",
+ .s = "6D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp256r1 sha256",
+ .curve_name = "secp256r1",
+ .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
+ .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
+ .size_bits = 256,
+ .hash_type = "sha-256",
+ .hash_message = "sample",
+ .r = "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716",
+ .s = "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp256r1 sha384",
+ .curve_name = "secp256r1",
+ .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
+ .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
+ .size_bits = 256,
+ .hash_type = "sha-384",
+ .hash_message = "sample",
+ .r = "0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719",
+ .s = "4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp256r1 sha512",
+ .curve_name = "secp256r1",
+ .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
+ .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
+ .size_bits = 256,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00",
+ .s = "2362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp256r1 sha512 error",
+ .curve_name = "secp256r1",
+ .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
+ .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
+ .size_bits = 256,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00",
+ .s = "0362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE",
+ .expected = -EINVAL,
+ },
+ /*
+ * secp384r1
+ */
+ {
+ .test_name = "secp384r1 sha1",
+ .curve_name = "secp384r1",
+ .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
+ .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
+ .size_bits = 384,
+ .hash_type = "sha-1",
+ .hash_message = "sample",
+ .r = "EC748D839243D6FBEF4FC5C4859A7DFFD7F3ABDDF72014540C16D73309834FA37B9BA002899F6FDA3A4A9386790D4EB2",
+ .s = "A3BCFA947BEEF4732BF247AC17F71676CB31A847B9FF0CBC9C9ED4C1A5B3FACF26F49CA031D4857570CCB5CA4424A443",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp384r1 sha256",
+ .curve_name = "secp384r1",
+ .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
+ .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
+ .size_bits = 384,
+ .hash_type = "sha-256",
+ .hash_message = "sample",
+ .r = "21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33BDE1E888E63355D92FA2B3C36D8FB2CD",
+ .s = "F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEBEFDC63ECCD1AC42EC0CB8668A4FA0AB0",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp384r1 sha384",
+ .curve_name = "secp384r1",
+ .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
+ .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
+ .size_bits = 384,
+ .hash_type = "sha-384",
+ .hash_message = "sample",
+ .r = "94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C81A648152E44ACF96E36DD1E80FABE46",
+ .s = "99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94FA329C145786E679E7B82C71A38628AC8",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp384r1 sha512",
+ .curve_name = "secp384r1",
+ .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
+ .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
+ .size_bits = 384,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799CFE30F35CC900056D7C99CD7882433709",
+ .s = "512C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112DC7CC3EF3446DEFCEB01A45C2667FDD5",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp384r1 sha512 error",
+ .curve_name = "secp384r1",
+ .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
+ .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
+ .size_bits = 384,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799CFE30F35CC900056D7C99CD7882433709",
+ .s = "012C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112DC7CC3EF3446DEFCEB01A45C2667FDD5",
+ .expected = -EINVAL,
+ },
+ /*
+ * secp521r1
+ */
+ {
+ .test_name = "secp521r1 sha1",
+ .curve_name = "secp521r1",
+ .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
+ .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
+ .size_bits = 521,
+ .hash_type = "sha-1",
+ .hash_message = "sample",
+ .r = "00343B6EC45728975EA5CBA6659BBB6062A5FF89EEA58BE3C80B619F322C87910FE092F7D45BB0F8EEE01ED3F20BABEC079D202AE677B243AB40B5431D497C55D75D",
+ .s = "00E7B0E675A9B24413D448B8CC119D2BF7B2D2DF032741C096634D6D65D0DBE3D5694625FB9E8104D3B842C1B0E2D0B98BEA19341E8676AEF66AE4EBA3D5475D5D16",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp521r1 sha256",
+ .curve_name = "secp521r1",
+ .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
+ .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
+ .size_bits = 521,
+ .hash_type = "sha-256",
+ .hash_message = "sample",
+ .r = "01511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E1A7",
+ .s = "004A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7ECFC",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp521r1 sha384",
+ .curve_name = "secp521r1",
+ .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
+ .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
+ .size_bits = 521,
+ .hash_type = "sha-384",
+ .hash_message = "sample",
+ .r = "01EA842A0E17D2DE4F92C15315C63DDF72685C18195C2BB95E572B9C5136CA4B4B576AD712A52BE9730627D16054BA40CC0B8D3FF035B12AE75168397F5D50C67451",
+ .s = "01F21A3CEE066E1961025FB048BD5FE2B7924D0CD797BABE0A83B66F1E35EEAF5FDE143FA85DC394A7DEE766523393784484BDF3E00114A1C857CDE1AA203DB65D61",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp521r1 sha512",
+ .curve_name = "secp521r1",
+ .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
+ .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
+ .size_bits = 521,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "00C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F174E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E377FA",
+ .s = "00617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF282623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A67A",
+ .expected = 0,
+ },
+ {
+ .test_name = "secp521r1 sha512 error",
+ .curve_name = "secp521r1",
+ .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
+ .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
+ .size_bits = 521,
+ .hash_type = "sha-512",
+ .hash_message = "sample",
+ .r = "00C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F174E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E377FA",
+ .s = "00017CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF282623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A67A",
+ .expected = -EINVAL,
+ },
+};
+
+static int ecdsa_test(struct unit_test_state *uts,
+ const struct ecdsa_test_vector_s *tv)
+{
+ struct ecdsa_public_key pubkey;
+ unsigned char x[ECDSA_POINT_SIZE];
+ unsigned char y[ECDSA_POINT_SIZE];
+ unsigned char hash[512 / 8];
+ size_t hash_len;
+ unsigned char signature[ECDSA_SIGNATURE_SIZE];
+ size_t sig_len;
+ int ret;
+
+ sig_len = DIV_ROUND_UP(tv->size_bits, 8);
+
+ pubkey.curve_name = tv->curve_name;
+ ret = hex2bin(x, tv->x, strlen(tv->x) / 2);
+ ut_asserteq(0, ret);
+ pubkey.x = x;
+ ret = hex2bin(y, tv->y, strlen(tv->y) / 2);
+ ut_asserteq(0, ret);
+ pubkey.y = y;
+ pubkey.size_bits = tv->size_bits;
+
+ if (!strcmp(tv->hash_type, "sha-1")) {
+#if CONFIG_IS_ENABLED(SHA1)
+ hash_len = SHA1_SUM_LEN;
+ sha1_csum_wd(tv->hash_message, strlen(tv->hash_message),
+ hash, SHA1_DEF_CHUNK_SZ);
+#else
+ /* sha1 is not supported so we skip this test */
+ ut_reportf("Test %s skipped (sha1 not supported)",
+ tv->test_name);
+ goto out;
+#endif
+ } else if (!strcmp(tv->hash_type, "sha-256")) {
+#if CONFIG_IS_ENABLED(SHA256)
+ hash_len = SHA256_SUM_LEN;
+ sha256_csum_wd(tv->hash_message, strlen(tv->hash_message),
+ hash, CHUNKSZ_SHA256);
+#else
+ /* sha256 is not supported so we skip this test */
+ ut_reportf("Test %s skipped (sha256 not supported)",
+ tv->test_name);
+ goto out;
+#endif
+ } else if (!strcmp(tv->hash_type, "sha-384")) {
+#if CONFIG_IS_ENABLED(SHA384)
+ hash_len = SHA384_SUM_LEN;
+ sha384_csum_wd(tv->hash_message, strlen(tv->hash_message),
+ hash, CHUNKSZ_SHA384);
+#else
+ /* sha384 is not supported so we skip this test */
+ ut_reportf("Test %s skipped (sha384 not supported)",
+ tv->test_name);
+ goto out;
+#endif
+ } else if (!strcmp(tv->hash_type, "sha-512")) {
+#if CONFIG_IS_ENABLED(SHA512)
+ hash_len = SHA512_SUM_LEN;
+ sha512_csum_wd(tv->hash_message, strlen(tv->hash_message),
+ hash, CHUNKSZ_SHA512);
+#else
+ /* sha512 is not supported so we skip this test */
+ ut_reportf("Test %s skipped (sha512 not supported)",
+ tv->test_name);
+ goto out;
+#endif
+ } else {
+ ut_reportf("Unknown hash type (%s)", tv->hash_type);
+ return -EINVAL;
+ }
+
+ ret = hex2bin(signature, tv->r, sig_len);
+ ut_asserteq(0, ret);
+ ret = hex2bin(signature + sig_len, tv->s, sig_len);
+ ut_asserteq(0, ret);
+ sig_len = sig_len * 2;
+
+ ret = ecdsa_hash_verify(&pubkey,
+ hash, hash_len,
+ signature, sig_len);
+ ut_asserteq(tv->expected, ret);
+
+#if !CONFIG_IS_ENABLED(SHA1) || !CONFIG_IS_ENABLED(SHA256) || !CONFIG_IS_ENABLED(SHA384) || !CONFIG_IS_ENABLED(SHA512)
+ out:
+#endif
+
+ return 0;
+}
+
+static int lib_ecdsa(struct unit_test_state *uts)
+{
+ int i, ret;
+ size_t num_test = ARRAY_SIZE(ecdsa_test_vector);
+
+ for (i = 0; i < num_test; i++) {
+ ret = ecdsa_test(uts, &ecdsa_test_vector[i]);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+LIB_TEST(lib_ecdsa, 0);
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 05/15] drivers: crypto: add software ecdsa support
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (3 preceding siblings ...)
2026-09-03 8:16 ` [PATCH v9 04/15] test: lib: ecdsa: add initial test Philippe Reynes
@ 2026-09-03 8:16 ` Philippe Reynes
2026-09-03 14:32 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 06/15] test: dm: ecdsa.c: clean this test as software ecdsa is now implemented Philippe Reynes
` (10 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
Add a software ecdsa driver so it is
now possible to use ecdsa signature on
board without ecdsa hardware support.
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v2:
- no change
v3:
- add depends on ECDSA_VERIFY to ECDSA_SW
- change sw_ecdsa_verify to ecdsa_hash_verify
- v4
- use ECDSA_MBEDTLS to build the driver
- clean include (change order)
v5:
- use $(PHASE_) in the Makefile for the driver
v6:
- remove include u-boot/ecdsa.h from ecdsa-sw.c
v7:
- no change
v8:
- no change
v9:
- no change
drivers/crypto/Makefile | 1 +
drivers/crypto/ecdsa/Makefile | 6 ++++++
drivers/crypto/ecdsa/ecdsa-sw.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 39 insertions(+)
create mode 100644 drivers/crypto/ecdsa/Makefile
create mode 100644 drivers/crypto/ecdsa/ecdsa-sw.c
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index e4a4482b7f3..8170e4cae9c 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -4,6 +4,7 @@
# http://www.samsung.com
obj-$(CONFIG_EXYNOS_ACE_SHA) += ace_sha.o
+obj-$(CONFIG_ECDSA) += ecdsa/
obj-y += aes/
obj-y += rsa_mod_exp/
obj-y += fsl/
diff --git a/drivers/crypto/ecdsa/Makefile b/drivers/crypto/ecdsa/Makefile
new file mode 100644
index 00000000000..89be50824cb
--- /dev/null
+++ b/drivers/crypto/ecdsa/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
+#
+
+obj-$(CONFIG_$(PHASE_)ECDSA_VERIFY_MBEDTLS) += ecdsa-sw.o
diff --git a/drivers/crypto/ecdsa/ecdsa-sw.c b/drivers/crypto/ecdsa/ecdsa-sw.c
new file mode 100644
index 00000000000..2af1405f73b
--- /dev/null
+++ b/drivers/crypto/ecdsa/ecdsa-sw.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
+ */
+#include <crypto/ecdsa-uclass.h>
+#include <crypto/internal/ecdsa.h>
+#include <dm.h>
+#include <linux/types.h>
+
+static int ops_sw_ecdsa_verify(__always_unused struct udevice *dev,
+ const struct ecdsa_public_key *pubkey,
+ const void *hash, size_t hash_len,
+ const void *signature, size_t sig_len)
+{
+ return ecdsa_hash_verify(pubkey, hash, hash_len, signature, sig_len);
+}
+
+static const struct ecdsa_ops sw_ecdsa_ops = {
+ .verify = ops_sw_ecdsa_verify,
+};
+
+U_BOOT_DRIVER(sw_ecdsa) = {
+ .name = "sw_ecdsa",
+ .id = UCLASS_ECDSA,
+ .ops = &sw_ecdsa_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRVINFO(sw_ecdsa) = {
+ .name = "sw_ecdsa",
+};
+
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 06/15] test: dm: ecdsa.c: clean this test as software ecdsa is now implemented
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (4 preceding siblings ...)
2026-09-03 8:16 ` [PATCH v9 05/15] drivers: crypto: add software ecdsa support Philippe Reynes
@ 2026-09-03 8:16 ` Philippe Reynes
2026-09-03 14:33 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 07/15] test: py: vboot: prepare integration test for ecdsa Philippe Reynes
` (9 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes
The test ecdsa was done when ecdsa was only supported by hardware.
So it wasn't possible to test ecdsa on sandbox, and there is a test
to check that ecdsa is not supported on sandbox.
Now, there is a software implementation of ecdsa. So we add a test
to verify that ecdsa_verify may be used on sandbox.
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v2:
- initial version
v3:
- no change
v4:
- add a test that use ecdsa_verify
v5:
- change secp256r1 to ecdsa256
- check that checksum and crypto are not null
v6:
- update commit message
- remove fdt_strerror in macro CHECK
- return ENOMEM when malloc fails
- add a define FDT_MAX_SIZE to avoid hardcoded value
v7:
- change uint8_t to u8
- set required_keynode to -1
v8:
- remove macro CHECK with a goto inside
- use lowercase for hex data
- code cleanup
v9:
- no change
test/dm/ecdsa.c | 107 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 97 insertions(+), 10 deletions(-)
diff --git a/test/dm/ecdsa.c b/test/dm/ecdsa.c
index d7eac7115f7..261ca3f9f73 100644
--- a/test/dm/ecdsa.c
+++ b/test/dm/ecdsa.c
@@ -3,36 +3,123 @@
#include <crypto/ecdsa-uclass.h>
#include <dm.h>
#include <dm/test.h>
+#include <malloc.h>
#include <test/ut.h>
#include <u-boot/ecdsa.h>
+#define FDT_MAX_SIZE 512
+
+static int set_fdt_ecdsa_point(char *fdt, const char *name, const char *data)
+{
+ char *value = NULL;
+ size_t len;
+ int ret = 0;
+
+ if (!fdt || !name || !data) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ len = strlen(data) / 2;
+ if (!len) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ value = malloc(len);
+ if (!value) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = hex2bin(value, data, len);
+ if (ret)
+ goto out;
+
+ ret = fdt_property(fdt, name, value, len);
+ if (ret)
+ goto out;
+
+out:
+ free(value);
+ return ret;
+}
+
+static int create_fdt_with_ecdsa_key(struct unit_test_state *uts,
+ char *fdt, size_t size,
+ const char *name, const char *curve,
+ const char *x, const char *y)
+{
+ ut_assertok(fdt_create(fdt, size));
+ ut_assertok(fdt_finish_reservemap(fdt));
+ ut_assertok(fdt_begin_node(fdt, ""));
+ ut_assertok(fdt_begin_node(fdt, "signature"));
+ ut_assertok(fdt_begin_node(fdt, name));
+ ut_assertok(fdt_property_string(fdt, "algo", "sha256,ecdsa256"));
+ ut_assertok(set_fdt_ecdsa_point(fdt, "ecdsa,y-point", y));
+ ut_assertok(set_fdt_ecdsa_point(fdt, "ecdsa,x-point", x));
+ ut_assertok(fdt_property_string(fdt, "ecdsa,curve", curve));
+ ut_assertok(fdt_property_string(fdt, "key-name-hint", name));
+ ut_assertok(fdt_end_node(fdt)); /* name */
+ ut_assertok(fdt_end_node(fdt)); /* "signature" */
+ ut_assertok(fdt_end_node(fdt)); /* "" */
+ ut_assertok(fdt_finish(fdt));
+ ut_assertok(fdt_pack(fdt));
+
+ return 0;
+}
+
/*
* Basic test of the ECDSA uclass and ecdsa_verify()
*
- * ECDSA implementations in u-boot are hardware-dependent. Until we have a
- * software implementation that can be compiled into the sandbox, all we can
- * test is the uclass support.
+ * ECDSA software implementation is tested in another test,
+ * so we only check that the UCLASS_ECDSA uclass may be used.
*
- * The uclass_get() test is redundant since ecdsa_verify() would also fail. We
- * run both functions in order to isolate the cause more clearly. i.e. is
- * ecdsa_verify() failing because the UCLASS is absent/broken?
+ * The data used in this test come from RFC6979 and use the
+ * sample with curve NIST P-256, hash sha256 and text "sample".
*/
static int dm_test_ecdsa_verify(struct unit_test_state *uts)
{
struct uclass *ucp;
+ const char *full_name = "sha256,ecdsa256";
+ const char *name = "key-ecdsa-256";
+ const char *curve = "prime256v1";
+ const char *x = "60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6";
+ const char *y = "7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299";
+ const char *r = "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716";
+ const char *s = "f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8";
+ u8 sig[64];
+ char fdt[FDT_MAX_SIZE];
- struct checksum_algo algo = {
- .checksum_len = 256,
+ struct image_region region[] = {
+ {
+ .data = "sample",
+ .size = strlen("sample"),
+ },
};
struct image_sign_info info = {
- .checksum = &algo,
+ .checksum = image_get_checksum_algo(full_name),
+ .crypto = image_get_crypto_algo(full_name),
+ .required_keynode = -1,
+ .fdt_blob = fdt,
};
+ ut_assertnonnull(info.checksum);
+ ut_assertnonnull(info.crypto);
+
+ /* create a fdt with the public key */
+ ut_assertok(create_fdt_with_ecdsa_key(uts, fdt, sizeof(fdt), name, curve, x, y));
+
+ /* prepare the signature */
+ ut_assertok(hex2bin(sig + 0, r, strlen(r) / 2));
+ ut_assertok(hex2bin(sig + 32, s, strlen(s) / 2));
+
ut_assertok(uclass_get(UCLASS_ECDSA, &ucp));
ut_assertnonnull(ucp);
- ut_asserteq(-ENODEV, ecdsa_verify(&info, NULL, 0, NULL, 0));
+ ut_assertok(ecdsa_verify(&info, region, 1, sig, sizeof(sig)));
return 0;
}
+
DM_TEST(dm_test_ecdsa_verify, UTF_SCAN_PDATA | UTF_SCAN_FDT);
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 07/15] test: py: vboot: prepare integration test for ecdsa
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (5 preceding siblings ...)
2026-09-03 8:16 ` [PATCH v9 06/15] test: dm: ecdsa.c: clean this test as software ecdsa is now implemented Philippe Reynes
@ 2026-09-03 8:16 ` Philippe Reynes
2026-09-03 15:42 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 08/15] test: vboot: add " Philippe Reynes
` (8 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
The vboot tests only consider rsa algo for signature.
To prepare the integration of ecdsa test, the signature
algo is now explicit.
Reviewed-by: Simon Glass <simon.glass@canonical.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v2:
- initial version
v3:
- no change
v4:
- no change
v5:
- no change
v6:
- no change
v7:
- no change
v8:
- no change
v9:
- some minor update to fix rebase on next
test/py/tests/test_fit_ecdsa.py | 2 +-
test/py/tests/test_vboot.py | 104 +++++++++---------
....its => sign-configs-sha1-rsa2048-pss.its} | 0
...sha1.its => sign-configs-sha1-rsa2048.its} | 0
... sign-configs-sha256-rsa2048-pss-prod.its} | 0
...ts => sign-configs-sha256-rsa2048-pss.its} | 0
...56.its => sign-configs-sha256-rsa2048.its} | 0
...84.its => sign-configs-sha384-rsa3072.its} | 0
...s.its => sign-images-sha1-rsa2048-pss.its} | 0
...-sha1.its => sign-images-sha1-rsa2048.its} | 0
...its => sign-images-sha256-rsa2048-pss.its} | 0
...256.its => sign-images-sha256-rsa2048.its} | 0
...384.its => sign-images-sha384-rsa3072.its} | 0
13 files changed, 54 insertions(+), 52 deletions(-)
rename test/py/tests/vboot/{sign-configs-sha1-pss.its => sign-configs-sha1-rsa2048-pss.its} (100%)
rename test/py/tests/vboot/{sign-configs-sha1.its => sign-configs-sha1-rsa2048.its} (100%)
rename test/py/tests/vboot/{sign-configs-sha256-pss-prod.its => sign-configs-sha256-rsa2048-pss-prod.its} (100%)
rename test/py/tests/vboot/{sign-configs-sha256-pss.its => sign-configs-sha256-rsa2048-pss.its} (100%)
rename test/py/tests/vboot/{sign-configs-sha256.its => sign-configs-sha256-rsa2048.its} (100%)
rename test/py/tests/vboot/{sign-configs-sha384.its => sign-configs-sha384-rsa3072.its} (100%)
rename test/py/tests/vboot/{sign-images-sha1-pss.its => sign-images-sha1-rsa2048-pss.its} (100%)
rename test/py/tests/vboot/{sign-images-sha1.its => sign-images-sha1-rsa2048.its} (100%)
rename test/py/tests/vboot/{sign-images-sha256-pss.its => sign-images-sha256-rsa2048-pss.its} (100%)
rename test/py/tests/vboot/{sign-images-sha256.its => sign-images-sha256-rsa2048.its} (100%)
rename test/py/tests/vboot/{sign-images-sha384.its => sign-images-sha384-rsa3072.its} (100%)
diff --git a/test/py/tests/test_fit_ecdsa.py b/test/py/tests/test_fit_ecdsa.py
index 3e816d68eb6..e59390374af 100644
--- a/test/py/tests/test_fit_ecdsa.py
+++ b/test/py/tests/test_fit_ecdsa.py
@@ -102,7 +102,7 @@ def test_fit_ecdsa(ubman):
with open(key_file, 'w') as f:
f.write(key.export_key(format='PEM'))
- assemble_fit_image(fit_file, f'{datadir}/sign-images-sha256.its', tempdir)
+ assemble_fit_image(fit_file, f'{datadir}/sign-images-sha256-rsa2048.its', tempdir)
fit = SignableFitImage(ubman, fit_file)
nodes = fit.find_signable_image_nodes()
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index e9259584e32..33cbcea5c24 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -84,21 +84,21 @@ def make_fit(its, ubman, mkimage, dtc_args, datadir, fit):
# Only run the full suite on a few combinations, since it doesn't add any more
# test coverage.
TESTDATA_IN = [
- ['sha1-basic', 'sha1', '', None, False, True, False, False],
- ['sha1-pad', 'sha1', '', '-E -p 0x10000', False, False, False, False],
- ['sha1-pss', 'sha1', '-pss', None, False, False, False, False],
- ['sha1-pss-pad', 'sha1', '-pss', '-E -p 0x10000', False, False, False, False],
- ['sha256-basic', 'sha256', '', None, False, False, False, False],
- ['sha256-pad', 'sha256', '', '-E -p 0x10000', False, False, False, False],
- ['sha256-pss', 'sha256', '-pss', None, False, False, False, False],
- ['sha256-pss-pad', 'sha256', '-pss', '-E -p 0x10000', False, False, False, False],
- ['sha256-pss-required', 'sha256', '-pss', None, True, False, False, False],
- ['sha256-pss-pad-required', 'sha256', '-pss', '-E -p 0x10000', True, True, False, False],
- ['sha384-basic', 'sha384', '', None, False, False, False, False],
- ['sha384-pad', 'sha384', '', '-E -p 0x10000', False, False, False, False],
- ['algo-arg', 'algo-arg', '', '-o sha256,rsa2048', False, False, True, False],
- ['sha256-global-sign', 'sha256', '', '', False, False, False, True],
- ['sha256-global-sign-pss', 'sha256', '-pss', '', False, False, False, True],
+ ['sha1-basic', 'sha1', '-rsa2048', '', None, False, True, False, False],
+ ['sha1-pad', 'sha1', '-rsa2048', '', '-E -p 0x10000', False, False, False, False],
+ ['sha1-pss', 'sha1', '-rsa2048', '-pss', None, False, False, False, False],
+ ['sha1-pss-pad', 'sha1', '-rsa2048', '-pss', '-E -p 0x10000', False, False, False, False],
+ ['sha256-basic', 'sha256', '-rsa2048', '', None, False, False, False, False],
+ ['sha256-pad', 'sha256', '-rsa2048', '', '-E -p 0x10000', False, False, False, False],
+ ['sha256-pss', 'sha256', '-rsa2048', '-pss', None, False, False, False, False],
+ ['sha256-pss-pad', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', False, False, False, False],
+ ['sha256-pss-required', 'sha256', '-rsa2048', '-pss', None, True, False, False, False],
+ ['sha256-pss-pad-required', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', True, True, False, False],
+ ['sha384-basic', 'sha384', '-rsa3072', '', None, False, False, False, False],
+ ['sha384-pad', 'sha384', '-rsa3072', '', '-E -p 0x10000', False, False, False, False],
+ ['algo-arg', 'algo-arg', '', '', '-o sha256,rsa2048', False, False, True, False],
+ ['sha256-global-sign', 'sha256', '-rsa2048', '', '', False, False, False, True],
+ ['sha256-global-sign-pss', 'sha256', '-rsa2048', '-pss', '', False, False, False, True],
]
# Mark all but the first test as slow, so they are not run with '-k not slow'
@@ -111,9 +111,9 @@ TESTDATA += [pytest.param(*v, marks=pytest.mark.slow) for v in TESTDATA_IN[1:]]
@pytest.mark.requiredtool('fdtget')
@pytest.mark.requiredtool('fdtput')
@pytest.mark.requiredtool('openssl')
-@pytest.mark.parametrize("name,sha_algo,padding,sign_options,required,full_test,algo_arg,global_sign",
+@pytest.mark.parametrize("name,sha_algo,sig_algo,padding,sign_options,required,full_test,algo_arg,global_sign",
TESTDATA)
-def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
+def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
full_test, algo_arg, global_sign):
"""Test verified boot signing with mkimage and verification with 'bootm'.
@@ -287,7 +287,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
utils.run_and_log(ubman, 'openssl req -batch -new -x509 -key %s%s.key '
'-out %s%s.crt' % (tmpdir, name, tmpdir, name))
- def test_with_algo(sha_algo, padding, sign_options):
+ def test_with_algo(sha_algo, sig_algo, padding, sign_options):
"""Test verified boot with the given hash algorithm.
This is the main part of the test code. The same procedure is followed
@@ -308,7 +308,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
# Build the FIT, but don't sign anything yet
ubman.log.action('%s: Test FIT with signed images' % sha_algo)
- make_fit('sign-images-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
+ make_fit('sign-images-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
run_bootm(sha_algo, 'unsigned images', ' - OK' if algo_arg else 'dev-', True)
# Sign images with our dev keys
@@ -319,7 +319,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
dtc('sandbox-u-boot.dts', ubman, dtc_args, datadir, tmpdir, dtb)
ubman.log.action('%s: Test FIT with signed configuration' % sha_algo)
- make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
+ make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
run_bootm(sha_algo, 'unsigned config', '%s+ OK' % ('sha256' if algo_arg else sha_algo), True)
# Sign images with our dev keys
@@ -390,7 +390,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
run_bootm(sha_algo, 'evil clone', 'Bad Data Hash', False, efit)
# Create a new properly signed fit and replace header bytes
- make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
+ make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
sign_fit(sha_algo, sign_options)
bcfg = ubman.config.buildconfig
max_size = int(bcfg.get('config_fit_signature_max_size', 0x10000000), 0)
@@ -424,7 +424,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
# Create a new properly signed fit and replace hashed-strings
# size property
- make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
+ make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
sign_fit(sha_algo, sign_options)
utils.run_and_log(ubman, 'fdtput -t x %s %s hashed-strings 0' %
(fit, sig_node))
@@ -448,7 +448,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
'Bad Data Hash', False)
ubman.log.action('%s: Check in-bounds hashed-strings size' % sha_algo)
- def test_required_key(sha_algo, padding, sign_options):
+ def test_required_key(sha_algo, sig_algo, padding, sign_options):
"""Test verified boot with the given hash algorithm.
This function tests if U-Boot rejects an image when a required key isn't
@@ -470,12 +470,12 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
# Build the FIT with prod key (keys required) and sign it. This puts the
# signature into sandbox-u-boot.dtb, marked 'required'
- make_fit('sign-configs-%s%s-prod.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
+ make_fit('sign-configs-%s%s%s-prod.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
sign_fit(sha_algo, sign_options)
# Build the FIT with dev key (keys NOT required). This adds the
# signature into sandbox-u-boot.dtb, NOT marked 'required'.
- make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
+ make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
sign_fit_norequire(sha_algo, sign_options)
# So now sandbox-u-boot.dtb two signatures, for the prod and dev keys.
@@ -487,7 +487,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
# Build the FIT with dev key (keys required) and sign it. This puts the
# signature into sandbox-u-boot.dtb, marked 'required'.
- make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
+ make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
sign_fit(sha_algo, sign_options)
# Set the required-mode policy to "any".
@@ -567,8 +567,9 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
dtb = '%ssandbox-u-boot.dtb' % tmpdir
sig_node = '/configurations/conf-1/signature'
- create_rsa_pair('dev')
- create_rsa_pair('prod')
+ if sig_algo == "-rsa2048" or sig_algo == "-rsa3072" or sig_algo == "":
+ create_rsa_pair('dev')
+ create_rsa_pair('prod')
# Create a number kernel image with zeroes
with open('%stest-kernel.bin' % tmpdir, 'wb') as fd:
@@ -587,9 +588,9 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
if global_sign:
test_global_sign(sha_algo, padding, sign_options)
elif required:
- test_required_key(sha_algo, padding, sign_options)
+ test_required_key(sha_algo, sig_algo, padding, sign_options)
else:
- test_with_algo(sha_algo, padding, sign_options)
+ test_with_algo(sha_algo, sig_algo, padding, sign_options)
finally:
# Go back to the original U-Boot with the correct dtb.
ubman.config.dtb = old_dtb
@@ -616,6 +617,7 @@ def test_vboot_ext_data_bounds(ubman):
by U-Boot to hold public keys from the signing process.
"""
sha_algo = 'sha256'
+ sig_algo = '-rsa2048'
def run_bootm(test_type, expect_string):
"""Run a 'bootm' command in U-Boot and expect it to fail.
@@ -684,7 +686,7 @@ def test_vboot_ext_data_bounds(ubman):
sign_fit() overwrites the FIT, so a new one is built before each test
case mutates its external-data properties.
"""
- make_fit('sign-configs-%s.its' % sha_algo, ubman, mkimage, dtc_args,
+ make_fit('sign-configs-%s%s.its' % (sha_algo, sig_algo), ubman, mkimage, dtc_args,
datadir, fit)
sign_fit('-E')
@@ -762,21 +764,21 @@ def test_vboot_ext_data_bounds(ubman):
TESTDATA_IN = [
- ['sha1-basic', 'sha1', '', None, False],
- ['sha1-pad', 'sha1', '', '-E -p 0x10000', False],
- ['sha1-pss', 'sha1', '-pss', None, False],
- ['sha1-pss-pad', 'sha1', '-pss', '-E -p 0x10000', False],
- ['sha256-basic', 'sha256', '', None, False],
- ['sha256-pad', 'sha256', '', '-E -p 0x10000', False],
- ['sha256-pss', 'sha256', '-pss', None, False],
- ['sha256-pss-pad', 'sha256', '-pss', '-E -p 0x10000', False],
- ['sha256-pss-required', 'sha256', '-pss', None, False],
- ['sha256-pss-pad-required', 'sha256', '-pss', '-E -p 0x10000', False],
- ['sha384-basic', 'sha384', '', None, False],
- ['sha384-pad', 'sha384', '', '-E -p 0x10000', False],
- ['algo-arg', 'algo-arg', '', '-o sha256,rsa2048', True],
- ['sha256-global-sign', 'sha256', '', '', False],
- ['sha256-global-sign-pss', 'sha256', '-pss', '', False],
+ ['sha1-basic', 'sha1', '-rsa2048', '', None, False],
+ ['sha1-pad', 'sha1', '-rsa2048', '', '-E -p 0x10000', False],
+ ['sha1-pss', 'sha1', '-rsa2048', '-pss', None, False],
+ ['sha1-pss-pad', 'sha1', '-rsa2048', '-pss', '-E -p 0x10000', False],
+ ['sha256-basic', 'sha256', '-rsa2048', '', None, False],
+ ['sha256-pad', 'sha256', '-rsa2048', '', '-E -p 0x10000', False],
+ ['sha256-pss', 'sha256', '-rsa2048', '-pss', None, False],
+ ['sha256-pss-pad', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', False],
+ ['sha256-pss-required', 'sha256', '-rsa2048', '-pss', None, False],
+ ['sha256-pss-pad-required', 'sha256', '-rsa2048' , '-pss', '-E -p 0x10000', False],
+ ['sha384-basic', 'sha384', '-rsa3072', '', None, False],
+ ['sha384-pad', 'sha384', '-rsa3072', '', '-E -p 0x10000', False],
+ ['algo-arg', 'algo-arg', '', '', '-o sha256,rsa2048', True],
+ ['sha256-global-sign', 'sha256', '-rsa2048', '', '', False],
+ ['sha256-global-sign-pss', 'sha256', '-rsa2048', '-pss', '', False],
]
# Mark all but the first test as slow, so they are not run with '-k not slow'
@@ -787,8 +789,8 @@ TESTDATA += [pytest.param(*v, marks=pytest.mark.slow) for v in TESTDATA_IN[1:]]
@pytest.mark.buildconfigspec('fit_signature')
@pytest.mark.requiredtool('dtc')
@pytest.mark.requiredtool('openssl')
-@pytest.mark.parametrize("name,sha_algo,padding,sign_options,algo_arg", TESTDATA)
-def test_fdt_add_pubkey(ubman, name, sha_algo, padding, sign_options, algo_arg):
+@pytest.mark.parametrize("name,sha_algo,sig_algo,padding,sign_options,algo_arg", TESTDATA)
+def test_fdt_add_pubkey(ubman, name, sha_algo, sig_algo, padding, sign_options, algo_arg):
"""Test fdt_add_pubkey utility with bunch of different algo options."""
def sign_fit(sha_algo, options):
@@ -807,7 +809,7 @@ def test_fdt_add_pubkey(ubman, name, sha_algo, padding, sign_options, algo_arg):
ubman.log.action('%s: Sign images' % sha_algo)
utils.run_and_log(ubman, args)
- def test_add_pubkey(sha_algo, padding, sign_options):
+ def test_add_pubkey(sha_algo, sig_algo, padding, sign_options):
"""Test fdt_add_pubkey utility with given hash algorithm and padding.
This function tests if fdt_add_pubkey utility may add public keys into dtb.
@@ -830,7 +832,7 @@ def test_fdt_add_pubkey(ubman, name, sha_algo, padding, sign_options, algo_arg):
'rsa3072' if sha_algo == 'sha384' else 'rsa2048'),
'-k', tmpdir, '-n', 'dev', '-r', 'conf', dtb])
- make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
+ make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
# Sign images with our dev keys
sign_fit(sha_algo, sign_options)
@@ -852,4 +854,4 @@ def test_fdt_add_pubkey(ubman, name, sha_algo, padding, sign_options, algo_arg):
# keys created in test_vboot test
- test_add_pubkey(sha_algo, padding, sign_options)
+ test_add_pubkey(sha_algo, sig_algo, padding, sign_options)
diff --git a/test/py/tests/vboot/sign-configs-sha1-pss.its b/test/py/tests/vboot/sign-configs-sha1-rsa2048-pss.its
similarity index 100%
rename from test/py/tests/vboot/sign-configs-sha1-pss.its
rename to test/py/tests/vboot/sign-configs-sha1-rsa2048-pss.its
diff --git a/test/py/tests/vboot/sign-configs-sha1.its b/test/py/tests/vboot/sign-configs-sha1-rsa2048.its
similarity index 100%
rename from test/py/tests/vboot/sign-configs-sha1.its
rename to test/py/tests/vboot/sign-configs-sha1-rsa2048.its
diff --git a/test/py/tests/vboot/sign-configs-sha256-pss-prod.its b/test/py/tests/vboot/sign-configs-sha256-rsa2048-pss-prod.its
similarity index 100%
rename from test/py/tests/vboot/sign-configs-sha256-pss-prod.its
rename to test/py/tests/vboot/sign-configs-sha256-rsa2048-pss-prod.its
diff --git a/test/py/tests/vboot/sign-configs-sha256-pss.its b/test/py/tests/vboot/sign-configs-sha256-rsa2048-pss.its
similarity index 100%
rename from test/py/tests/vboot/sign-configs-sha256-pss.its
rename to test/py/tests/vboot/sign-configs-sha256-rsa2048-pss.its
diff --git a/test/py/tests/vboot/sign-configs-sha256.its b/test/py/tests/vboot/sign-configs-sha256-rsa2048.its
similarity index 100%
rename from test/py/tests/vboot/sign-configs-sha256.its
rename to test/py/tests/vboot/sign-configs-sha256-rsa2048.its
diff --git a/test/py/tests/vboot/sign-configs-sha384.its b/test/py/tests/vboot/sign-configs-sha384-rsa3072.its
similarity index 100%
rename from test/py/tests/vboot/sign-configs-sha384.its
rename to test/py/tests/vboot/sign-configs-sha384-rsa3072.its
diff --git a/test/py/tests/vboot/sign-images-sha1-pss.its b/test/py/tests/vboot/sign-images-sha1-rsa2048-pss.its
similarity index 100%
rename from test/py/tests/vboot/sign-images-sha1-pss.its
rename to test/py/tests/vboot/sign-images-sha1-rsa2048-pss.its
diff --git a/test/py/tests/vboot/sign-images-sha1.its b/test/py/tests/vboot/sign-images-sha1-rsa2048.its
similarity index 100%
rename from test/py/tests/vboot/sign-images-sha1.its
rename to test/py/tests/vboot/sign-images-sha1-rsa2048.its
diff --git a/test/py/tests/vboot/sign-images-sha256-pss.its b/test/py/tests/vboot/sign-images-sha256-rsa2048-pss.its
similarity index 100%
rename from test/py/tests/vboot/sign-images-sha256-pss.its
rename to test/py/tests/vboot/sign-images-sha256-rsa2048-pss.its
diff --git a/test/py/tests/vboot/sign-images-sha256.its b/test/py/tests/vboot/sign-images-sha256-rsa2048.its
similarity index 100%
rename from test/py/tests/vboot/sign-images-sha256.its
rename to test/py/tests/vboot/sign-images-sha256-rsa2048.its
diff --git a/test/py/tests/vboot/sign-images-sha384.its b/test/py/tests/vboot/sign-images-sha384-rsa3072.its
similarity index 100%
rename from test/py/tests/vboot/sign-images-sha384.its
rename to test/py/tests/vboot/sign-images-sha384-rsa3072.its
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 08/15] test: vboot: add test for ecdsa
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (6 preceding siblings ...)
2026-09-03 8:16 ` [PATCH v9 07/15] test: py: vboot: prepare integration test for ecdsa Philippe Reynes
@ 2026-09-03 8:16 ` Philippe Reynes
2026-09-03 15:43 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 09/15] tools: fit_image_setup_sig: set required_keynode to -1 Philippe Reynes
` (7 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
This commit adds test case for ecdsa on fit, but not (yet) for
the global image signature (preload).
Reviewed-by: Simon Glass <simon.glass@canonical.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v2:
- initial version
v3:
- no change
v4:
- no change
v5:
- no change
v6:
- no change
v7:
- no change
v8:
- no change
v9:
- some minor changes to fix rebase on next
test/py/tests/test_vboot.py | 29 ++++++++++++
.../vboot/sign-configs-sha256-ecdsa256.its | 44 +++++++++++++++++++
.../vboot/sign-configs-sha256-ecdsa384.its | 44 +++++++++++++++++++
.../vboot/sign-configs-sha256-ecdsa521.its | 44 +++++++++++++++++++
.../vboot/sign-images-sha256-ecdsa256.its | 42 ++++++++++++++++++
.../vboot/sign-images-sha256-ecdsa384.its | 42 ++++++++++++++++++
.../vboot/sign-images-sha256-ecdsa521.its | 42 ++++++++++++++++++
7 files changed, 287 insertions(+)
create mode 100644 test/py/tests/vboot/sign-configs-sha256-ecdsa256.its
create mode 100644 test/py/tests/vboot/sign-configs-sha256-ecdsa384.its
create mode 100644 test/py/tests/vboot/sign-configs-sha256-ecdsa521.its
create mode 100644 test/py/tests/vboot/sign-images-sha256-ecdsa256.its
create mode 100644 test/py/tests/vboot/sign-images-sha256-ecdsa384.its
create mode 100644 test/py/tests/vboot/sign-images-sha256-ecdsa521.its
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index 33cbcea5c24..89876ff030a 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -94,6 +94,9 @@ TESTDATA_IN = [
['sha256-pss-pad', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', False, False, False, False],
['sha256-pss-required', 'sha256', '-rsa2048', '-pss', None, True, False, False, False],
['sha256-pss-pad-required', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', True, True, False, False],
+ ['sha256-basic-ecdsa256', 'sha256', '-ecdsa256', '', None, False, False, False, False],
+ ['sha256-basic-ecdsa384', 'sha256', '-ecdsa384', '', None, False, False, False, False],
+ ['sha256-basic-ecdsa521', 'sha256', '-ecdsa521', '', None, False, False, False, False],
['sha384-basic', 'sha384', '-rsa3072', '', None, False, False, False, False],
['sha384-pad', 'sha384', '-rsa3072', '', '-E -p 0x10000', False, False, False, False],
['algo-arg', 'algo-arg', '', '', '-o sha256,rsa2048', False, False, True, False],
@@ -287,6 +290,29 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
utils.run_and_log(ubman, 'openssl req -batch -new -x509 -key %s%s.key '
'-out %s%s.crt' % (tmpdir, name, tmpdir, name))
+ def create_ecdsa_pair(name):
+ """Generate a new ECDSA key pair
+
+ Args:
+ name: Name of the key (e.g. 'dev')
+ """
+
+ if sig_algo == "-ecdsa256":
+ curve_name = "secp256r1"
+ elif sig_algo == "-ecdsa384":
+ curve_name = "secp384r1"
+ elif sig_algo == "-ecdsa521":
+ curve_name = "secp521r1"
+ else:
+ curve_name = "unknownCurve"
+
+ utils.run_and_log(ubman, 'openssl ecparam -name %s -genkey -noout -out %s%s.pem' %
+ (curve_name, tmpdir, name))
+
+ # Create a certificate containing the public key
+ utils.run_and_log(ubman, 'openssl req -batch -new -x509 -key %s%s.pem '
+ '-out %s%s.crt' % (tmpdir, name, tmpdir, name))
+
def test_with_algo(sha_algo, sig_algo, padding, sign_options):
"""Test verified boot with the given hash algorithm.
@@ -570,6 +596,9 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
if sig_algo == "-rsa2048" or sig_algo == "-rsa3072" or sig_algo == "":
create_rsa_pair('dev')
create_rsa_pair('prod')
+ elif sig_algo == "-ecdsa256" or sig_algo == "-ecdsa384" or sig_algo == "-ecdsa521":
+ create_ecdsa_pair('dev')
+ create_ecdsa_pair('prod')
# Create a number kernel image with zeroes
with open('%stest-kernel.bin' % tmpdir, 'wb') as fd:
diff --git a/test/py/tests/vboot/sign-configs-sha256-ecdsa256.its b/test/py/tests/vboot/sign-configs-sha256-ecdsa256.its
new file mode 100644
index 00000000000..6bd291a40c2
--- /dev/null
+++ b/test/py/tests/vboot/sign-configs-sha256-ecdsa256.its
@@ -0,0 +1,44 @@
+/dts-v1/;
+
+/ {
+ description = "Chrome OS kernel image with one or more FDT blobs";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ data = /incbin/("test-kernel.bin");
+ type = "kernel_noload";
+ arch = "sandbox";
+ os = "linux";
+ compression = "none";
+ load = <0x4>;
+ entry = <0x8>;
+ kernel-version = <1>;
+ hash-1 {
+ algo = "sha256";
+ };
+ };
+ fdt-1 {
+ description = "snow";
+ data = /incbin/("sandbox-kernel.dtb");
+ type = "flat_dt";
+ arch = "sandbox";
+ compression = "none";
+ fdt-version = <1>;
+ hash-1 {
+ algo = "sha256";
+ };
+ };
+ };
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ kernel = "kernel";
+ fdt = "fdt-1";
+ signature {
+ algo = "sha256,ecdsa256";
+ key-name-hint = "dev";
+ };
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sign-configs-sha256-ecdsa384.its b/test/py/tests/vboot/sign-configs-sha256-ecdsa384.its
new file mode 100644
index 00000000000..68c482acff2
--- /dev/null
+++ b/test/py/tests/vboot/sign-configs-sha256-ecdsa384.its
@@ -0,0 +1,44 @@
+/dts-v1/;
+
+/ {
+ description = "Chrome OS kernel image with one or more FDT blobs";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ data = /incbin/("test-kernel.bin");
+ type = "kernel_noload";
+ arch = "sandbox";
+ os = "linux";
+ compression = "none";
+ load = <0x4>;
+ entry = <0x8>;
+ kernel-version = <1>;
+ hash-1 {
+ algo = "sha256";
+ };
+ };
+ fdt-1 {
+ description = "snow";
+ data = /incbin/("sandbox-kernel.dtb");
+ type = "flat_dt";
+ arch = "sandbox";
+ compression = "none";
+ fdt-version = <1>;
+ hash-1 {
+ algo = "sha256";
+ };
+ };
+ };
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ kernel = "kernel";
+ fdt = "fdt-1";
+ signature {
+ algo = "sha256,ecdsa384";
+ key-name-hint = "dev";
+ };
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sign-configs-sha256-ecdsa521.its b/test/py/tests/vboot/sign-configs-sha256-ecdsa521.its
new file mode 100644
index 00000000000..f673accd39a
--- /dev/null
+++ b/test/py/tests/vboot/sign-configs-sha256-ecdsa521.its
@@ -0,0 +1,44 @@
+/dts-v1/;
+
+/ {
+ description = "Chrome OS kernel image with one or more FDT blobs";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ data = /incbin/("test-kernel.bin");
+ type = "kernel_noload";
+ arch = "sandbox";
+ os = "linux";
+ compression = "none";
+ load = <0x4>;
+ entry = <0x8>;
+ kernel-version = <1>;
+ hash-1 {
+ algo = "sha256";
+ };
+ };
+ fdt-1 {
+ description = "snow";
+ data = /incbin/("sandbox-kernel.dtb");
+ type = "flat_dt";
+ arch = "sandbox";
+ compression = "none";
+ fdt-version = <1>;
+ hash-1 {
+ algo = "sha256";
+ };
+ };
+ };
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ kernel = "kernel";
+ fdt = "fdt-1";
+ signature {
+ algo = "sha256,ecdsa521";
+ key-name-hint = "dev";
+ };
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sign-images-sha256-ecdsa256.its b/test/py/tests/vboot/sign-images-sha256-ecdsa256.its
new file mode 100644
index 00000000000..009003bb601
--- /dev/null
+++ b/test/py/tests/vboot/sign-images-sha256-ecdsa256.its
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+ description = "Chrome OS kernel image with one or more FDT blobs";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ data = /incbin/("test-kernel.bin");
+ type = "kernel_noload";
+ arch = "sandbox";
+ os = "linux";
+ compression = "none";
+ load = <0x4>;
+ entry = <0x8>;
+ kernel-version = <1>;
+ signature {
+ algo = "sha256,ecdsa256";
+ key-name-hint = "dev";
+ };
+ };
+ fdt-1 {
+ description = "snow";
+ data = /incbin/("sandbox-kernel.dtb");
+ type = "flat_dt";
+ arch = "sandbox";
+ compression = "none";
+ fdt-version = <1>;
+ signature {
+ algo = "sha256,ecdsa256";
+ key-name-hint = "dev";
+ };
+ };
+ };
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ kernel = "kernel";
+ fdt = "fdt-1";
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sign-images-sha256-ecdsa384.its b/test/py/tests/vboot/sign-images-sha256-ecdsa384.its
new file mode 100644
index 00000000000..567de687a06
--- /dev/null
+++ b/test/py/tests/vboot/sign-images-sha256-ecdsa384.its
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+ description = "Chrome OS kernel image with one or more FDT blobs";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ data = /incbin/("test-kernel.bin");
+ type = "kernel_noload";
+ arch = "sandbox";
+ os = "linux";
+ compression = "none";
+ load = <0x4>;
+ entry = <0x8>;
+ kernel-version = <1>;
+ signature {
+ algo = "sha256,ecdsa384";
+ key-name-hint = "dev";
+ };
+ };
+ fdt-1 {
+ description = "snow";
+ data = /incbin/("sandbox-kernel.dtb");
+ type = "flat_dt";
+ arch = "sandbox";
+ compression = "none";
+ fdt-version = <1>;
+ signature {
+ algo = "sha256,ecdsa384";
+ key-name-hint = "dev";
+ };
+ };
+ };
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ kernel = "kernel";
+ fdt = "fdt-1";
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sign-images-sha256-ecdsa521.its b/test/py/tests/vboot/sign-images-sha256-ecdsa521.its
new file mode 100644
index 00000000000..74ed45b21b8
--- /dev/null
+++ b/test/py/tests/vboot/sign-images-sha256-ecdsa521.its
@@ -0,0 +1,42 @@
+/dts-v1/;
+
+/ {
+ description = "Chrome OS kernel image with one or more FDT blobs";
+ #address-cells = <1>;
+
+ images {
+ kernel {
+ data = /incbin/("test-kernel.bin");
+ type = "kernel_noload";
+ arch = "sandbox";
+ os = "linux";
+ compression = "none";
+ load = <0x4>;
+ entry = <0x8>;
+ kernel-version = <1>;
+ signature {
+ algo = "sha256,ecdsa521";
+ key-name-hint = "dev";
+ };
+ };
+ fdt-1 {
+ description = "snow";
+ data = /incbin/("sandbox-kernel.dtb");
+ type = "flat_dt";
+ arch = "sandbox";
+ compression = "none";
+ fdt-version = <1>;
+ signature {
+ algo = "sha256,ecdsa521";
+ key-name-hint = "dev";
+ };
+ };
+ };
+ configurations {
+ default = "conf-1";
+ conf-1 {
+ kernel = "kernel";
+ fdt = "fdt-1";
+ };
+ };
+};
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 09/15] tools: fit_image_setup_sig: set required_keynode to -1
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (7 preceding siblings ...)
2026-09-03 8:16 ` [PATCH v9 08/15] test: vboot: add " Philippe Reynes
@ 2026-09-03 8:16 ` Philippe Reynes
2026-09-03 14:34 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 10/15] tools: mkimage: pre-load: add support of ecdsa Philippe Reynes
` (6 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:16 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
When initializing info about a signature, set required_keynode
to -1 instead of 0, as 0 is a valid keynode offset.
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v5:
- initial version
v6:
- no change
v7:
- change info->required_keynode > 0 to info->required_keynode >= 0
in ecdsa_verify_hash
v8:
- no change
v9:
- no change
lib/ecdsa/ecdsa-verify.c | 2 +-
tools/image-host.c | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c
index 494b60b4ab0..341486de2d3 100644
--- a/lib/ecdsa/ecdsa-verify.c
+++ b/lib/ecdsa/ecdsa-verify.c
@@ -117,7 +117,7 @@ static int ecdsa_verify_hash(struct udevice *dev,
if (!ops || !ops->verify)
return -ENODEV;
- if (info->required_keynode > 0) {
+ if (info->required_keynode >= 0) {
ret = fdt_get_key(&key, info->fdt_blob, info->required_keynode);
if (ret < 0)
return ret;
diff --git a/tools/image-host.c b/tools/image-host.c
index 46036673050..9a85a3dda2f 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -202,6 +202,7 @@ static int fit_image_setup_sig(struct image_sign_info *info,
info->checksum = image_get_checksum_algo(algo_name);
info->crypto = image_get_crypto_algo(algo_name);
info->padding = image_get_padding_algo(padding_name);
+ info->required_keynode = -1;
info->require_keys = require_keys;
info->engine_id = engine_id;
if (!info->checksum || !info->crypto) {
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 10/15] tools: mkimage: pre-load: add support of ecdsa
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (8 preceding siblings ...)
2026-09-03 8:16 ` [PATCH v9 09/15] tools: fit_image_setup_sig: set required_keynode to -1 Philippe Reynes
@ 2026-09-03 8:17 ` Philippe Reynes
2026-09-03 14:36 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 11/15] tools: binman: " Philippe Reynes
` (5 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:17 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
Right now, mkimage can only create pre-load header
using rsa. We add the support of ecdsa.
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v3:
- initial version
v4:
- use pre_load_noffset (do not compute it again)
- release memory allocated with strdup
- clean code
v5:
- check checksum and algo before using them
v6:
- no change
v7:
- no change
v8:
- no change
v9:
- no change
lib/ecdsa/ecdsa-libcrypto.c | 29 +++++++++---
tools/image-host.c | 92 ++++++++++++++++++++++++++++++++-----
2 files changed, 103 insertions(+), 18 deletions(-)
diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c
index b3fc75fac48..5e69782424c 100644
--- a/lib/ecdsa/ecdsa-libcrypto.c
+++ b/lib/ecdsa/ecdsa-libcrypto.c
@@ -517,14 +517,9 @@ int ecdsa_verify(struct image_sign_info *info,
return ret;
}
-static int do_add(struct signer *ctx, void *fdt, const char *key_node_name,
- struct image_sign_info *info)
+static int search_key_node(void *fdt, const char *key_node_name)
{
- int signature_node, key_node, ret, key_bits;
- const char *curve_name;
- const EC_GROUP *group;
- const EC_POINT *point;
- BIGNUM *x, *y;
+ int signature_node, key_node;
signature_node = fdt_subnode_offset(fdt, 0, FIT_SIG_NODENAME);
if (signature_node == -FDT_ERR_NOTFOUND) {
@@ -559,6 +554,26 @@ static int do_add(struct signer *ctx, void *fdt, const char *key_node_name,
return key_node;
}
+ return key_node;
+}
+
+static int do_add(struct signer *ctx, void *fdt, const char *key_node_name,
+ struct image_sign_info *info)
+{
+ int key_node, ret, key_bits;
+ const char *curve_name;
+ const EC_GROUP *group;
+ const EC_POINT *point;
+ BIGNUM *x, *y;
+
+ if (info->required_keynode >= 0) {
+ key_node = info->required_keynode;
+ } else {
+ key_node = search_key_node(fdt, key_node_name);
+ if (key_node < 0)
+ return key_node;
+ }
+
group = EC_KEY_get0_group(ctx->ecdsa_key);
key_bits = EC_GROUP_order_bits(group);
curve_name = OBJ_nid2sn(EC_GROUP_get_curve_name(group));
diff --git a/tools/image-host.c b/tools/image-host.c
index 9a85a3dda2f..ed1bfe68a31 100644
--- a/tools/image-host.c
+++ b/tools/image-host.c
@@ -14,6 +14,7 @@
#include <image.h>
#include <hexdump.h>
#include <version.h>
+#include <u-boot/ecdsa.h>
#include <sys/stat.h>
#include <sys/wait.h>
@@ -1681,13 +1682,74 @@ err_cert:
return ret;
}
+static int fit_pre_load_data_key_rsa(const char *keydir, void *keydest,
+ int pre_load_noffset, const void *key_name)
+{
+ unsigned char *pubkey = NULL;
+ int ret, pubkey_len;
+
+ /* Read public key */
+ ret = read_pub_key(keydir, key_name, &pubkey, &pubkey_len);
+ if (ret < 0)
+ goto out;
+
+ /* Add the public key to the device tree */
+ ret = fdt_setprop(keydest, pre_load_noffset, "public-key",
+ pubkey, pubkey_len);
+ if (ret)
+ fprintf(stderr, "Can't set public-key in node %s (ret = %d)\n",
+ IMAGE_PRE_LOAD_PATH, ret);
+ out:
+ return ret;
+}
+
+static int fit_pre_load_data_key_ecdsa(const char *keydir, void *keydest,
+ int pre_load_noffset, const void *key_name,
+ const void *algo_name)
+{
+ struct image_sign_info info;
+ int node, ret = 0;
+
+ memset(&info, 0, sizeof(info));
+ info.keydir = keydir;
+ info.keyname = strdup(key_name);
+ info.name = strdup(algo_name);
+ info.checksum = image_get_checksum_algo(algo_name);
+ if (!info.checksum) {
+ fprintf(stderr, "Can't find valid checksum from %s\n",
+ (char *)algo_name);
+ ret = -EINVAL;
+ goto out;
+ }
+ info.crypto = image_get_crypto_algo(algo_name);
+ if (!info.crypto) {
+ fprintf(stderr, "Can't find valid crypto from %s\n",
+ (char *)algo_name);
+ ret = -EINVAL;
+ goto out;
+ }
+ info.required_keynode = pre_load_noffset;
+
+ node = ecdsa_add_verify_data(&info, keydest);
+ if (node < 0) {
+ fprintf(stderr, "Can't add verify data: err = %d\n", node);
+ ret = -EIO;
+ }
+
+ out:
+ free((void *)info.keyname);
+ free((void *)info.name);
+
+ return ret;
+}
+
int fit_pre_load_data(const char *keydir, void *keydest, void *fit)
{
int pre_load_noffset;
const void *algo_name;
const void *key_name;
- unsigned char *pubkey = NULL;
- int ret, pubkey_len;
+ char *name;
+ int ret;
if (!keydir || !keydest || !fit)
return 0;
@@ -1714,17 +1776,25 @@ int fit_pre_load_data(const char *keydir, void *keydest, void *fit)
goto out;
}
- /* Read public key */
- ret = read_pub_key(keydir, key_name, &pubkey, &pubkey_len);
- if (ret < 0)
+ /* Is it a RSA or an ECDSA key */
+ name = strchr((const char *)algo_name, ',');
+ if (!name) {
+ fprintf(stderr, "The name of the algo is invalid: %s\n",
+ (char *)algo_name);
+ ret = -EINVAL;
goto out;
+ }
+ name += 1;
- /* Add the public key to the device tree */
- ret = fdt_setprop(keydest, pre_load_noffset, "public-key",
- pubkey, pubkey_len);
- if (ret)
- fprintf(stderr, "Can't set public-key in node %s (ret = %d)\n",
- IMAGE_PRE_LOAD_PATH, ret);
+ if (!strncmp(name, "rsa", 3)) {
+ ret = fit_pre_load_data_key_rsa(keydir, keydest, pre_load_noffset, key_name);
+ } else if (!strncmp(name, "ecdsa", 5)) {
+ ret = fit_pre_load_data_key_ecdsa(keydir, keydest, pre_load_noffset,
+ key_name, algo_name);
+ } else {
+ fprintf(stderr, "The algo %s is not supported\n", (char *)algo_name);
+ ret = -EINVAL;
+ }
out:
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 11/15] tools: binman: pre-load: add support of ecdsa
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (9 preceding siblings ...)
2026-09-03 8:17 ` [PATCH v9 10/15] tools: mkimage: pre-load: add support of ecdsa Philippe Reynes
@ 2026-09-03 8:17 ` Philippe Reynes
2026-09-03 14:37 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 12/15] boot: " Philippe Reynes
` (4 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:17 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
Right now, binman can only create pre-load header
using rsa. We add the support of ecdsa.
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v3:
- initial version
v4:
- merge patch 11 that was adding test for ecdsa pre-load
- add key size check
- use exc instead of simply e
- rename dts filaneme
- add a test to check key size
v5:
- compute ecdsa521 sig instead of using hardcoded value 132
- fix english: don't -> doesn't
- avoid line too long
v6:
- no change
v7:
- no change
v8:
- no change
v9:
- no change
tools/binman/etype/pre_load.py | 78 ++++++++++++++++---
tools/binman/ftest.py | 50 ++++++++++++
tools/binman/test/ecdsa521.pem | 7 ++
tools/binman/test/security/pre_load_ecdsa.dts | 22 ++++++
.../security/pre_load_ecdsa_invalid_algo.dts | 22 ++++++
.../security/pre_load_ecdsa_invalid_key.dts | 22 ++++++
.../security/pre_load_ecdsa_invalid_sha.dts | 22 ++++++
7 files changed, 214 insertions(+), 9 deletions(-)
create mode 100644 tools/binman/test/ecdsa521.pem
create mode 100644 tools/binman/test/security/pre_load_ecdsa.dts
create mode 100644 tools/binman/test/security/pre_load_ecdsa_invalid_algo.dts
create mode 100644 tools/binman/test/security/pre_load_ecdsa_invalid_key.dts
create mode 100644 tools/binman/test/security/pre_load_ecdsa_invalid_sha.dts
diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
index 0d953cb258e..7890c1c62a8 100644
--- a/tools/binman/etype/pre_load.py
+++ b/tools/binman/etype/pre_load.py
@@ -16,8 +16,10 @@ from binman.entry import EntryArg
from Cryptodome.Hash import SHA256, SHA384, SHA512
from Cryptodome.PublicKey import RSA
+from Cryptodome.PublicKey import ECC
from Cryptodome.Signature import pkcs1_15
from Cryptodome.Signature import pss
+from Cryptodome.Signature import DSS
PRE_LOAD_MAGIC = b'UBSH'
@@ -27,6 +29,12 @@ RSAS = {
'rsa4096': 4096 / 8
}
+ECDSAS = {
+ 'ecdsa256': 256 / 8 * 2,
+ 'ecdsa384': 384 / 8 * 2,
+ 'ecdsa521': (521 + 7) / 8 * 2
+}
+
SHAS = {
'sha256': SHA256,
'sha384': SHA384,
@@ -86,24 +94,17 @@ class Entry_pre_load(Entry_collection):
if self.key_path is None:
self.key_path = ''
- def _CreateHeader(self):
- """Create a pre load header"""
- hash_name, sign_name = self.algo_name.split(',')
- padding_name = self.padding_name
- key_name = os.path.join(self.key_path, self.key_name)
-
+ def _CreateHeaderRsa(self, hash_name, sign_name, padding_name, key_name):
# Check hash and signature name/type
if hash_name not in SHAS:
self.Raise(hash_name + " is not supported")
- if sign_name not in RSAS:
- self.Raise(sign_name + " is not supported")
# Read the key
key = RSA.import_key(tools.read_file(key_name))
# Check if the key has the expected size
if key.size_in_bytes() != RSAS[sign_name]:
- self.Raise("The key " + self.key_name + " don't have the expected size")
+ self.Raise("The key " + self.key_name + " doesn't have the expected size")
# Compute the hash
hash_image = SHAS[hash_name].new()
@@ -151,6 +152,65 @@ class Entry_pre_load(Entry_collection):
return data + pad
+ def _CreateHeaderEcdsa(self, hash_name, sign_name, key_name):
+ # Check hash and signature name/type
+ if hash_name not in SHAS:
+ self.Raise(hash_name + " is not supported")
+
+ # Read the key
+ key = ECC.import_key(tools.read_file(key_name))
+
+ # Check if the key has the expected size
+ if key.pointQ.size_in_bytes() * 2 != ECDSAS[sign_name]:
+ self.Raise("The key " + self.key_name + " doesn't have the expected size")
+
+ # Compute the hash
+ hash_image = SHAS[hash_name].new()
+ hash_image.update(self.image)
+
+ # Compute the signature
+ signer = DSS.new(key, 'fips-186-3')
+ sig = signer.sign(hash_image)
+
+ hash_sig = SHA256.new()
+ hash_sig.update(sig)
+
+ version = self.version
+ header_size = self.header_size
+ image_size = len(self.image)
+ ofs_img_sig = 64 + len(sig)
+ flags = 0
+ reserved0 = 0
+ reserved1 = 0
+
+ first_header = struct.pack('>4sIIIIIII32s', PRE_LOAD_MAGIC,
+ version, header_size, image_size,
+ ofs_img_sig, flags, reserved0,
+ reserved1, hash_sig.digest())
+
+ hash_first_header = SHAS[hash_name].new()
+ hash_first_header.update(first_header)
+ sig_first_header = signer.sign(hash_first_header)
+
+ data = first_header + sig_first_header + sig
+ pad = bytearray(self.header_size - len(data))
+
+ return data + pad
+
+ def _CreateHeader(self):
+ """Create a pre load header"""
+ hash_name, sign_name = self.algo_name.split(',')
+ padding_name = self.padding_name
+ key_name = os.path.join(self.key_path, self.key_name)
+
+ if sign_name in RSAS:
+ return self._CreateHeaderRsa(hash_name, sign_name, padding_name, key_name)
+
+ if sign_name in ECDSAS:
+ return self._CreateHeaderEcdsa(hash_name, sign_name, key_name)
+
+ self.Raise(sign_name + " is not supported")
+
def ObtainContents(self):
"""Create a placeholder for the header"""
self.SetContents(tools.get_bytes(0, self.header_size))
diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
index 5f0de4c74a7..a3209bb1595 100644
--- a/tools/binman/ftest.py
+++ b/tools/binman/ftest.py
@@ -5925,12 +5925,62 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
image_fname = tools.get_output_filename('image.bin')
is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key"))
+ self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
+ self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
+ self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
+ self.assertEqual(is_signed, True)
+ def testPreLoadEcdsa(self):
+ """Test an image with a pre-load header using ecdsa key"""
+ entry_args = {
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+ }
+ data = self._DoReadFileDtb(
+ 'security/pre_load_ecdsa.dts', entry_args=entry_args,
+ extra_indirs=[os.path.join(self._binman_dir, 'test')])[0]
+
+ image_fname = tools.get_output_filename('image.bin')
+ is_signed = self._CheckPreload(image_fname,
+ self.TestFile('ecdsa521.pem'),
+ 'sha256,ecdsa521')
self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
self.assertEqual(is_signed, True)
+ def testPreLoadEcdsaInvalidSha(self):
+ """Test an image with a pre-load ecdsa header with an invalid hash"""
+ entry_args = {
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+ }
+ with self.assertRaises(ValueError) as exc:
+ self._DoReadFileDtb('security/pre_load_ecdsa_invalid_sha.dts',
+ entry_args=entry_args)
+ self.assertIn("Node '/binman/pre-load': sha2560 is not supported",
+ str(exc.exception))
+
+ def testPreLoadEcdsaInvalidAlgo(self):
+ """Test an image with a pre-load header with an invalid algo"""
+ entry_args = {
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+ }
+ with self.assertRaises(ValueError) as exc:
+ data = self._DoReadFileDtb('security/pre_load_ecdsa_invalid_algo.dts',
+ entry_args=entry_args)
+ self.assertIn("Node '/binman/pre-load': ecdsa5210 is not supported",
+ str(exc.exception))
+
+ def testPreLoadEcdsaInvalidKey(self):
+ """Test an image with a pre-load header with an invalid key size"""
+ entry_args = {
+ 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
+ }
+ with self.assertRaises(ValueError) as exc:
+ data = self._DoReadFileDtb('security/pre_load_ecdsa_invalid_key.dts',
+ entry_args=entry_args)
+ self.assertIn("Node '/binman/pre-load': The key ecdsa521.pem doesn't have the expected size",
+ str(exc.exception))
+
def _CheckSafeUniqueNames(self, *images):
"""Check all entries of given images for unsafe unique names"""
for image in images:
diff --git a/tools/binman/test/ecdsa521.pem b/tools/binman/test/ecdsa521.pem
new file mode 100644
index 00000000000..ac1904d3955
--- /dev/null
+++ b/tools/binman/test/ecdsa521.pem
@@ -0,0 +1,7 @@
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIBM+CNnraGci2/mw1wPq44l2HccHnoBbdP3DiU6zqsBOq8IR8uegz2
+FLzWsjxcW7hwROCdEm6tW99wqsyPE25RZ3egBwYFK4EEACOhgYkDgYYABABu5bWV
+aQ4EgnXFjojX9df3gBEBipphEEFAoG87GuoWBdlimFC8UEEXiKNU37w0wlJn4bG0
+8uOKwDqBk3uF+DrmZwB45lCSKkjdRWsJeDt+iEuFe2O/mbXoL4p5D8MM2OsDV5GT
+srUbxhXq+T/i5lV7XXm2+tT/7zU8ZQce6WRufbd9KQ==
+-----END EC PRIVATE KEY-----
diff --git a/tools/binman/test/security/pre_load_ecdsa.dts b/tools/binman/test/security/pre_load_ecdsa.dts
new file mode 100644
index 00000000000..247b85aad4c
--- /dev/null
+++ b/tools/binman/test/security/pre_load_ecdsa.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ pre-load {
+ content = <&image>;
+ algo-name = "sha256,ecdsa521";
+ key-name = "ecdsa521.pem";
+ header-size = <4096>;
+ version = <0x11223344>;
+ };
+
+ image: blob-ext {
+ filename = "refcode.bin";
+ };
+ };
+};
diff --git a/tools/binman/test/security/pre_load_ecdsa_invalid_algo.dts b/tools/binman/test/security/pre_load_ecdsa_invalid_algo.dts
new file mode 100644
index 00000000000..be71edbbdcd
--- /dev/null
+++ b/tools/binman/test/security/pre_load_ecdsa_invalid_algo.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ pre-load {
+ content = <&image>;
+ algo-name = "sha256,ecdsa5210";
+ key-name = "ecdsa521.pem";
+ header-size = <4096>;
+ version = <0x11223344>;
+ };
+
+ image: blob-ext {
+ filename = "refcode.bin";
+ };
+ };
+};
diff --git a/tools/binman/test/security/pre_load_ecdsa_invalid_key.dts b/tools/binman/test/security/pre_load_ecdsa_invalid_key.dts
new file mode 100644
index 00000000000..15d71cf0324
--- /dev/null
+++ b/tools/binman/test/security/pre_load_ecdsa_invalid_key.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ pre-load {
+ content = <&image>;
+ algo-name = "sha256,ecdsa384";
+ key-name = "ecdsa521.pem";
+ header-size = <4096>;
+ version = <0x11223344>;
+ };
+
+ image: blob-ext {
+ filename = "refcode.bin";
+ };
+ };
+};
diff --git a/tools/binman/test/security/pre_load_ecdsa_invalid_sha.dts b/tools/binman/test/security/pre_load_ecdsa_invalid_sha.dts
new file mode 100644
index 00000000000..1017707375e
--- /dev/null
+++ b/tools/binman/test/security/pre_load_ecdsa_invalid_sha.dts
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ pre-load {
+ content = <&image>;
+ algo-name = "sha2560,ecdsa521";
+ key-name = "ecdsa521.pem";
+ header-size = <4096>;
+ version = <0x11223344>;
+ };
+
+ image: blob-ext {
+ filename = "refcode.bin";
+ };
+ };
+};
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 12/15] boot: pre-load: add support of ecdsa
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (10 preceding siblings ...)
2026-09-03 8:17 ` [PATCH v9 11/15] tools: binman: " Philippe Reynes
@ 2026-09-03 8:17 ` Philippe Reynes
2026-09-03 14:38 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 13/15] tools: preload_check_sign: " Philippe Reynes
` (3 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:17 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
Right now, u-boot can only boot image with a
pre-load header with rsa. We add the support
of ecdsa.
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v3:
- initial version
v4:
- avoid calling image_get_crypto_algo several times
v5:
- simplify the function is_ecdsa
- re-use already computed crypto in function image_pre_load_sig_setup
v6:
- no change
v7:
- no change
v8:
- no change
v9:
- no change
boot/image-pre-load.c | 53 +++++++++++++++++++++++++++++++++----------
1 file changed, 41 insertions(+), 12 deletions(-)
diff --git a/boot/image-pre-load.c b/boot/image-pre-load.c
index 2f851ebb28c..af72ea6d547 100644
--- a/boot/image-pre-load.c
+++ b/boot/image-pre-load.c
@@ -70,6 +70,12 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
return 0;
}
#else
+
+static int is_ecdsa(struct crypto_algo *crypto)
+{
+ return crypto && !strncmp(crypto->name, "ecdsa", 5);
+}
+
/*
* This function gathers information about the signature check
* that could be done before launching the image.
@@ -86,6 +92,7 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
int key_len;
int node, ret = 0;
char *sig_info_path = NULL;
+ struct crypto_algo *crypto;
if (!info) {
log_err("ERROR: info is NULL for image pre-load sig check\n");
@@ -114,11 +121,24 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
goto out;
}
- padding_name = fdt_getprop(gd_fdt_blob(), node,
- IMAGE_PRE_LOAD_PROP_PADDING_NAME, NULL);
- if (!padding_name) {
- log_info("INFO: no padding_name provided, so using pkcs-1.5\n");
- padding_name = "pkcs-1.5";
+ crypto = image_get_crypto_algo(algo_name);
+ if (!crypto) {
+ printf("ERROR: can't find a valid crypto algo from %s\n",
+ (char *)algo_name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (is_ecdsa(crypto)) {
+ padding_name = NULL;
+ } else {
+ padding_name = fdt_getprop(gd_fdt_blob(), node,
+ IMAGE_PRE_LOAD_PROP_PADDING_NAME,
+ NULL);
+ if (!padding_name) {
+ log_info("INFO: no padding_name provided, so using pkcs-1.5\n");
+ padding_name = "pkcs-1.5";
+ }
}
sig_size = fdt_getprop(gd_fdt_blob(), node,
@@ -129,12 +149,17 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
goto out;
}
- key = fdt_getprop(gd_fdt_blob(), node,
- IMAGE_PRE_LOAD_PROP_PUBLIC_KEY, &key_len);
- if (!key) {
- log_err("ERROR: no key for image pre-load sig check\n");
- ret = -EINVAL;
- goto out;
+ if (is_ecdsa(crypto)) {
+ key = NULL;
+ key_len = 0;
+ } else {
+ key = fdt_getprop(gd_fdt_blob(), node,
+ IMAGE_PRE_LOAD_PROP_PUBLIC_KEY, &key_len);
+ if (!key) {
+ log_err("ERROR: no key for image pre-load sig check\n");
+ ret = -EINVAL;
+ goto out;
+ }
}
info->algo_name = (char *)algo_name;
@@ -152,9 +177,13 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
info->sig_info.name = info->algo_name;
info->sig_info.padding = image_get_padding_algo(info->padding_name);
info->sig_info.checksum = image_get_checksum_algo(info->sig_info.name);
- info->sig_info.crypto = image_get_crypto_algo(info->sig_info.name);
+ info->sig_info.crypto = crypto;
info->sig_info.key = info->key;
info->sig_info.keylen = info->key_len;
+ if (is_ecdsa(crypto)) {
+ info->sig_info.required_keynode = node;
+ info->sig_info.fdt_blob = gd_fdt_blob();
+ }
out:
return ret;
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 13/15] tools: preload_check_sign: add support of ecdsa
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (11 preceding siblings ...)
2026-09-03 8:17 ` [PATCH v9 12/15] boot: " Philippe Reynes
@ 2026-09-03 8:17 ` Philippe Reynes
2026-09-03 14:39 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 14/15] test: py: vboot: prepare test for global signature with ecdsa Philippe Reynes
` (2 subsequent siblings)
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:17 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
right now, the tool preload_check_sign may only
checks an image with a pre-load header with rsa.
We add the support of pre-load header with ecdsa.
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v3:
- initial version
v4:
- free key to avoid mem leak
- fix error management (set ret before goto out)
v5:
- add include ec.h, evp.h, err.h and image.h
v6:
- no change
v7:
- no change
v8:
- no change
v9:
- no change
tools/preload_check_sign.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/tools/preload_check_sign.c b/tools/preload_check_sign.c
index ebead459273..d94f0509e74 100644
--- a/tools/preload_check_sign.c
+++ b/tools/preload_check_sign.c
@@ -8,9 +8,13 @@
* complete file. The tool preload_check_sign allows to verify and authenticate
* a file starting with a preload header.
*/
+
+#define OPENSSL_API_COMPAT 0x10101000L
+
#include <stdio.h>
#include <unistd.h>
#include <openssl/pem.h>
+#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <image.h>
@@ -144,6 +148,32 @@ int main(int argc, char **argv)
info.sig_info.key = info.key;
info.sig_info.keylen = info.key_len;
+ /* For ecdsa key, we have to update some values */
+ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
+ EC_KEY *ecdsa_key;
+ const EC_GROUP *group;
+
+ ecdsa_key = EVP_PKEY_get1_EC_KEY(pkey);
+ if (!ecdsa_key) {
+ fprintf(stderr, "Can not extract ECDSA key\n");
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+
+ group = EC_KEY_get0_group(ecdsa_key);
+ if (!group) {
+ fprintf(stderr, "Can not extract ECDSA group\n");
+ EC_KEY_free(ecdsa_key);
+ ret = EXIT_FAILURE;
+ goto out;
+ }
+
+ info.sig_info.keyfile = keyfile;
+ info.sig_size = (EC_GROUP_order_bits(group) + 7) / 8 * 2;
+
+ EC_KEY_free(ecdsa_key);
+ }
+
/* Check the signature */
image_pre_load_sig_set_info(&info);
ret = image_pre_load_sig((ulong)buffer);
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 14/15] test: py: vboot: prepare test for global signature with ecdsa
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (12 preceding siblings ...)
2026-09-03 8:17 ` [PATCH v9 13/15] tools: preload_check_sign: " Philippe Reynes
@ 2026-09-03 8:17 ` Philippe Reynes
2026-09-03 14:40 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 15/15] test: py: vboot: add " Philippe Reynes
2026-09-03 18:35 ` [PATCH v9 00/15] add software ecdsa support Tom Rini
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:17 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
The vboot tests only consider rsa for test with global signature.
To prepare the integration of test with ecdsa test, the signature
algo is now explicit.
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v3:
- initial version
v4:
- no change
v5:
- no change
v6:
- no change
v7:
- no change
v8:
- no change
v9:
- no change
test/py/tests/test_vboot.py | 12 ++++++------
...binman-pss.dts => sandbox-binman-rsa2048-pss.dts} | 0
...sandbox-binman.dts => sandbox-binman-rsa2048.dts} | 0
...pss.dts => sandbox-u-boot-global-rsa2048-pss.dts} | 0
...-global.dts => sandbox-u-boot-global-rsa2048.dts} | 0
5 files changed, 6 insertions(+), 6 deletions(-)
rename test/py/tests/vboot/{sandbox-binman-pss.dts => sandbox-binman-rsa2048-pss.dts} (100%)
rename test/py/tests/vboot/{sandbox-binman.dts => sandbox-binman-rsa2048.dts} (100%)
rename test/py/tests/vboot/{sandbox-u-boot-global-pss.dts => sandbox-u-boot-global-rsa2048-pss.dts} (100%)
rename test/py/tests/vboot/{sandbox-u-boot-global.dts => sandbox-u-boot-global-rsa2048.dts} (100%)
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index 89876ff030a..e3996486ab6 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -536,7 +536,7 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
dtb)
run_bootm(sha_algo, 'multi required key', '', False)
- def test_global_sign(sha_algo, padding, sign_options):
+ def test_global_sign(sha_algo, sig_algo, padding, sign_options):
"""Test global image signature with the given hash algorithm and padding.
Args:
@@ -545,14 +545,14 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
rsa signature algorithm.
"""
- dtb = '%ssandbox-u-boot-global%s.dtb' % (tmpdir, padding)
+ dtb = '%ssandbox-u-boot-global%s%s.dtb' % (tmpdir, sig_algo, padding)
ubman.config.dtb = dtb
# Compile our device tree files for kernel and U-Boot. These are
# regenerated here since mkimage will modify them (by adding a
# public key) below.
dtc('sandbox-kernel.dts', ubman, dtc_args, datadir, tmpdir, dtb)
- dtc_options('sandbox-u-boot-global%s.dts' % padding, '-p 1024')
+ dtc_options('sandbox-u-boot-global%s%s.dts' % (sig_algo, padding), '-p 1024')
# Build the FIT with dev key (keys NOT required). This adds the
# signature into sandbox-u-boot.dtb, NOT marked 'required'.
@@ -561,11 +561,11 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
# Build the dtb for binman that define the pre-load header
# with the global sigature.
- dtc('sandbox-binman%s.dts' % padding, ubman, dtc_args, datadir, tmpdir, dtb)
+ dtc('sandbox-binman%s%s.dts' % (sig_algo, padding), ubman, dtc_args, datadir, tmpdir, dtb)
# Run binman to create the final image with the not signed fit
# and the pre-load header that contains the global signature.
- run_binman('sandbox-binman%s.dtb' % padding)
+ run_binman('sandbox-binman%s%s.dtb' % (sig_algo, padding))
# Check that the signature is correctly verified by u-boot
run_bootm(sha_algo, 'global image signature',
@@ -615,7 +615,7 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
try:
ubman.config.dtb = dtb
if global_sign:
- test_global_sign(sha_algo, padding, sign_options)
+ test_global_sign(sha_algo, sig_algo, padding, sign_options)
elif required:
test_required_key(sha_algo, sig_algo, padding, sign_options)
else:
diff --git a/test/py/tests/vboot/sandbox-binman-pss.dts b/test/py/tests/vboot/sandbox-binman-rsa2048-pss.dts
similarity index 100%
rename from test/py/tests/vboot/sandbox-binman-pss.dts
rename to test/py/tests/vboot/sandbox-binman-rsa2048-pss.dts
diff --git a/test/py/tests/vboot/sandbox-binman.dts b/test/py/tests/vboot/sandbox-binman-rsa2048.dts
similarity index 100%
rename from test/py/tests/vboot/sandbox-binman.dts
rename to test/py/tests/vboot/sandbox-binman-rsa2048.dts
diff --git a/test/py/tests/vboot/sandbox-u-boot-global-pss.dts b/test/py/tests/vboot/sandbox-u-boot-global-rsa2048-pss.dts
similarity index 100%
rename from test/py/tests/vboot/sandbox-u-boot-global-pss.dts
rename to test/py/tests/vboot/sandbox-u-boot-global-rsa2048-pss.dts
diff --git a/test/py/tests/vboot/sandbox-u-boot-global.dts b/test/py/tests/vboot/sandbox-u-boot-global-rsa2048.dts
similarity index 100%
rename from test/py/tests/vboot/sandbox-u-boot-global.dts
rename to test/py/tests/vboot/sandbox-u-boot-global-rsa2048.dts
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v9 15/15] test: py: vboot: add test for global signature with ecdsa
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (13 preceding siblings ...)
2026-09-03 8:17 ` [PATCH v9 14/15] test: py: vboot: prepare test for global signature with ecdsa Philippe Reynes
@ 2026-09-03 8:17 ` Philippe Reynes
2026-09-03 14:41 ` Raymond Mao
2026-09-03 18:35 ` [PATCH v9 00/15] add software ecdsa support Tom Rini
15 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-03 8:17 UTC (permalink / raw)
To: marko.makela, jonny.green, raymondmaoca, trini, simon.glass
Cc: u-boot, Philippe Reynes, Simon Glass
As now u-boot supports pre-load header with ecdsa, we
add some tests to vboot with ecdsa pre-load header.
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
---
v3:
- initial version
v4:
- no change
v5:
- no change
v6:
- no change
v7:
- no change
v8:
- no change
v9:
- no change
test/py/tests/test_vboot.py | 3 +++
.../tests/vboot/sandbox-binman-ecdsa256.dts | 24 +++++++++++++++++
.../tests/vboot/sandbox-binman-ecdsa384.dts | 24 +++++++++++++++++
.../tests/vboot/sandbox-binman-ecdsa521.dts | 24 +++++++++++++++++
.../vboot/sandbox-u-boot-global-ecdsa256.dts | 27 +++++++++++++++++++
.../vboot/sandbox-u-boot-global-ecdsa384.dts | 27 +++++++++++++++++++
.../vboot/sandbox-u-boot-global-ecdsa521.dts | 27 +++++++++++++++++++
7 files changed, 156 insertions(+)
create mode 100644 test/py/tests/vboot/sandbox-binman-ecdsa256.dts
create mode 100644 test/py/tests/vboot/sandbox-binman-ecdsa384.dts
create mode 100644 test/py/tests/vboot/sandbox-binman-ecdsa521.dts
create mode 100644 test/py/tests/vboot/sandbox-u-boot-global-ecdsa256.dts
create mode 100644 test/py/tests/vboot/sandbox-u-boot-global-ecdsa384.dts
create mode 100644 test/py/tests/vboot/sandbox-u-boot-global-ecdsa521.dts
diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
index e3996486ab6..ed7e6bb33d2 100644
--- a/test/py/tests/test_vboot.py
+++ b/test/py/tests/test_vboot.py
@@ -102,6 +102,9 @@ TESTDATA_IN = [
['algo-arg', 'algo-arg', '', '', '-o sha256,rsa2048', False, False, True, False],
['sha256-global-sign', 'sha256', '-rsa2048', '', '', False, False, False, True],
['sha256-global-sign-pss', 'sha256', '-rsa2048', '-pss', '', False, False, False, True],
+ ['sha256-global-sign-ecdsa256', 'sha256', '-ecdsa256', '', '', False, False, False, True],
+ ['sha256-global-sign-ecdsa384', 'sha256', '-ecdsa384', '', '', False, False, False, True],
+ ['sha256-global-sign-ecdsa521', 'sha256', '-ecdsa521', '', '', False, False, False, True],
]
# Mark all but the first test as slow, so they are not run with '-k not slow'
diff --git a/test/py/tests/vboot/sandbox-binman-ecdsa256.dts b/test/py/tests/vboot/sandbox-binman-ecdsa256.dts
new file mode 100644
index 00000000000..0e84b81078b
--- /dev/null
+++ b/test/py/tests/vboot/sandbox-binman-ecdsa256.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ filename = "sandbox.img";
+
+ pre-load {
+ content = <&image>;
+ algo-name = "sha256,ecdsa256";
+ key-name = "dev.pem";
+ header-size = <4096>;
+ version = <1>;
+ };
+
+ image: blob-ext {
+ filename = "test.fit";
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sandbox-binman-ecdsa384.dts b/test/py/tests/vboot/sandbox-binman-ecdsa384.dts
new file mode 100644
index 00000000000..56faf67fe57
--- /dev/null
+++ b/test/py/tests/vboot/sandbox-binman-ecdsa384.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ filename = "sandbox.img";
+
+ pre-load {
+ content = <&image>;
+ algo-name = "sha256,ecdsa384";
+ key-name = "dev.pem";
+ header-size = <4096>;
+ version = <1>;
+ };
+
+ image: blob-ext {
+ filename = "test.fit";
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sandbox-binman-ecdsa521.dts b/test/py/tests/vboot/sandbox-binman-ecdsa521.dts
new file mode 100644
index 00000000000..8e2fc3de31d
--- /dev/null
+++ b/test/py/tests/vboot/sandbox-binman-ecdsa521.dts
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ filename = "sandbox.img";
+
+ pre-load {
+ content = <&image>;
+ algo-name = "sha256,ecdsa521";
+ key-name = "dev.pem";
+ header-size = <4096>;
+ version = <1>;
+ };
+
+ image: blob-ext {
+ filename = "test.fit";
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sandbox-u-boot-global-ecdsa256.dts b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa256.dts
new file mode 100644
index 00000000000..f15ada3987c
--- /dev/null
+++ b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa256.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ model = "Sandbox Verified Boot Test";
+ compatible = "sandbox";
+
+ binman {
+ };
+
+ reset@0 {
+ compatible = "sandbox,reset";
+ };
+
+ image {
+ pre-load {
+ sig {
+ algo-name = "sha256,ecdsa256";
+ signature-size = <64>;
+ mandatory = "yes";
+
+ key-name = "dev";
+ };
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sandbox-u-boot-global-ecdsa384.dts b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa384.dts
new file mode 100644
index 00000000000..24540ace249
--- /dev/null
+++ b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa384.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ model = "Sandbox Verified Boot Test";
+ compatible = "sandbox";
+
+ binman {
+ };
+
+ reset@0 {
+ compatible = "sandbox,reset";
+ };
+
+ image {
+ pre-load {
+ sig {
+ algo-name = "sha256,ecdsa384";
+ signature-size = <96>;
+ mandatory = "yes";
+
+ key-name = "dev";
+ };
+ };
+ };
+};
diff --git a/test/py/tests/vboot/sandbox-u-boot-global-ecdsa521.dts b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa521.dts
new file mode 100644
index 00000000000..72fa3b2c790
--- /dev/null
+++ b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa521.dts
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+/ {
+ model = "Sandbox Verified Boot Test";
+ compatible = "sandbox";
+
+ binman {
+ };
+
+ reset@0 {
+ compatible = "sandbox,reset";
+ };
+
+ image {
+ pre-load {
+ sig {
+ algo-name = "sha256,ecdsa521";
+ signature-size = <132>;
+ mandatory = "yes";
+
+ key-name = "dev";
+ };
+ };
+ };
+};
--
2.43.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH v9 01/15] ecdsa: fix support of secp521r1
2026-09-03 8:16 ` [PATCH v9 01/15] ecdsa: fix support of secp521r1 Philippe Reynes
@ 2026-09-03 14:30 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:30 UTC (permalink / raw)
To: Philippe Reynes; +Cc: marko.makela, jonny.green, trini, simon.glass, u-boot
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> Current implementation of ecdsa only supports key len aligned on
> 8 bits. But the curve secp521r1 uses a key of 521 bits which is not
> aligned on 8 bits. In this commit, we update the keys management
> for ecdsa to support keys that are not aligned on 8 bits.
>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v2:
> - intitial version
> v3:
> - fix typo in comments
> v4:
> - fix commit message
> - clean code with DIV_ROUND_UP-
> - duplicate data before shifting
> - support ecdsa521 and secp521r1
> - clean code
> v5:
> - check that x and y are not null before using them
> - free keys when keys not found
> -v6:
> - free x and y if x and y are not null
> - do not free key when an error has occured
> v7:
> - no change
> v8:
> - check the exact size read in the dtb instead of doing a simple
> test on the expected size
> - change memdup api to use the same as in the header include/linux/string.h
> - code cleanup
> v9:
> - no change
>
> lib/ecdsa/ecdsa-libcrypto.c | 75 ++++++++++++++++++++++++++++++++++++-
> lib/ecdsa/ecdsa-verify.c | 71 +++++++++++++++++++++++++++++++++--
> lib/fdt-libcrypto.c | 2 +-
> tools/image-sig-host.c | 7 ++++
> 4 files changed, 148 insertions(+), 7 deletions(-)
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c
> index c4bfb2cec61..b3fc75fac48 100644
> --- a/lib/ecdsa/ecdsa-libcrypto.c
> +++ b/lib/ecdsa/ecdsa-libcrypto.c
> @@ -26,6 +26,8 @@
> #include <openssl/ec.h>
> #include <openssl/bn.h>
>
> +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
> +
> /* Image signing context for openssl-libcrypto */
> struct signer {
> EVP_PKEY *evp_key; /* Pointer to EVP_PKEY object */
> @@ -41,10 +43,36 @@ struct ecdsa_public_key {
> int size_bits;
> };
>
> +/*
> + * This function returns a valid pointer so
> + * the caller must then free this pointer.
> + */
> +static char *memdup(const void *src, size_t len)
> +{
> + char *p;
> +
> + p = malloc(len);
> + if (!p)
> + return NULL;
> +
> + memcpy(p, src, len);
> +
> + return p;
> +}
> +
> +/*
> + * This function fills keys with valid pointers (x and y) so
> + * the caller must then free those pointers with fdt_free_key().
> + */
> static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
> {
> + const char *x;
> + const char *y;
> int x_len;
> int y_len;
> + int expected_len;
> +
> + memset(key, 0, sizeof(*key));
>
> key->curve_name = fdt_getprop(fdt, node, "ecdsa,curve", NULL);
> if (!key->curve_name)
> @@ -54,6 +82,8 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
> key->size_bits = 256;
> else if (!strcmp(key->curve_name, "secp384r1"))
> key->size_bits = 384;
> + else if (!strcmp(key->curve_name, "secp521r1"))
> + key->size_bits = 521;
> else
> return -EINVAL;
>
> @@ -63,12 +93,45 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
> if (!key->x || !key->y)
> return -EINVAL;
>
> - if (x_len != key->size_bits / 8 || y_len != key->size_bits / 8)
> + /*
> + * The public key is stored as an array of u32, so if the key size is
> + * not a multiple of 32 (for example 521), we may have extra bytes.
> + * To avoid any issue later, we shift the x and y pointer to the first
> + * useful byte.
> + */
> + expected_len = DIV_ROUND_UP(key->size_bits, 8);
> +
> + if (x_len < expected_len || y_len < expected_len)
> return -EINVAL;
>
> + x = memdup(key->x + (x_len - expected_len), expected_len);
> + if (!x) {
> + fprintf(stderr, "Cannot allocate memory for point X");
> + return -ENOMEM;
> + }
> + key->x = (const uint8_t *)x;
> +
> + y = memdup(key->y + (y_len - expected_len), expected_len);
> + if (!y) {
> + fprintf(stderr, "Cannot allocate memory for point Y");
> + free((char *)x);
> + return -ENOMEM;
> + }
> + key->y = (const uint8_t *)y;
> +
> return 0;
> }
>
> +static void fdt_free_key(struct ecdsa_public_key *key)
> +{
> + if (!key)
> + return;
> + if (key->x)
> + free((char *)key->x);
> + if (key->y)
> + free((char *)key->y);
> +}
> +
> static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
> {
> struct ecdsa_public_key pubkey;
> @@ -89,8 +152,11 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
> nid = NID_X9_62_prime256v1;
> } else if (!strcmp(pubkey.curve_name, "secp384r1")) {
> nid = NID_secp384r1;
> + } else if (!strcmp(pubkey.curve_name, "secp521r1")) {
> + nid = NID_secp521r1;
> } else {
> fprintf(stderr, "Unsupported curve name: '%s'\n", pubkey.curve_name);
> + fdt_free_key(&pubkey);
> return -EINVAL;
> }
>
> @@ -100,6 +166,7 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
> ec_key = EC_KEY_new_by_curve_name(nid);
> if (!ec_key) {
> fprintf(stderr, "Failed to allocate EC_KEY for curve %s\n", pubkey.curve_name);
> + fdt_free_key(&pubkey);
> return -ENOMEM;
> }
>
> @@ -108,10 +175,11 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
> if (!point) {
> fprintf(stderr, "Failed to allocate EC_POINT\n");
> EC_KEY_free(ec_key);
> + fdt_free_key(&pubkey);
> return -ENOMEM;
> }
>
> - len = pubkey.size_bits / 8;
> + len = DIV_ROUND_UP(pubkey.size_bits, 8);
>
> uint8_t buf[1 + len * 2];
>
> @@ -123,6 +191,7 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
> fprintf(stderr, "Failed to convert (x,y) point to EC_POINT\n");
> EC_POINT_free(point);
> EC_KEY_free(ec_key);
> + fdt_free_key(&pubkey);
> return -EINVAL;
> }
>
> @@ -130,11 +199,13 @@ static int read_key_from_fdt(struct signer *ctx, const void *fdt, int node)
> fprintf(stderr, "Failed to set EC_POINT as public key\n");
> EC_POINT_free(point);
> EC_KEY_free(ec_key);
> + fdt_free_key(&pubkey);
> return -EINVAL;
> }
>
> fprintf(stderr, "Successfully loaded ECDSA key from FDT node %d\n", node);
> EC_POINT_free(point);
> + fdt_free_key(&pubkey);
> ctx->ecdsa_key = ec_key;
>
> return 0;
> diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c
> index 629b662cf6c..494b60b4ab0 100644
> --- a/lib/ecdsa/ecdsa-verify.c
> +++ b/lib/ecdsa/ecdsa-verify.c
> @@ -10,6 +10,7 @@
>
> #include <crypto/ecdsa-uclass.h>
> #include <dm/uclass.h>
> +#include <malloc.h>
> #include <u-boot/ecdsa.h>
>
> /*
> @@ -24,13 +25,23 @@ static int ecdsa_key_size(const char *curve_name)
> return 256;
> else if (!strcmp(curve_name, "secp384r1"))
> return 384;
> + else if (!strcmp(curve_name, "secp521r1"))
> + return 521;
>
> return 0;
> }
>
> +/*
> + * This function fills keys with valid pointers (x and y) so
> + * the caller must then free those pointers with fdt_free_key().
> + */
> static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
> {
> - int x_len, y_len;
> + int expected_read, expected_len, x_len, y_len;
> + const char *x;
> + const char *y;
> +
> + memset(key, 0, sizeof(*key));
>
> key->curve_name = fdt_getprop(fdt, node, "ecdsa,curve", NULL);
> if (!key->curve_name) {
> @@ -50,15 +61,50 @@ static int fdt_get_key(struct ecdsa_public_key *key, const void *fdt, int node)
> if (!key->x || !key->y)
> return -EINVAL;
>
> - if (x_len != (key->size_bits / 8) || y_len != (key->size_bits / 8)) {
> + expected_read = DIV_ROUND_UP(key->size_bits, 32) * 4;
> + if (x_len != expected_read || y_len != expected_read) {
> printf("%s: node=%d, curve@%p x@%p+%i y@%p+%i\n", __func__,
> node, key->curve_name, key->x, x_len, key->y, y_len);
> return -EINVAL;
> }
>
> + /*
> + * The public key is stored as an array of u32, so if the key size is
> + * not a multiple of 32 (for example 521), we may have extra bytes.
> + * To avoid any issue later, we shift the x and y pointer to the first
> + * useful byte.
> + */
> + expected_len = DIV_ROUND_UP(key->size_bits, 8);
> +
> + x = memdup(key->x + (x_len - expected_len), expected_len);
> + if (!x) {
> + debug("Cannot allocate memory for point X\n");
> + return -ENOMEM;
> + }
> + key->x = (const uint8_t *)x;
> +
> + y = memdup(key->y + (y_len - expected_len), expected_len);
> + if (!y) {
> + debug("Cannot allocate memory for point Y\n");
> + free((char *)x);
> + key->x = NULL;
> + return -ENOMEM;
> + }
> + key->y = (const uint8_t *)y;
> +
> return 0;
> }
>
> +static void fdt_free_key(struct ecdsa_public_key *key)
> +{
> + if (!key)
> + return;
> + if (key->x)
> + free((char *)key->x);
> + if (key->y)
> + free((char *)key->y);
> +}
> +
> static int ecdsa_verify_hash(struct udevice *dev,
> const struct image_sign_info *info,
> const void *hash, const void *sig, uint sig_len)
> @@ -76,8 +122,11 @@ static int ecdsa_verify_hash(struct udevice *dev,
> if (ret < 0)
> return ret;
>
> - return ops->verify(dev, &key, hash, algo->checksum_len,
> - sig, sig_len);
> + ret = ops->verify(dev, &key, hash, algo->checksum_len,
> + sig, sig_len);
> + fdt_free_key(&key);
> +
> + return ret;
> }
>
> sig_node = fdt_subnode_offset(info->fdt_blob, 0, FIT_SIG_NODENAME);
> @@ -93,6 +142,8 @@ static int ecdsa_verify_hash(struct udevice *dev,
> ret = ops->verify(dev, &key, hash, algo->checksum_len,
> sig, sig_len);
>
> + fdt_free_key(&key);
> +
> /* On success, don't worry about remaining keys */
> if (!ret)
> return 0;
> @@ -135,6 +186,18 @@ U_BOOT_CRYPTO_ALGO(ecdsa384) = {
> .verify = ecdsa_verify,
> };
>
> +U_BOOT_CRYPTO_ALGO(ecdsa521) = {
> + .name = "ecdsa521",
> + .key_len = ECDSA521_BYTES,
> + .verify = ecdsa_verify,
> +};
> +
> +U_BOOT_CRYPTO_ALGO(secp521r1) = {
> + .name = "secp521r1",
> + .key_len = ECDSA521_BYTES,
> + .verify = ecdsa_verify,
> +};
> +
> /*
> * uclass definition for ECDSA API
> *
> diff --git a/lib/fdt-libcrypto.c b/lib/fdt-libcrypto.c
> index ecb0344c8f6..090246b44e9 100644
> --- a/lib/fdt-libcrypto.c
> +++ b/lib/fdt-libcrypto.c
> @@ -10,7 +10,7 @@
> int fdt_add_bignum(void *blob, int noffset, const char *prop_name,
> BIGNUM *num, int num_bits)
> {
> - int nwords = num_bits / 32;
> + int nwords = (num_bits + 31) / 32;
> int size;
> uint32_t *buf, *ptr;
> BIGNUM *tmp, *big2, *big32, *big2_32;
> diff --git a/tools/image-sig-host.c b/tools/image-sig-host.c
> index 5285263c616..285547994ca 100644
> --- a/tools/image-sig-host.c
> +++ b/tools/image-sig-host.c
> @@ -83,6 +83,13 @@ struct crypto_algo crypto_algos[] = {
> .add_verify_data = ecdsa_add_verify_data,
> .verify = ecdsa_verify,
> },
> + {
> + .name = "ecdsa521",
> + .key_len = ECDSA521_BYTES,
> + .sign = ecdsa_sign,
> + .add_verify_data = ecdsa_add_verify_data,
> + .verify = ecdsa_verify,
> + },
> {
> .name = "secp521r1",
> .key_len = ECDSA521_BYTES,
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 02/15] mbedtls: enable support of ecc
2026-09-03 8:16 ` [PATCH v9 02/15] mbedtls: enable support of ecc Philippe Reynes
@ 2026-09-03 14:31 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:31 UTC (permalink / raw)
To: Philippe Reynes; +Cc: marko.makela, jonny.green, trini, simon.glass, u-boot
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> Prepares the support of ecdsa signature check
> using MbedTLS. It introduces the option ECDSA_MBEDTLS
> to enable (or not) the support of ecdsa in MbedTLS.
>
> So now, ecdsa is no longer supported by default in the lib TLS.
> To get it, the option ECDSA_MBEDTLS must be enabled.
>
> The option ECDSA_MBEDTLS only enables the ecdsa support
> in MbedTLS, it doesn't provide any API to use it for
> signature check. It will be done in another commit
> by adding the option ECDSA_VERIFY_MBEDTLS.
>
> Two internal options are also added BIGNUM_MBEDTLS
> and ECC_MBEDTLS. Those options are used to share code
> between different option and avoid duplication.
>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v2:
> - move ecdsa to MBEDTLS_LIB_X509
> - enhance depencendies
> v3:
> - do not use _MBEDTLS in mbedtls_def_config.h
> v4:
> - do not select ECDSA on some configs
> - remove duplicated MBEDTLS_ECP_DP_SECP256K1_ENABLED
> - change dependencies for ECDSA configs
> v5:
> - MBEDTLS_LIB_TLS depends en ECDSA_MBEDTLS
> - update some configs according to previous change
> - build of ecdsa is conditionned by ECDSA_MBEDTLS
> v6:
> - fix dependencies for ecdsa and ecc on mbedtls
> - ecdsa is no longer mandatory for tls
> v7:
> - no change
> v8:
> - enhance the commit message
> - use /* */ instead of //
> v9:
> - no change
>
> configs/sandbox_defconfig | 1 +
> lib/ecdsa/Kconfig | 1 +
> lib/mbedtls/Kconfig | 17 +++++++++++++
> lib/mbedtls/Makefile | 17 +++++++------
> lib/mbedtls/mbedtls_def_config.h | 41 +++++++++++++++++++++-----------
> 5 files changed, 56 insertions(+), 21 deletions(-)
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
> index 5c97418783f..b9991d269d9 100644
> --- a/configs/sandbox_defconfig
> +++ b/configs/sandbox_defconfig
> @@ -389,6 +389,7 @@ CONFIG_PMBUS=y
> CONFIG_CMD_DHRYSTONE=y
> CONFIG_MBEDTLS_LIB=y
> CONFIG_HKDF_MBEDTLS=y
> +CONFIG_ECDSA_MBEDTLS=y
> CONFIG_ECDSA=y
> CONFIG_ECDSA_VERIFY=y
> CONFIG_RSASSA_PSS=y
> diff --git a/lib/ecdsa/Kconfig b/lib/ecdsa/Kconfig
> index ca13b6bfa1f..dac8bcf23dd 100644
> --- a/lib/ecdsa/Kconfig
> +++ b/lib/ecdsa/Kconfig
> @@ -1,6 +1,7 @@
> config ECDSA
> bool "Enable ECDSA support"
> depends on DM
> + select ASN1_DECODER
> help
> This enables the ECDSA (elliptic curve signature) algorithm for FIT
> image verification in U-Boot. The ECDSA algorithm is implemented
> diff --git a/lib/mbedtls/Kconfig b/lib/mbedtls/Kconfig
> index 789721ee6cd..e019f17d6bd 100644
> --- a/lib/mbedtls/Kconfig
> +++ b/lib/mbedtls/Kconfig
> @@ -247,6 +247,12 @@ config MBEDTLS_LIB_X509
>
> if MBEDTLS_LIB_X509
>
> +config BIGNUM_MBEDTLS
> + bool
> +
> +config ECC_MBEDTLS
> + bool
> +
> config ASN1_DECODER_MBEDTLS
> bool "ASN1 decoder with MbedTLS certificate library"
> depends on MBEDTLS_LIB_X509 && ASN1_DECODER
> @@ -264,6 +270,7 @@ config RSA_PUBLIC_KEY_PARSER_MBEDTLS
> bool "RSA public key parser with MbedTLS certificate library"
> depends on ASYMMETRIC_PUBLIC_KEY_MBEDTLS
> select ASN1_DECODER_MBEDTLS
> + select BIGNUM_MBEDTLS
> help
> This option chooses MbedTLS certificate library for RSA public key
> parser.
> @@ -292,6 +299,15 @@ config MSCODE_PARSER_MBEDTLS
> This option chooses MbedTLS certificate library for MS authenticode
> parser.
>
> +config ECDSA_MBEDTLS
> + bool "Enable ECDSA support with MbedTLS certificate library"
> + depends on MBEDTLS_LIB_X509 && ASN1_DECODER_MBEDTLS
> + select BIGNUM_MBEDTLS
> + select ECC_MBEDTLS
> + help
> + This option enables support of ECDSA with the MbedTLS certificate
> + library.
> +
> endif # MBEDTLS_LIB_X509
>
> config MBEDTLS_LIB_TLS
> @@ -301,6 +317,7 @@ config MBEDTLS_LIB_TLS
> depends on ASYMMETRIC_PUBLIC_KEY_MBEDTLS
> depends on ASN1_DECODER_MBEDTLS
> depends on MBEDTLS_LIB
> + select ECC_MBEDTLS
> help
> Enable MbedTLS TLS library. Required for HTTPs support
> in wget
> diff --git a/lib/mbedtls/Makefile b/lib/mbedtls/Makefile
> index c5b445bd85c..0c86c90d15a 100644
> --- a/lib/mbedtls/Makefile
> +++ b/lib/mbedtls/Makefile
> @@ -39,13 +39,21 @@ mbedtls_lib_crypto-$(CONFIG_$(PHASE_)HKDF_MBEDTLS) += \
> # MbedTLS X509 library
> obj-$(CONFIG_$(XPL_)MBEDTLS_LIB_X509) += mbedtls_lib_x509.o
> mbedtls_lib_x509-y := $(MBEDTLS_LIB_DIR)/x509.o
> +mbedtls_lib_x509-$(CONFIG_$(PHASE_)ECC_MBEDTLS) += \
> + $(MBEDTLS_LIB_DIR)/ecp.o \
> + $(MBEDTLS_LIB_DIR)/ecp_curves.o \
> + $(MBEDTLS_LIB_DIR)/ecp_curves_new.o \
> + $(MBEDTLS_LIB_DIR)/pk_ecc.o
> +mbedtls_lib_x509-$(CONFIG_$(PHASE_)ECDSA_MBEDTLS) += \
> + $(MBEDTLS_LIB_DIR)/ecdsa.o
> +mbedtls_lib_x509-$(CONFIG_$(PHASE_)BIGNUM_MBEDTLS) += \
> + $(MBEDTLS_LIB_DIR)/bignum.o \
> + $(MBEDTLS_LIB_DIR)/bignum_core.o
> mbedtls_lib_x509-$(CONFIG_$(PHASE_)ASN1_DECODER_MBEDTLS) += \
> $(MBEDTLS_LIB_DIR)/asn1parse.o \
> $(MBEDTLS_LIB_DIR)/asn1write.o \
> $(MBEDTLS_LIB_DIR)/oid.o
> mbedtls_lib_x509-$(CONFIG_$(PHASE_)RSA_PUBLIC_KEY_PARSER_MBEDTLS) += \
> - $(MBEDTLS_LIB_DIR)/bignum.o \
> - $(MBEDTLS_LIB_DIR)/bignum_core.o \
> $(MBEDTLS_LIB_DIR)/rsa.o \
> $(MBEDTLS_LIB_DIR)/rsa_alt_helpers.o
> mbedtls_lib_x509-$(CONFIG_$(PHASE_)ASYMMETRIC_PUBLIC_KEY_MBEDTLS) += \
> @@ -64,7 +72,6 @@ mbedtls_lib_tls-y := \
> $(MBEDTLS_LIB_DIR)/mps_reader.o \
> $(MBEDTLS_LIB_DIR)/mps_trace.o \
> $(MBEDTLS_LIB_DIR)/net_sockets.o \
> - $(MBEDTLS_LIB_DIR)/pk_ecc.o \
> $(MBEDTLS_LIB_DIR)/ssl_cache.o \
> $(MBEDTLS_LIB_DIR)/ssl_ciphersuites.o \
> $(MBEDTLS_LIB_DIR)/ssl_client.o \
> @@ -82,8 +89,4 @@ mbedtls_lib_tls-y := \
> $(MBEDTLS_LIB_DIR)/cipher.o \
> $(MBEDTLS_LIB_DIR)/cipher_wrap.o \
> $(MBEDTLS_LIB_DIR)/ecdh.o \
> - $(MBEDTLS_LIB_DIR)/ecdsa.o \
> - $(MBEDTLS_LIB_DIR)/ecp.o \
> - $(MBEDTLS_LIB_DIR)/ecp_curves.o \
> - $(MBEDTLS_LIB_DIR)/ecp_curves_new.o \
> $(MBEDTLS_LIB_DIR)/gcm.o \
> diff --git a/lib/mbedtls/mbedtls_def_config.h b/lib/mbedtls/mbedtls_def_config.h
> index dda3f4dd6e4..d55f31acfda 100644
> --- a/lib/mbedtls/mbedtls_def_config.h
> +++ b/lib/mbedtls/mbedtls_def_config.h
> @@ -62,6 +62,25 @@
>
> #if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509)
>
> +#if CONFIG_IS_ENABLED(BIGNUM_MBEDTLS)
> +#define MBEDTLS_BIGNUM_C
> +#endif
> +
> +#if CONFIG_IS_ENABLED(ECC_MBEDTLS)
> +#define MBEDTLS_ECP_C
> +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
> +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
> +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
> +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
> +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
> +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
> +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
> +#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
> +#define MBEDTLS_ECP_DP_BP256R1_ENABLED
> +#define MBEDTLS_ECP_DP_BP384R1_ENABLED
> +#define MBEDTLS_ECP_DP_BP512R1_ENABLED
> +#endif
> +
> #if CONFIG_IS_ENABLED(X509_CERTIFICATE_PARSER)
> #define MBEDTLS_X509_USE_C
> #define MBEDTLS_X509_CRT_PARSE_C
> @@ -74,7 +93,6 @@
> #endif
>
> #if CONFIG_IS_ENABLED(RSA_PUBLIC_KEY_PARSER)
> -#define MBEDTLS_BIGNUM_C
> #define MBEDTLS_RSA_C
> #define MBEDTLS_PKCS1_V15
> #endif
> @@ -89,6 +107,10 @@
> #define MBEDTLS_ASN1_WRITE_C
> #endif
>
> +#if CONFIG_IS_ENABLED(ECDSA_MBEDTLS)
> +#define MBEDTLS_ECDSA_C
> +#endif
> +
> #endif /* #if CONFIG_IS_ENABLED(MBEDTLS_LIB_X509) */
>
> #if CONFIG_IS_ENABLED(MBEDTLS_LIB_TLS)
> @@ -122,7 +144,9 @@
>
> /* ECDSA */
> #if CONFIG_IS_ENABLED(ASN1_DECODER)
> +#if CONFIG_IS_ENABLED(ECDSA_MBEDTLS)
> #define MBEDTLS_ECDSA_C
> +#endif /* #if CONFIG_IS_ENABLED(ECDSA_MBEDTLS) */
> #define MBEDTLS_ECP_C
> #define MBEDTLS_ECDH_C
> #endif
> @@ -130,24 +154,13 @@
> #define MBEDTLS_HMAC_DRBG_C
>
> #define MBEDTLS_CAN_ECDH
> +#if CONFIG_IS_ENABLED(ECDSA_MBEDTLS)
> #define MBEDTLS_PK_CAN_ECDSA_SIGN
> #if CONFIG_IS_ENABLED(X509_CERTIFICATE_PARSER)
> #define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
> #define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
> #endif
> -
> -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
> -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
> -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
> -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
> -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
> -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
> -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
> -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
> -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
> -#define MBEDTLS_ECP_DP_BP256R1_ENABLED
> -#define MBEDTLS_ECP_DP_BP384R1_ENABLED
> -#define MBEDTLS_ECP_DP_BP512R1_ENABLED
> +#endif /* #if CONFIG_IS_ENABLED(ECDSA_MBEDTLS) */
>
> #endif /* #if CONFIG_IS_ENABLED(MBEDTLS_LIB_TLS) */
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 03/15] ecdsa: initial support of ecdsa using mbedtls
2026-09-03 8:16 ` [PATCH v9 03/15] ecdsa: initial support of ecdsa using mbedtls Philippe Reynes
@ 2026-09-03 14:31 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:31 UTC (permalink / raw)
To: Philippe Reynes; +Cc: marko.makela, jonny.green, trini, simon.glass, u-boot
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> Adds an initial support of ecdsa verify using mbedtls.
>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v2:
> - rename sw_ecdsa.c to ecdsa.c
> v3:
> - rename sw_ecdsa_verify to ecdsa_hash_verify
> - stop on first group found
> - check signature len
> - use debug instead of printf
> - check function returns
> - fix memleaks in ecdsa_hash_verify
> v4:
> - move struct ecdsa_public_key from ecdsa-u-class.h to internal/ecdsa.h
> - use DIV_ROUND_UP
> - some code cleanup
> v5:
> - add kerneldoc header for ecdsa_hash_verify
> - read error when setting Q.Z
> v6:
> - add ECDSA_VERIFY_MBEDTLS
> - fix kerneldoc: doc not add a space before :
> v7:
> - no change
> v8:
> - add some useful comments
> - avoid using label such as out1, out2, out3 ...
> - code cleanup
> v9:
> - no change
>
> configs/sandbox_defconfig | 1 +
> include/crypto/ecdsa-uclass.h | 15 +---
> include/crypto/internal/ecdsa.h | 39 ++++++++
> lib/mbedtls/Kconfig | 7 ++
> lib/mbedtls/Makefile | 3 +
> lib/mbedtls/ecdsa.c | 152 ++++++++++++++++++++++++++++++++
> 6 files changed, 203 insertions(+), 14 deletions(-)
> create mode 100644 include/crypto/internal/ecdsa.h
> create mode 100644 lib/mbedtls/ecdsa.c
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
> index b9991d269d9..63682ef0e74 100644
> --- a/configs/sandbox_defconfig
> +++ b/configs/sandbox_defconfig
> @@ -390,6 +390,7 @@ CONFIG_CMD_DHRYSTONE=y
> CONFIG_MBEDTLS_LIB=y
> CONFIG_HKDF_MBEDTLS=y
> CONFIG_ECDSA_MBEDTLS=y
> +CONFIG_ECDSA_VERIFY_MBEDTLS=y
> CONFIG_ECDSA=y
> CONFIG_ECDSA_VERIFY=y
> CONFIG_RSASSA_PSS=y
> diff --git a/include/crypto/ecdsa-uclass.h b/include/crypto/ecdsa-uclass.h
> index 189843820a0..047a5eda2fc 100644
> --- a/include/crypto/ecdsa-uclass.h
> +++ b/include/crypto/ecdsa-uclass.h
> @@ -4,20 +4,7 @@
> */
>
> #include <dm/device.h>
> -
> -/**
> - * struct ecdsa_public_key - ECDSA public key properties
> - *
> - * The struct has pointers to the (x, y) curve coordinates to an ECDSA public
> - * key, as well as the name of the ECDSA curve. The size of the key is inferred
> - * from the 'curve_name'
> - */
> -struct ecdsa_public_key {
> - const char *curve_name; /* Name of curve, e.g. "prime256v1" */
> - const void *x; /* x coordinate of public key */
> - const void *y; /* y coordinate of public key */
> - unsigned int size_bits; /* key size in bits, derived from curve name */
> -};
> +#include <crypto/internal/ecdsa.h>
>
> struct ecdsa_ops {
> /**
> diff --git a/include/crypto/internal/ecdsa.h b/include/crypto/internal/ecdsa.h
> new file mode 100644
> index 00000000000..244a07d1f1f
> --- /dev/null
> +++ b/include/crypto/internal/ecdsa.h
> @@ -0,0 +1,39 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (c) 2026, Philippe Reynes <philippe.reynes@softathome.com>
> + */
> +#ifndef _ECDSA_HELPER_
> +#define _ECDSA_HELPER_
> +
> +#include <linux/types.h>
> +
> +/**
> + * struct ecdsa_public_key - ECDSA public key properties
> + *
> + * The struct has pointers to the (x, y) curve coordinates to an ECDSA public
> + * key, as well as the name of the ECDSA curve. The size of the key is inferred
> + * from the 'curve_name'
> + */
> +struct ecdsa_public_key {
> + const char *curve_name; /* Name of curve, e.g. "prime256v1" */
> + const void *x; /* x coordinate of public key */
> + const void *y; /* y coordinate of public key */
> + unsigned int size_bits; /* key size in bits, derived from curve name */
> +};
> +
> +/**
> + * ecdsa_hash_verify() - Verify the ecdsa signature of a hash
> + *
> + * @pubkey: ecdsa public key
> + * @hash: Hash
> + * @hash_len: Size of the hash
> + * @signature: Signature
> + * @sig_len: Size of the signature
> + *
> + * Return: 0 if all verified ok, <0 on error
> + */
> +int ecdsa_hash_verify(const struct ecdsa_public_key *pubkey,
> + const void *hash, size_t hash_len,
> + const void *signature, size_t sig_len);
> +
> +#endif
> diff --git a/lib/mbedtls/Kconfig b/lib/mbedtls/Kconfig
> index e019f17d6bd..66bc16db451 100644
> --- a/lib/mbedtls/Kconfig
> +++ b/lib/mbedtls/Kconfig
> @@ -308,6 +308,13 @@ config ECDSA_MBEDTLS
> This option enables support of ECDSA with the MbedTLS certificate
> library.
>
> +config ECDSA_VERIFY_MBEDTLS
> + bool "Enable ECDSA verify"
> + depends on ECDSA_MBEDTLS && ECDSA_VERIFY
> + help
> + This option enables support of ECDSA signature check with
> + MbedTLS certificate library.
> +
> endif # MBEDTLS_LIB_X509
>
> config MBEDTLS_LIB_TLS
> diff --git a/lib/mbedtls/Makefile b/lib/mbedtls/Makefile
> index 0c86c90d15a..b96db812afc 100644
> --- a/lib/mbedtls/Makefile
> +++ b/lib/mbedtls/Makefile
> @@ -11,6 +11,9 @@ obj-$(CONFIG_$(PHASE_)SHA1_MBEDTLS) += sha1.o
> obj-$(CONFIG_$(PHASE_)SHA256_MBEDTLS) += sha256.o
> obj-$(CONFIG_$(PHASE_)SHA512_MBEDTLS) += sha512.o
>
> +# shim layer for ecdsa verify
> +obj-$(CONFIG_$(PHASE_)ECDSA_VERIFY_MBEDTLS) += ecdsa.o
> +
> # x509 libraries
> obj-$(CONFIG_$(PHASE_)ASYMMETRIC_PUBLIC_KEY_MBEDTLS) += \
> public_key.o
> diff --git a/lib/mbedtls/ecdsa.c b/lib/mbedtls/ecdsa.c
> new file mode 100644
> index 00000000000..ca4e572e638
> --- /dev/null
> +++ b/lib/mbedtls/ecdsa.c
> @@ -0,0 +1,152 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
> + */
> +
> +#include <log.h>
> +#include <linux/errno.h>
> +#include <linux/string.h>
> +#include <linux/types.h>
> +
> +#include <crypto/internal/ecdsa.h>
> +
> +#include "mbedtls_options.h" /* required to access private fields */
> +#include <mbedtls/ecdsa.h>
> +#include <mbedtls/ecp.h>
> +
> +static mbedtls_ecp_group_id ecdsa_search_group_id(const char *curve_name)
> +{
> + mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
> + const mbedtls_ecp_curve_info *info;
> +
> + if (!curve_name)
> + return MBEDTLS_ECP_DP_NONE;
> +
> + /*
> + * This curve name is read in the FIT metadata.
> + * When this FIT metadata are filled by mkimage (or binman),
> + * the curve name is the alias/name provided by OpenSSL.
> + * And for secp256r1, OpenSSL uses the alias prime256v1.
> + * So here, we have to manage this OpenSSL alias.
> + */
> + if (!strcmp(curve_name, "prime256v1"))
> + return MBEDTLS_ECP_DP_SECP256R1;
> +
> + info = mbedtls_ecp_curve_list();
> + while (info && info->name) {
> + if (!strcmp(curve_name, info->name)) {
> + grp_id = info->grp_id;
> + break;
> + }
> + info++;
> + }
> +
> + return grp_id;
> +}
> +
> +int ecdsa_hash_verify(const struct ecdsa_public_key *pubkey,
> + const void *hash, size_t hash_len,
> + const void *signature, size_t sig_len)
> +{
> + mbedtls_ecp_group_id grp_id;
> + mbedtls_ecp_group grp;
> + mbedtls_ecp_point Q;
> + mbedtls_mpi r, s;
> + int key_len;
> + int err;
> +
> + key_len = DIV_ROUND_UP(pubkey->size_bits, 8);
> +
> + /* check the signature len */
> + if (sig_len != 2 * key_len) {
> + log_debug("sig len should be twice the key len (sig len = %zu, key len = %d)\n",
> + sig_len, key_len);
> + err = -EINVAL;
> + goto out;
> + }
> +
> + /* search the group */
> + grp_id = ecdsa_search_group_id(pubkey->curve_name);
> + if (grp_id == MBEDTLS_ECP_DP_NONE) {
> + log_debug("curve name %s not found\n", pubkey->curve_name);
> + err = -EINVAL;
> + goto out;
> + }
> +
> + /* init and load the group */
> + mbedtls_ecp_group_init(&grp);
> + err = mbedtls_ecp_group_load(&grp, grp_id);
> + if (err) {
> + err = -EINVAL;
> + goto free_grp;
> + }
> +
> + /* prepare the pubkey */
> + mbedtls_ecp_point_init(&Q);
> + err = mbedtls_mpi_read_binary(&Q.X, pubkey->x, key_len);
> + if (err) {
> + log_debug("could not read value x of the public key (err = %d)\n",
> + err);
> + err = -EINVAL;
> + goto free_q;
> + }
> + err = mbedtls_mpi_read_binary(&Q.Y, pubkey->y, key_len);
> + if (err) {
> + log_debug("could not read value y of the public key (err = %d)\n",
> + err);
> + err = -EINVAL;
> + goto free_q;
> + }
> + err = mbedtls_mpi_lset(&Q.Z, 1);
> + if (err) {
> + log_debug("could not set value z of the public key (err = %d)\n",
> + err);
> + err = -EINVAL;
> + goto free_q;
> + }
> +
> + /* check if the pubkey is valid */
> + err = mbedtls_ecp_check_pubkey(&grp, &Q);
> + if (err) {
> + log_debug("public key is invalid (err = %d)\n", err);
> + err = -EKEYREJECTED;
> + goto free_q;
> + }
> +
> + /* compute r */
> + mbedtls_mpi_init(&r);
> + err = mbedtls_mpi_read_binary(&r, signature, key_len);
> + if (err) {
> + log_debug("could not read value r of the signature (err = %d)\n",
> + err);
> + err = -EINVAL;
> + goto free_r;
> + }
> +
> + /* compute s */
> + mbedtls_mpi_init(&s);
> + err = mbedtls_mpi_read_binary(&s, signature + key_len, key_len);
> + if (err) {
> + log_debug("could not read value s of the signature (err = %d)\n",
> + err);
> + err = -EINVAL;
> + goto free_s;
> + }
> +
> + /* check the signature */
> + err = mbedtls_ecdsa_verify(&grp, hash, hash_len, &Q, &r, &s);
> + if (err)
> + err = -EINVAL;
> +
> + free_s:
> + mbedtls_mpi_free(&s);
> + free_r:
> + mbedtls_mpi_free(&r);
> + free_q:
> + mbedtls_ecp_point_free(&Q);
> + free_grp:
> + mbedtls_ecp_group_free(&grp);
> + out:
> +
> + return err;
> +}
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 04/15] test: lib: ecdsa: add initial test
2026-09-03 8:16 ` [PATCH v9 04/15] test: lib: ecdsa: add initial test Philippe Reynes
@ 2026-09-03 14:32 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:32 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> Adds tests to check that the function ecdsa_hash_verify
> using mbedtls is valid.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v2:
> - little change to only use test with sha enabled
> v3:
> - remove useless field *k in struct ecdsa_test_vector_s
> - change expected value on error (don't use mbedtls error)
> - manage function returns
> - update third parameter of sha*_csum_wd
> v4:
> - define SHA256_DEF_CHUNK_SZ, SHA384_DEF_CHUNK_SZ and SHA512_DEF_CHUNK_SZ
> - report skipped tests
> - add const on some variables
> - code cleanup
> v5:
> - do not define SHA256_DEF_CHUNK_SZ, SHA384_DEF_CHUNK_SZ and SHA512_DEF_CHUNK_SZ
> - use CHUNKSZ_SHA256, CHUNKSZ_SHA384 and CHUNKSZ_SHA521
> - do not use 528 to compule ecdsa 521 sig size but compute it
> - use ut_reportf instead of ut_failf
> v6:
> - no change
> v7:
> - no change
> v8:
> - no change
> v9:
> - no change
>
> test/lib/Makefile | 1 +
> test/lib/ecdsa.c | 456 ++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 457 insertions(+)
> create mode 100644 test/lib/ecdsa.c
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/test/lib/Makefile b/test/lib/Makefile
> index f25383a40e5..e9c779a7b47 100644
> --- a/test/lib/Makefile
> +++ b/test/lib/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_$(PHASE_)UT_COMPRESSION) += compression.o
> ifeq ($(CONFIG_XPL_BUILD),)
> obj-y += abuf.o
> obj-y += alist.o
> +obj-$(CONFIG_ECDSA_VERIFY_MBEDTLS) += ecdsa.o
> obj-$(CONFIG_EFI_LOADER) += efi_device_path.o efi_memory.o
> obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
> ifdef CONFIG_RISCV
> diff --git a/test/lib/ecdsa.c b/test/lib/ecdsa.c
> new file mode 100644
> index 00000000000..bc7737837e5
> --- /dev/null
> +++ b/test/lib/ecdsa.c
> @@ -0,0 +1,456 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
> + */
> +
> +#include <command.h>
> +#include <image.h>
> +#include <test/lib.h>
> +#include <test/test.h>
> +#include <test/ut.h>
> +#include <crypto/ecdsa-uclass.h>
> +#include <crypto/internal/ecdsa.h>
> +
> +#define ECDSA_POINT_SIZE (DIV_ROUND_UP(521, 8) * 2)
> +#define ECDSA_SIGNATURE_SIZE (ECDSA_POINT_SIZE * 2)
> +
> +struct ecdsa_test_vector_s {
> + const char *test_name;
> + const char *curve_name;
> + const char *x;
> + const char *y;
> + int size_bits;
> + const char *hash_type;
> + const char *hash_message;
> + const char *r;
> + const char *s;
> + int expected;
> +};
> +
> +/*
> + * Those data come from RFC6979
> + */
> +
> +static const struct ecdsa_test_vector_s ecdsa_test_vector[] = {
> + /*
> + * secp192r1
> + */
> + {
> + .test_name = "secp192r1 sha1",
> + .curve_name = "secp192r1",
> + .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
> + .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
> + .size_bits = 192,
> + .hash_type = "sha-1",
> + .hash_message = "sample",
> + .r = "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF",
> + .s = "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp192r1 sha256",
> + .curve_name = "secp192r1",
> + .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
> + .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
> + .size_bits = 192,
> + .hash_type = "sha-256",
> + .hash_message = "sample",
> + .r = "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55",
> + .s = "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp192r1 sha384",
> + .curve_name = "secp192r1",
> + .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
> + .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
> + .size_bits = 192,
> + .hash_type = "sha-384",
> + .hash_message = "sample",
> + .r = "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5",
> + .s = "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp192r1 sha512",
> + .curve_name = "secp192r1",
> + .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
> + .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
> + .size_bits = 192,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8",
> + .s = "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp192r1 sha512 error",
> + .curve_name = "secp192r1",
> + .x = "AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56",
> + .y = "3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43",
> + .size_bits = 192,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8",
> + .s = "0F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67",
> + .expected = -EINVAL,
> + },
> + /*
> + * secp224r1
> + */
> + {
> + .test_name = "secp224r1 sha1",
> + .curve_name = "secp224r1",
> + .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
> + .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
> + .size_bits = 224,
> + .hash_type = "sha-1",
> + .hash_message = "sample",
> + .r = "22226F9D40A96E19C4A301CE5B74B115303C0F3A4FD30FC257FB57AC",
> + .s = "66D1CDD83E3AF75605DD6E2FEFF196D30AA7ED7A2EDF7AF475403D69",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp224r1 sha256",
> + .curve_name = "secp224r1",
> + .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
> + .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
> + .size_bits = 224,
> + .hash_type = "sha-256",
> + .hash_message = "sample",
> + .r = "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA",
> + .s = "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp224r1 sha384",
> + .curve_name = "secp224r1",
> + .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
> + .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
> + .size_bits = 224,
> + .hash_type = "sha-384",
> + .hash_message = "sample",
> + .r = "0B115E5E36F0F9EC81F1325A5952878D745E19D7BB3EABFABA77E953",
> + .s = "830F34CCDFE826CCFDC81EB4129772E20E122348A2BBD889A1B1AF1D",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp224r1 sha512",
> + .curve_name = "secp224r1",
> + .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
> + .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
> + .size_bits = 224,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397",
> + .s = "A4CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp224r1 sha512 error",
> + .curve_name = "secp224r1",
> + .x = "00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
> + .y = "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
> + .size_bits = 224,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397",
> + .s = "04CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084",
> + .expected = -EINVAL,
> + },
> + /*
> + * secp256r1
> + */
> + {
> + .test_name = "secp256r1 sha1",
> + .curve_name = "secp256r1",
> + .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
> + .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
> + .size_bits = 256,
> + .hash_type = "sha-1",
> + .hash_message = "sample",
> + .r = "61340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D32",
> + .s = "6D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp256r1 sha256",
> + .curve_name = "secp256r1",
> + .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
> + .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
> + .size_bits = 256,
> + .hash_type = "sha-256",
> + .hash_message = "sample",
> + .r = "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716",
> + .s = "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp256r1 sha384",
> + .curve_name = "secp256r1",
> + .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
> + .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
> + .size_bits = 256,
> + .hash_type = "sha-384",
> + .hash_message = "sample",
> + .r = "0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719",
> + .s = "4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp256r1 sha512",
> + .curve_name = "secp256r1",
> + .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
> + .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
> + .size_bits = 256,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00",
> + .s = "2362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp256r1 sha512 error",
> + .curve_name = "secp256r1",
> + .x = "60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
> + .y = "7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
> + .size_bits = 256,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00",
> + .s = "0362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE",
> + .expected = -EINVAL,
> + },
> + /*
> + * secp384r1
> + */
> + {
> + .test_name = "secp384r1 sha1",
> + .curve_name = "secp384r1",
> + .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
> + .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
> + .size_bits = 384,
> + .hash_type = "sha-1",
> + .hash_message = "sample",
> + .r = "EC748D839243D6FBEF4FC5C4859A7DFFD7F3ABDDF72014540C16D73309834FA37B9BA002899F6FDA3A4A9386790D4EB2",
> + .s = "A3BCFA947BEEF4732BF247AC17F71676CB31A847B9FF0CBC9C9ED4C1A5B3FACF26F49CA031D4857570CCB5CA4424A443",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp384r1 sha256",
> + .curve_name = "secp384r1",
> + .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
> + .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
> + .size_bits = 384,
> + .hash_type = "sha-256",
> + .hash_message = "sample",
> + .r = "21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33BDE1E888E63355D92FA2B3C36D8FB2CD",
> + .s = "F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEBEFDC63ECCD1AC42EC0CB8668A4FA0AB0",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp384r1 sha384",
> + .curve_name = "secp384r1",
> + .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
> + .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
> + .size_bits = 384,
> + .hash_type = "sha-384",
> + .hash_message = "sample",
> + .r = "94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C81A648152E44ACF96E36DD1E80FABE46",
> + .s = "99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94FA329C145786E679E7B82C71A38628AC8",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp384r1 sha512",
> + .curve_name = "secp384r1",
> + .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
> + .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
> + .size_bits = 384,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799CFE30F35CC900056D7C99CD7882433709",
> + .s = "512C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112DC7CC3EF3446DEFCEB01A45C2667FDD5",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp384r1 sha512 error",
> + .curve_name = "secp384r1",
> + .x = "EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
> + .y = "8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
> + .size_bits = 384,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799CFE30F35CC900056D7C99CD7882433709",
> + .s = "012C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112DC7CC3EF3446DEFCEB01A45C2667FDD5",
> + .expected = -EINVAL,
> + },
> + /*
> + * secp521r1
> + */
> + {
> + .test_name = "secp521r1 sha1",
> + .curve_name = "secp521r1",
> + .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
> + .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
> + .size_bits = 521,
> + .hash_type = "sha-1",
> + .hash_message = "sample",
> + .r = "00343B6EC45728975EA5CBA6659BBB6062A5FF89EEA58BE3C80B619F322C87910FE092F7D45BB0F8EEE01ED3F20BABEC079D202AE677B243AB40B5431D497C55D75D",
> + .s = "00E7B0E675A9B24413D448B8CC119D2BF7B2D2DF032741C096634D6D65D0DBE3D5694625FB9E8104D3B842C1B0E2D0B98BEA19341E8676AEF66AE4EBA3D5475D5D16",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp521r1 sha256",
> + .curve_name = "secp521r1",
> + .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
> + .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
> + .size_bits = 521,
> + .hash_type = "sha-256",
> + .hash_message = "sample",
> + .r = "01511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E1A7",
> + .s = "004A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7ECFC",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp521r1 sha384",
> + .curve_name = "secp521r1",
> + .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
> + .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
> + .size_bits = 521,
> + .hash_type = "sha-384",
> + .hash_message = "sample",
> + .r = "01EA842A0E17D2DE4F92C15315C63DDF72685C18195C2BB95E572B9C5136CA4B4B576AD712A52BE9730627D16054BA40CC0B8D3FF035B12AE75168397F5D50C67451",
> + .s = "01F21A3CEE066E1961025FB048BD5FE2B7924D0CD797BABE0A83B66F1E35EEAF5FDE143FA85DC394A7DEE766523393784484BDF3E00114A1C857CDE1AA203DB65D61",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp521r1 sha512",
> + .curve_name = "secp521r1",
> + .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
> + .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
> + .size_bits = 521,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "00C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F174E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E377FA",
> + .s = "00617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF282623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A67A",
> + .expected = 0,
> + },
> + {
> + .test_name = "secp521r1 sha512 error",
> + .curve_name = "secp521r1",
> + .x = "01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
> + .y = "00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
> + .size_bits = 521,
> + .hash_type = "sha-512",
> + .hash_message = "sample",
> + .r = "00C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F174E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E377FA",
> + .s = "00017CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF282623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A67A",
> + .expected = -EINVAL,
> + },
> +};
> +
> +static int ecdsa_test(struct unit_test_state *uts,
> + const struct ecdsa_test_vector_s *tv)
> +{
> + struct ecdsa_public_key pubkey;
> + unsigned char x[ECDSA_POINT_SIZE];
> + unsigned char y[ECDSA_POINT_SIZE];
> + unsigned char hash[512 / 8];
> + size_t hash_len;
> + unsigned char signature[ECDSA_SIGNATURE_SIZE];
> + size_t sig_len;
> + int ret;
> +
> + sig_len = DIV_ROUND_UP(tv->size_bits, 8);
> +
> + pubkey.curve_name = tv->curve_name;
> + ret = hex2bin(x, tv->x, strlen(tv->x) / 2);
> + ut_asserteq(0, ret);
> + pubkey.x = x;
> + ret = hex2bin(y, tv->y, strlen(tv->y) / 2);
> + ut_asserteq(0, ret);
> + pubkey.y = y;
> + pubkey.size_bits = tv->size_bits;
> +
> + if (!strcmp(tv->hash_type, "sha-1")) {
> +#if CONFIG_IS_ENABLED(SHA1)
> + hash_len = SHA1_SUM_LEN;
> + sha1_csum_wd(tv->hash_message, strlen(tv->hash_message),
> + hash, SHA1_DEF_CHUNK_SZ);
> +#else
> + /* sha1 is not supported so we skip this test */
> + ut_reportf("Test %s skipped (sha1 not supported)",
> + tv->test_name);
> + goto out;
> +#endif
> + } else if (!strcmp(tv->hash_type, "sha-256")) {
> +#if CONFIG_IS_ENABLED(SHA256)
> + hash_len = SHA256_SUM_LEN;
> + sha256_csum_wd(tv->hash_message, strlen(tv->hash_message),
> + hash, CHUNKSZ_SHA256);
> +#else
> + /* sha256 is not supported so we skip this test */
> + ut_reportf("Test %s skipped (sha256 not supported)",
> + tv->test_name);
> + goto out;
> +#endif
> + } else if (!strcmp(tv->hash_type, "sha-384")) {
> +#if CONFIG_IS_ENABLED(SHA384)
> + hash_len = SHA384_SUM_LEN;
> + sha384_csum_wd(tv->hash_message, strlen(tv->hash_message),
> + hash, CHUNKSZ_SHA384);
> +#else
> + /* sha384 is not supported so we skip this test */
> + ut_reportf("Test %s skipped (sha384 not supported)",
> + tv->test_name);
> + goto out;
> +#endif
> + } else if (!strcmp(tv->hash_type, "sha-512")) {
> +#if CONFIG_IS_ENABLED(SHA512)
> + hash_len = SHA512_SUM_LEN;
> + sha512_csum_wd(tv->hash_message, strlen(tv->hash_message),
> + hash, CHUNKSZ_SHA512);
> +#else
> + /* sha512 is not supported so we skip this test */
> + ut_reportf("Test %s skipped (sha512 not supported)",
> + tv->test_name);
> + goto out;
> +#endif
> + } else {
> + ut_reportf("Unknown hash type (%s)", tv->hash_type);
> + return -EINVAL;
> + }
> +
> + ret = hex2bin(signature, tv->r, sig_len);
> + ut_asserteq(0, ret);
> + ret = hex2bin(signature + sig_len, tv->s, sig_len);
> + ut_asserteq(0, ret);
> + sig_len = sig_len * 2;
> +
> + ret = ecdsa_hash_verify(&pubkey,
> + hash, hash_len,
> + signature, sig_len);
> + ut_asserteq(tv->expected, ret);
> +
> +#if !CONFIG_IS_ENABLED(SHA1) || !CONFIG_IS_ENABLED(SHA256) || !CONFIG_IS_ENABLED(SHA384) || !CONFIG_IS_ENABLED(SHA512)
> + out:
> +#endif
> +
> + return 0;
> +}
> +
> +static int lib_ecdsa(struct unit_test_state *uts)
> +{
> + int i, ret;
> + size_t num_test = ARRAY_SIZE(ecdsa_test_vector);
> +
> + for (i = 0; i < num_test; i++) {
> + ret = ecdsa_test(uts, &ecdsa_test_vector[i]);
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> +LIB_TEST(lib_ecdsa, 0);
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 05/15] drivers: crypto: add software ecdsa support
2026-09-03 8:16 ` [PATCH v9 05/15] drivers: crypto: add software ecdsa support Philippe Reynes
@ 2026-09-03 14:32 ` Raymond Mao
2026-09-03 15:33 ` Raymond Mao
0 siblings, 1 reply; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:32 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> Add a software ecdsa driver so it is
> now possible to use ecdsa signature on
> board without ecdsa hardware support.
>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v2:
> - no change
> v3:
> - add depends on ECDSA_VERIFY to ECDSA_SW
> - change sw_ecdsa_verify to ecdsa_hash_verify
> - v4
> - use ECDSA_MBEDTLS to build the driver
> - clean include (change order)
> v5:
> - use $(PHASE_) in the Makefile for the driver
> v6:
> - remove include u-boot/ecdsa.h from ecdsa-sw.c
> v7:
> - no change
> v8:
> - no change
> v9:
> - no change
>
> drivers/crypto/Makefile | 1 +
> drivers/crypto/ecdsa/Makefile | 6 ++++++
> drivers/crypto/ecdsa/ecdsa-sw.c | 32 ++++++++++++++++++++++++++++++++
> 3 files changed, 39 insertions(+)
> create mode 100644 drivers/crypto/ecdsa/Makefile
> create mode 100644 drivers/crypto/ecdsa/ecdsa-sw.c
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
> index e4a4482b7f3..8170e4cae9c 100644
> --- a/drivers/crypto/Makefile
> +++ b/drivers/crypto/Makefile
> @@ -4,6 +4,7 @@
> # http://www.samsung.com
>
> obj-$(CONFIG_EXYNOS_ACE_SHA) += ace_sha.o
> +obj-$(CONFIG_ECDSA) += ecdsa/
> obj-y += aes/
> obj-y += rsa_mod_exp/
> obj-y += fsl/
> diff --git a/drivers/crypto/ecdsa/Makefile b/drivers/crypto/ecdsa/Makefile
> new file mode 100644
> index 00000000000..89be50824cb
> --- /dev/null
> +++ b/drivers/crypto/ecdsa/Makefile
> @@ -0,0 +1,6 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
> +#
> +
> +obj-$(CONFIG_$(PHASE_)ECDSA_VERIFY_MBEDTLS) += ecdsa-sw.o
> diff --git a/drivers/crypto/ecdsa/ecdsa-sw.c b/drivers/crypto/ecdsa/ecdsa-sw.c
> new file mode 100644
> index 00000000000..2af1405f73b
> --- /dev/null
> +++ b/drivers/crypto/ecdsa/ecdsa-sw.c
> @@ -0,0 +1,32 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
> + */
> +#include <crypto/ecdsa-uclass.h>
> +#include <crypto/internal/ecdsa.h>
> +#include <dm.h>
> +#include <linux/types.h>
> +
> +static int ops_sw_ecdsa_verify(__always_unused struct udevice *dev,
> + const struct ecdsa_public_key *pubkey,
> + const void *hash, size_t hash_len,
> + const void *signature, size_t sig_len)
> +{
> + return ecdsa_hash_verify(pubkey, hash, hash_len, signature, sig_len);
> +}
> +
> +static const struct ecdsa_ops sw_ecdsa_ops = {
> + .verify = ops_sw_ecdsa_verify,
> +};
> +
> +U_BOOT_DRIVER(sw_ecdsa) = {
> + .name = "sw_ecdsa",
> + .id = UCLASS_ECDSA,
> + .ops = &sw_ecdsa_ops,
> + .flags = DM_FLAG_PRE_RELOC,
> +};
> +
> +U_BOOT_DRVINFO(sw_ecdsa) = {
> + .name = "sw_ecdsa",
> +};
> +
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 06/15] test: dm: ecdsa.c: clean this test as software ecdsa is now implemented
2026-09-03 8:16 ` [PATCH v9 06/15] test: dm: ecdsa.c: clean this test as software ecdsa is now implemented Philippe Reynes
@ 2026-09-03 14:33 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:33 UTC (permalink / raw)
To: Philippe Reynes; +Cc: marko.makela, jonny.green, trini, simon.glass, u-boot
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> The test ecdsa was done when ecdsa was only supported by hardware.
> So it wasn't possible to test ecdsa on sandbox, and there is a test
> to check that ecdsa is not supported on sandbox.
> Now, there is a software implementation of ecdsa. So we add a test
> to verify that ecdsa_verify may be used on sandbox.
>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v2:
> - initial version
> v3:
> - no change
> v4:
> - add a test that use ecdsa_verify
> v5:
> - change secp256r1 to ecdsa256
> - check that checksum and crypto are not null
> v6:
> - update commit message
> - remove fdt_strerror in macro CHECK
> - return ENOMEM when malloc fails
> - add a define FDT_MAX_SIZE to avoid hardcoded value
> v7:
> - change uint8_t to u8
> - set required_keynode to -1
> v8:
> - remove macro CHECK with a goto inside
> - use lowercase for hex data
> - code cleanup
> v9:
> - no change
>
> test/dm/ecdsa.c | 107 +++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 97 insertions(+), 10 deletions(-)
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/test/dm/ecdsa.c b/test/dm/ecdsa.c
> index d7eac7115f7..261ca3f9f73 100644
> --- a/test/dm/ecdsa.c
> +++ b/test/dm/ecdsa.c
> @@ -3,36 +3,123 @@
> #include <crypto/ecdsa-uclass.h>
> #include <dm.h>
> #include <dm/test.h>
> +#include <malloc.h>
> #include <test/ut.h>
> #include <u-boot/ecdsa.h>
>
> +#define FDT_MAX_SIZE 512
> +
> +static int set_fdt_ecdsa_point(char *fdt, const char *name, const char *data)
> +{
> + char *value = NULL;
> + size_t len;
> + int ret = 0;
> +
> + if (!fdt || !name || !data) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + len = strlen(data) / 2;
> + if (!len) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + value = malloc(len);
> + if (!value) {
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + ret = hex2bin(value, data, len);
> + if (ret)
> + goto out;
> +
> + ret = fdt_property(fdt, name, value, len);
> + if (ret)
> + goto out;
> +
> +out:
> + free(value);
> + return ret;
> +}
> +
> +static int create_fdt_with_ecdsa_key(struct unit_test_state *uts,
> + char *fdt, size_t size,
> + const char *name, const char *curve,
> + const char *x, const char *y)
> +{
> + ut_assertok(fdt_create(fdt, size));
> + ut_assertok(fdt_finish_reservemap(fdt));
> + ut_assertok(fdt_begin_node(fdt, ""));
> + ut_assertok(fdt_begin_node(fdt, "signature"));
> + ut_assertok(fdt_begin_node(fdt, name));
> + ut_assertok(fdt_property_string(fdt, "algo", "sha256,ecdsa256"));
> + ut_assertok(set_fdt_ecdsa_point(fdt, "ecdsa,y-point", y));
> + ut_assertok(set_fdt_ecdsa_point(fdt, "ecdsa,x-point", x));
> + ut_assertok(fdt_property_string(fdt, "ecdsa,curve", curve));
> + ut_assertok(fdt_property_string(fdt, "key-name-hint", name));
> + ut_assertok(fdt_end_node(fdt)); /* name */
> + ut_assertok(fdt_end_node(fdt)); /* "signature" */
> + ut_assertok(fdt_end_node(fdt)); /* "" */
> + ut_assertok(fdt_finish(fdt));
> + ut_assertok(fdt_pack(fdt));
> +
> + return 0;
> +}
> +
> /*
> * Basic test of the ECDSA uclass and ecdsa_verify()
> *
> - * ECDSA implementations in u-boot are hardware-dependent. Until we have a
> - * software implementation that can be compiled into the sandbox, all we can
> - * test is the uclass support.
> + * ECDSA software implementation is tested in another test,
> + * so we only check that the UCLASS_ECDSA uclass may be used.
> *
> - * The uclass_get() test is redundant since ecdsa_verify() would also fail. We
> - * run both functions in order to isolate the cause more clearly. i.e. is
> - * ecdsa_verify() failing because the UCLASS is absent/broken?
> + * The data used in this test come from RFC6979 and use the
> + * sample with curve NIST P-256, hash sha256 and text "sample".
> */
> static int dm_test_ecdsa_verify(struct unit_test_state *uts)
> {
> struct uclass *ucp;
> + const char *full_name = "sha256,ecdsa256";
> + const char *name = "key-ecdsa-256";
> + const char *curve = "prime256v1";
> + const char *x = "60fed4ba255a9d31c961eb74c6356d68c049b8923b61fa6ce669622e60f29fb6";
> + const char *y = "7903fe1008b8bc99a41ae9e95628bc64f2f1b20c2d7e9f5177a3c294d4462299";
> + const char *r = "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716";
> + const char *s = "f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8";
> + u8 sig[64];
> + char fdt[FDT_MAX_SIZE];
>
> - struct checksum_algo algo = {
> - .checksum_len = 256,
> + struct image_region region[] = {
> + {
> + .data = "sample",
> + .size = strlen("sample"),
> + },
> };
>
> struct image_sign_info info = {
> - .checksum = &algo,
> + .checksum = image_get_checksum_algo(full_name),
> + .crypto = image_get_crypto_algo(full_name),
> + .required_keynode = -1,
> + .fdt_blob = fdt,
> };
>
> + ut_assertnonnull(info.checksum);
> + ut_assertnonnull(info.crypto);
> +
> + /* create a fdt with the public key */
> + ut_assertok(create_fdt_with_ecdsa_key(uts, fdt, sizeof(fdt), name, curve, x, y));
> +
> + /* prepare the signature */
> + ut_assertok(hex2bin(sig + 0, r, strlen(r) / 2));
> + ut_assertok(hex2bin(sig + 32, s, strlen(s) / 2));
> +
> ut_assertok(uclass_get(UCLASS_ECDSA, &ucp));
> ut_assertnonnull(ucp);
> - ut_asserteq(-ENODEV, ecdsa_verify(&info, NULL, 0, NULL, 0));
> + ut_assertok(ecdsa_verify(&info, region, 1, sig, sizeof(sig)));
>
> return 0;
> }
> +
> DM_TEST(dm_test_ecdsa_verify, UTF_SCAN_PDATA | UTF_SCAN_FDT);
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 09/15] tools: fit_image_setup_sig: set required_keynode to -1
2026-09-03 8:16 ` [PATCH v9 09/15] tools: fit_image_setup_sig: set required_keynode to -1 Philippe Reynes
@ 2026-09-03 14:34 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:34 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> When initializing info about a signature, set required_keynode
> to -1 instead of 0, as 0 is a valid keynode offset.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v5:
> - initial version
> v6:
> - no change
> v7:
> - change info->required_keynode > 0 to info->required_keynode >= 0
> in ecdsa_verify_hash
> v8:
> - no change
> v9:
> - no change
>
> lib/ecdsa/ecdsa-verify.c | 2 +-
> tools/image-host.c | 1 +
> 2 files changed, 2 insertions(+), 1 deletion(-)
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/lib/ecdsa/ecdsa-verify.c b/lib/ecdsa/ecdsa-verify.c
> index 494b60b4ab0..341486de2d3 100644
> --- a/lib/ecdsa/ecdsa-verify.c
> +++ b/lib/ecdsa/ecdsa-verify.c
> @@ -117,7 +117,7 @@ static int ecdsa_verify_hash(struct udevice *dev,
> if (!ops || !ops->verify)
> return -ENODEV;
>
> - if (info->required_keynode > 0) {
> + if (info->required_keynode >= 0) {
> ret = fdt_get_key(&key, info->fdt_blob, info->required_keynode);
> if (ret < 0)
> return ret;
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 46036673050..9a85a3dda2f 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -202,6 +202,7 @@ static int fit_image_setup_sig(struct image_sign_info *info,
> info->checksum = image_get_checksum_algo(algo_name);
> info->crypto = image_get_crypto_algo(algo_name);
> info->padding = image_get_padding_algo(padding_name);
> + info->required_keynode = -1;
> info->require_keys = require_keys;
> info->engine_id = engine_id;
> if (!info->checksum || !info->crypto) {
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 10/15] tools: mkimage: pre-load: add support of ecdsa
2026-09-03 8:17 ` [PATCH v9 10/15] tools: mkimage: pre-load: add support of ecdsa Philippe Reynes
@ 2026-09-03 14:36 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:36 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> Right now, mkimage can only create pre-load header
> using rsa. We add the support of ecdsa.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v3:
> - initial version
> v4:
> - use pre_load_noffset (do not compute it again)
> - release memory allocated with strdup
> - clean code
> v5:
> - check checksum and algo before using them
> v6:
> - no change
> v7:
> - no change
> v8:
> - no change
> v9:
> - no change
>
> lib/ecdsa/ecdsa-libcrypto.c | 29 +++++++++---
> tools/image-host.c | 92 ++++++++++++++++++++++++++++++++-----
> 2 files changed, 103 insertions(+), 18 deletions(-)
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/lib/ecdsa/ecdsa-libcrypto.c b/lib/ecdsa/ecdsa-libcrypto.c
> index b3fc75fac48..5e69782424c 100644
> --- a/lib/ecdsa/ecdsa-libcrypto.c
> +++ b/lib/ecdsa/ecdsa-libcrypto.c
> @@ -517,14 +517,9 @@ int ecdsa_verify(struct image_sign_info *info,
> return ret;
> }
>
> -static int do_add(struct signer *ctx, void *fdt, const char *key_node_name,
> - struct image_sign_info *info)
> +static int search_key_node(void *fdt, const char *key_node_name)
> {
> - int signature_node, key_node, ret, key_bits;
> - const char *curve_name;
> - const EC_GROUP *group;
> - const EC_POINT *point;
> - BIGNUM *x, *y;
> + int signature_node, key_node;
>
> signature_node = fdt_subnode_offset(fdt, 0, FIT_SIG_NODENAME);
> if (signature_node == -FDT_ERR_NOTFOUND) {
> @@ -559,6 +554,26 @@ static int do_add(struct signer *ctx, void *fdt, const char *key_node_name,
> return key_node;
> }
>
> + return key_node;
> +}
> +
> +static int do_add(struct signer *ctx, void *fdt, const char *key_node_name,
> + struct image_sign_info *info)
> +{
> + int key_node, ret, key_bits;
> + const char *curve_name;
> + const EC_GROUP *group;
> + const EC_POINT *point;
> + BIGNUM *x, *y;
> +
> + if (info->required_keynode >= 0) {
> + key_node = info->required_keynode;
> + } else {
> + key_node = search_key_node(fdt, key_node_name);
> + if (key_node < 0)
> + return key_node;
> + }
> +
> group = EC_KEY_get0_group(ctx->ecdsa_key);
> key_bits = EC_GROUP_order_bits(group);
> curve_name = OBJ_nid2sn(EC_GROUP_get_curve_name(group));
> diff --git a/tools/image-host.c b/tools/image-host.c
> index 9a85a3dda2f..ed1bfe68a31 100644
> --- a/tools/image-host.c
> +++ b/tools/image-host.c
> @@ -14,6 +14,7 @@
> #include <image.h>
> #include <hexdump.h>
> #include <version.h>
> +#include <u-boot/ecdsa.h>
>
> #include <sys/stat.h>
> #include <sys/wait.h>
> @@ -1681,13 +1682,74 @@ err_cert:
> return ret;
> }
>
> +static int fit_pre_load_data_key_rsa(const char *keydir, void *keydest,
> + int pre_load_noffset, const void *key_name)
> +{
> + unsigned char *pubkey = NULL;
> + int ret, pubkey_len;
> +
> + /* Read public key */
> + ret = read_pub_key(keydir, key_name, &pubkey, &pubkey_len);
> + if (ret < 0)
> + goto out;
> +
> + /* Add the public key to the device tree */
> + ret = fdt_setprop(keydest, pre_load_noffset, "public-key",
> + pubkey, pubkey_len);
> + if (ret)
> + fprintf(stderr, "Can't set public-key in node %s (ret = %d)\n",
> + IMAGE_PRE_LOAD_PATH, ret);
> + out:
> + return ret;
> +}
> +
> +static int fit_pre_load_data_key_ecdsa(const char *keydir, void *keydest,
> + int pre_load_noffset, const void *key_name,
> + const void *algo_name)
> +{
> + struct image_sign_info info;
> + int node, ret = 0;
> +
> + memset(&info, 0, sizeof(info));
> + info.keydir = keydir;
> + info.keyname = strdup(key_name);
> + info.name = strdup(algo_name);
> + info.checksum = image_get_checksum_algo(algo_name);
> + if (!info.checksum) {
> + fprintf(stderr, "Can't find valid checksum from %s\n",
> + (char *)algo_name);
> + ret = -EINVAL;
> + goto out;
> + }
> + info.crypto = image_get_crypto_algo(algo_name);
> + if (!info.crypto) {
> + fprintf(stderr, "Can't find valid crypto from %s\n",
> + (char *)algo_name);
> + ret = -EINVAL;
> + goto out;
> + }
> + info.required_keynode = pre_load_noffset;
> +
> + node = ecdsa_add_verify_data(&info, keydest);
> + if (node < 0) {
> + fprintf(stderr, "Can't add verify data: err = %d\n", node);
> + ret = -EIO;
> + }
> +
> + out:
> + free((void *)info.keyname);
> + free((void *)info.name);
> +
> + return ret;
> +}
> +
> int fit_pre_load_data(const char *keydir, void *keydest, void *fit)
> {
> int pre_load_noffset;
> const void *algo_name;
> const void *key_name;
> - unsigned char *pubkey = NULL;
> - int ret, pubkey_len;
> + char *name;
> + int ret;
>
> if (!keydir || !keydest || !fit)
> return 0;
> @@ -1714,17 +1776,25 @@ int fit_pre_load_data(const char *keydir, void *keydest, void *fit)
> goto out;
> }
>
> - /* Read public key */
> - ret = read_pub_key(keydir, key_name, &pubkey, &pubkey_len);
> - if (ret < 0)
> + /* Is it a RSA or an ECDSA key */
> + name = strchr((const char *)algo_name, ',');
> + if (!name) {
> + fprintf(stderr, "The name of the algo is invalid: %s\n",
> + (char *)algo_name);
> + ret = -EINVAL;
> goto out;
> + }
> + name += 1;
>
> - /* Add the public key to the device tree */
> - ret = fdt_setprop(keydest, pre_load_noffset, "public-key",
> - pubkey, pubkey_len);
> - if (ret)
> - fprintf(stderr, "Can't set public-key in node %s (ret = %d)\n",
> - IMAGE_PRE_LOAD_PATH, ret);
> + if (!strncmp(name, "rsa", 3)) {
> + ret = fit_pre_load_data_key_rsa(keydir, keydest, pre_load_noffset, key_name);
> + } else if (!strncmp(name, "ecdsa", 5)) {
> + ret = fit_pre_load_data_key_ecdsa(keydir, keydest, pre_load_noffset,
> + key_name, algo_name);
> + } else {
> + fprintf(stderr, "The algo %s is not supported\n", (char *)algo_name);
> + ret = -EINVAL;
> + }
>
> out:
> return ret;
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 11/15] tools: binman: pre-load: add support of ecdsa
2026-09-03 8:17 ` [PATCH v9 11/15] tools: binman: " Philippe Reynes
@ 2026-09-03 14:37 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:37 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> Right now, binman can only create pre-load header
> using rsa. We add the support of ecdsa.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v3:
> - initial version
> v4:
> - merge patch 11 that was adding test for ecdsa pre-load
> - add key size check
> - use exc instead of simply e
> - rename dts filaneme
> - add a test to check key size
> v5:
> - compute ecdsa521 sig instead of using hardcoded value 132
> - fix english: don't -> doesn't
> - avoid line too long
> v6:
> - no change
> v7:
> - no change
> v8:
> - no change
> v9:
> - no change
>
> tools/binman/etype/pre_load.py | 78 ++++++++++++++++---
> tools/binman/ftest.py | 50 ++++++++++++
> tools/binman/test/ecdsa521.pem | 7 ++
> tools/binman/test/security/pre_load_ecdsa.dts | 22 ++++++
> .../security/pre_load_ecdsa_invalid_algo.dts | 22 ++++++
> .../security/pre_load_ecdsa_invalid_key.dts | 22 ++++++
> .../security/pre_load_ecdsa_invalid_sha.dts | 22 ++++++
> 7 files changed, 214 insertions(+), 9 deletions(-)
> create mode 100644 tools/binman/test/ecdsa521.pem
> create mode 100644 tools/binman/test/security/pre_load_ecdsa.dts
> create mode 100644 tools/binman/test/security/pre_load_ecdsa_invalid_algo.dts
> create mode 100644 tools/binman/test/security/pre_load_ecdsa_invalid_key.dts
> create mode 100644 tools/binman/test/security/pre_load_ecdsa_invalid_sha.dts
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/tools/binman/etype/pre_load.py b/tools/binman/etype/pre_load.py
> index 0d953cb258e..7890c1c62a8 100644
> --- a/tools/binman/etype/pre_load.py
> +++ b/tools/binman/etype/pre_load.py
> @@ -16,8 +16,10 @@ from binman.entry import EntryArg
>
> from Cryptodome.Hash import SHA256, SHA384, SHA512
> from Cryptodome.PublicKey import RSA
> +from Cryptodome.PublicKey import ECC
> from Cryptodome.Signature import pkcs1_15
> from Cryptodome.Signature import pss
> +from Cryptodome.Signature import DSS
>
> PRE_LOAD_MAGIC = b'UBSH'
>
> @@ -27,6 +29,12 @@ RSAS = {
> 'rsa4096': 4096 / 8
> }
>
> +ECDSAS = {
> + 'ecdsa256': 256 / 8 * 2,
> + 'ecdsa384': 384 / 8 * 2,
> + 'ecdsa521': (521 + 7) / 8 * 2
> +}
> +
> SHAS = {
> 'sha256': SHA256,
> 'sha384': SHA384,
> @@ -86,24 +94,17 @@ class Entry_pre_load(Entry_collection):
> if self.key_path is None:
> self.key_path = ''
>
> - def _CreateHeader(self):
> - """Create a pre load header"""
> - hash_name, sign_name = self.algo_name.split(',')
> - padding_name = self.padding_name
> - key_name = os.path.join(self.key_path, self.key_name)
> -
> + def _CreateHeaderRsa(self, hash_name, sign_name, padding_name, key_name):
> # Check hash and signature name/type
> if hash_name not in SHAS:
> self.Raise(hash_name + " is not supported")
> - if sign_name not in RSAS:
> - self.Raise(sign_name + " is not supported")
>
> # Read the key
> key = RSA.import_key(tools.read_file(key_name))
>
> # Check if the key has the expected size
> if key.size_in_bytes() != RSAS[sign_name]:
> - self.Raise("The key " + self.key_name + " don't have the expected size")
> + self.Raise("The key " + self.key_name + " doesn't have the expected size")
>
> # Compute the hash
> hash_image = SHAS[hash_name].new()
> @@ -151,6 +152,65 @@ class Entry_pre_load(Entry_collection):
>
> return data + pad
>
> + def _CreateHeaderEcdsa(self, hash_name, sign_name, key_name):
> + # Check hash and signature name/type
> + if hash_name not in SHAS:
> + self.Raise(hash_name + " is not supported")
> +
> + # Read the key
> + key = ECC.import_key(tools.read_file(key_name))
> +
> + # Check if the key has the expected size
> + if key.pointQ.size_in_bytes() * 2 != ECDSAS[sign_name]:
> + self.Raise("The key " + self.key_name + " doesn't have the expected size")
> +
> + # Compute the hash
> + hash_image = SHAS[hash_name].new()
> + hash_image.update(self.image)
> +
> + # Compute the signature
> + signer = DSS.new(key, 'fips-186-3')
> + sig = signer.sign(hash_image)
> +
> + hash_sig = SHA256.new()
> + hash_sig.update(sig)
> +
> + version = self.version
> + header_size = self.header_size
> + image_size = len(self.image)
> + ofs_img_sig = 64 + len(sig)
> + flags = 0
> + reserved0 = 0
> + reserved1 = 0
> +
> + first_header = struct.pack('>4sIIIIIII32s', PRE_LOAD_MAGIC,
> + version, header_size, image_size,
> + ofs_img_sig, flags, reserved0,
> + reserved1, hash_sig.digest())
> +
> + hash_first_header = SHAS[hash_name].new()
> + hash_first_header.update(first_header)
> + sig_first_header = signer.sign(hash_first_header)
> +
> + data = first_header + sig_first_header + sig
> + pad = bytearray(self.header_size - len(data))
> +
> + return data + pad
> +
> + def _CreateHeader(self):
> + """Create a pre load header"""
> + hash_name, sign_name = self.algo_name.split(',')
> + padding_name = self.padding_name
> + key_name = os.path.join(self.key_path, self.key_name)
> +
> + if sign_name in RSAS:
> + return self._CreateHeaderRsa(hash_name, sign_name, padding_name, key_name)
> +
> + if sign_name in ECDSAS:
> + return self._CreateHeaderEcdsa(hash_name, sign_name, key_name)
> +
> + self.Raise(sign_name + " is not supported")
> +
> def ObtainContents(self):
> """Create a placeholder for the header"""
> self.SetContents(tools.get_bytes(0, self.header_size))
> diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py
> index 5f0de4c74a7..a3209bb1595 100644
> --- a/tools/binman/ftest.py
> +++ b/tools/binman/ftest.py
> @@ -5925,12 +5925,62 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
>
> image_fname = tools.get_output_filename('image.bin')
> is_signed = self._CheckPreload(image_fname, self.TestFile("dev.key"))
> + self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
> + self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
> + self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
> + self.assertEqual(is_signed, True)
>
> + def testPreLoadEcdsa(self):
> + """Test an image with a pre-load header using ecdsa key"""
> + entry_args = {
> + 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
> + }
> + data = self._DoReadFileDtb(
> + 'security/pre_load_ecdsa.dts', entry_args=entry_args,
> + extra_indirs=[os.path.join(self._binman_dir, 'test')])[0]
> +
> + image_fname = tools.get_output_filename('image.bin')
> + is_signed = self._CheckPreload(image_fname,
> + self.TestFile('ecdsa521.pem'),
> + 'sha256,ecdsa521')
> self.assertEqual(PRE_LOAD_MAGIC, data[:len(PRE_LOAD_MAGIC)])
> self.assertEqual(PRE_LOAD_VERSION, data[4:4 + len(PRE_LOAD_VERSION)])
> self.assertEqual(PRE_LOAD_HDR_SIZE, data[8:8 + len(PRE_LOAD_HDR_SIZE)])
> self.assertEqual(is_signed, True)
>
> + def testPreLoadEcdsaInvalidSha(self):
> + """Test an image with a pre-load ecdsa header with an invalid hash"""
> + entry_args = {
> + 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
> + }
> + with self.assertRaises(ValueError) as exc:
> + self._DoReadFileDtb('security/pre_load_ecdsa_invalid_sha.dts',
> + entry_args=entry_args)
> + self.assertIn("Node '/binman/pre-load': sha2560 is not supported",
> + str(exc.exception))
> +
> + def testPreLoadEcdsaInvalidAlgo(self):
> + """Test an image with a pre-load header with an invalid algo"""
> + entry_args = {
> + 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
> + }
> + with self.assertRaises(ValueError) as exc:
> + data = self._DoReadFileDtb('security/pre_load_ecdsa_invalid_algo.dts',
> + entry_args=entry_args)
> + self.assertIn("Node '/binman/pre-load': ecdsa5210 is not supported",
> + str(exc.exception))
> +
> + def testPreLoadEcdsaInvalidKey(self):
> + """Test an image with a pre-load header with an invalid key size"""
> + entry_args = {
> + 'pre-load-key-path': os.path.join(self._binman_dir, 'test'),
> + }
> + with self.assertRaises(ValueError) as exc:
> + data = self._DoReadFileDtb('security/pre_load_ecdsa_invalid_key.dts',
> + entry_args=entry_args)
> + self.assertIn("Node '/binman/pre-load': The key ecdsa521.pem doesn't have the expected size",
> + str(exc.exception))
> +
> def _CheckSafeUniqueNames(self, *images):
> """Check all entries of given images for unsafe unique names"""
> for image in images:
> diff --git a/tools/binman/test/ecdsa521.pem b/tools/binman/test/ecdsa521.pem
> new file mode 100644
> index 00000000000..ac1904d3955
> --- /dev/null
> +++ b/tools/binman/test/ecdsa521.pem
> @@ -0,0 +1,7 @@
> +-----BEGIN EC PRIVATE KEY-----
> +MIHcAgEBBEIBM+CNnraGci2/mw1wPq44l2HccHnoBbdP3DiU6zqsBOq8IR8uegz2
> +FLzWsjxcW7hwROCdEm6tW99wqsyPE25RZ3egBwYFK4EEACOhgYkDgYYABABu5bWV
> +aQ4EgnXFjojX9df3gBEBipphEEFAoG87GuoWBdlimFC8UEEXiKNU37w0wlJn4bG0
> +8uOKwDqBk3uF+DrmZwB45lCSKkjdRWsJeDt+iEuFe2O/mbXoL4p5D8MM2OsDV5GT
> +srUbxhXq+T/i5lV7XXm2+tT/7zU8ZQce6WRufbd9KQ==
> +-----END EC PRIVATE KEY-----
> diff --git a/tools/binman/test/security/pre_load_ecdsa.dts b/tools/binman/test/security/pre_load_ecdsa.dts
> new file mode 100644
> index 00000000000..247b85aad4c
> --- /dev/null
> +++ b/tools/binman/test/security/pre_load_ecdsa.dts
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + binman {
> + pre-load {
> + content = <&image>;
> + algo-name = "sha256,ecdsa521";
> + key-name = "ecdsa521.pem";
> + header-size = <4096>;
> + version = <0x11223344>;
> + };
> +
> + image: blob-ext {
> + filename = "refcode.bin";
> + };
> + };
> +};
> diff --git a/tools/binman/test/security/pre_load_ecdsa_invalid_algo.dts b/tools/binman/test/security/pre_load_ecdsa_invalid_algo.dts
> new file mode 100644
> index 00000000000..be71edbbdcd
> --- /dev/null
> +++ b/tools/binman/test/security/pre_load_ecdsa_invalid_algo.dts
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + binman {
> + pre-load {
> + content = <&image>;
> + algo-name = "sha256,ecdsa5210";
> + key-name = "ecdsa521.pem";
> + header-size = <4096>;
> + version = <0x11223344>;
> + };
> +
> + image: blob-ext {
> + filename = "refcode.bin";
> + };
> + };
> +};
> diff --git a/tools/binman/test/security/pre_load_ecdsa_invalid_key.dts b/tools/binman/test/security/pre_load_ecdsa_invalid_key.dts
> new file mode 100644
> index 00000000000..15d71cf0324
> --- /dev/null
> +++ b/tools/binman/test/security/pre_load_ecdsa_invalid_key.dts
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + binman {
> + pre-load {
> + content = <&image>;
> + algo-name = "sha256,ecdsa384";
> + key-name = "ecdsa521.pem";
> + header-size = <4096>;
> + version = <0x11223344>;
> + };
> +
> + image: blob-ext {
> + filename = "refcode.bin";
> + };
> + };
> +};
> diff --git a/tools/binman/test/security/pre_load_ecdsa_invalid_sha.dts b/tools/binman/test/security/pre_load_ecdsa_invalid_sha.dts
> new file mode 100644
> index 00000000000..1017707375e
> --- /dev/null
> +++ b/tools/binman/test/security/pre_load_ecdsa_invalid_sha.dts
> @@ -0,0 +1,22 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + binman {
> + pre-load {
> + content = <&image>;
> + algo-name = "sha2560,ecdsa521";
> + key-name = "ecdsa521.pem";
> + header-size = <4096>;
> + version = <0x11223344>;
> + };
> +
> + image: blob-ext {
> + filename = "refcode.bin";
> + };
> + };
> +};
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 12/15] boot: pre-load: add support of ecdsa
2026-09-03 8:17 ` [PATCH v9 12/15] boot: " Philippe Reynes
@ 2026-09-03 14:38 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:38 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> Right now, u-boot can only boot image with a
> pre-load header with rsa. We add the support
> of ecdsa.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v3:
> - initial version
> v4:
> - avoid calling image_get_crypto_algo several times
> v5:
> - simplify the function is_ecdsa
> - re-use already computed crypto in function image_pre_load_sig_setup
> v6:
> - no change
> v7:
> - no change
> v8:
> - no change
> v9:
> - no change
>
> boot/image-pre-load.c | 53 +++++++++++++++++++++++++++++++++----------
> 1 file changed, 41 insertions(+), 12 deletions(-)
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/boot/image-pre-load.c b/boot/image-pre-load.c
> index 2f851ebb28c..af72ea6d547 100644
> --- a/boot/image-pre-load.c
> +++ b/boot/image-pre-load.c
> @@ -70,6 +70,12 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
> return 0;
> }
> #else
> +
> +static int is_ecdsa(struct crypto_algo *crypto)
> +{
> + return crypto && !strncmp(crypto->name, "ecdsa", 5);
> +}
> +
> /*
> * This function gathers information about the signature check
> * that could be done before launching the image.
> @@ -86,6 +92,7 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
> int key_len;
> int node, ret = 0;
> char *sig_info_path = NULL;
> + struct crypto_algo *crypto;
>
> if (!info) {
> log_err("ERROR: info is NULL for image pre-load sig check\n");
> @@ -114,11 +121,24 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
> goto out;
> }
>
> - padding_name = fdt_getprop(gd_fdt_blob(), node,
> - IMAGE_PRE_LOAD_PROP_PADDING_NAME, NULL);
> - if (!padding_name) {
> - log_info("INFO: no padding_name provided, so using pkcs-1.5\n");
> - padding_name = "pkcs-1.5";
> + crypto = image_get_crypto_algo(algo_name);
> + if (!crypto) {
> + printf("ERROR: can't find a valid crypto algo from %s\n",
> + (char *)algo_name);
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + if (is_ecdsa(crypto)) {
> + padding_name = NULL;
> + } else {
> + padding_name = fdt_getprop(gd_fdt_blob(), node,
> + IMAGE_PRE_LOAD_PROP_PADDING_NAME,
> + NULL);
> + if (!padding_name) {
> + log_info("INFO: no padding_name provided, so using pkcs-1.5\n");
> + padding_name = "pkcs-1.5";
> + }
> }
>
> sig_size = fdt_getprop(gd_fdt_blob(), node,
> @@ -129,12 +149,17 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
> goto out;
> }
>
> - key = fdt_getprop(gd_fdt_blob(), node,
> - IMAGE_PRE_LOAD_PROP_PUBLIC_KEY, &key_len);
> - if (!key) {
> - log_err("ERROR: no key for image pre-load sig check\n");
> - ret = -EINVAL;
> - goto out;
> + if (is_ecdsa(crypto)) {
> + key = NULL;
> + key_len = 0;
> + } else {
> + key = fdt_getprop(gd_fdt_blob(), node,
> + IMAGE_PRE_LOAD_PROP_PUBLIC_KEY, &key_len);
> + if (!key) {
> + log_err("ERROR: no key for image pre-load sig check\n");
> + ret = -EINVAL;
> + goto out;
> + }
> }
>
> info->algo_name = (char *)algo_name;
> @@ -152,9 +177,13 @@ static int image_pre_load_sig_setup(struct image_sig_info *info)
> info->sig_info.name = info->algo_name;
> info->sig_info.padding = image_get_padding_algo(info->padding_name);
> info->sig_info.checksum = image_get_checksum_algo(info->sig_info.name);
> - info->sig_info.crypto = image_get_crypto_algo(info->sig_info.name);
> + info->sig_info.crypto = crypto;
> info->sig_info.key = info->key;
> info->sig_info.keylen = info->key_len;
> + if (is_ecdsa(crypto)) {
> + info->sig_info.required_keynode = node;
> + info->sig_info.fdt_blob = gd_fdt_blob();
> + }
>
> out:
> return ret;
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 13/15] tools: preload_check_sign: add support of ecdsa
2026-09-03 8:17 ` [PATCH v9 13/15] tools: preload_check_sign: " Philippe Reynes
@ 2026-09-03 14:39 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:39 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> right now, the tool preload_check_sign may only
> checks an image with a pre-load header with rsa.
> We add the support of pre-load header with ecdsa.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v3:
> - initial version
> v4:
> - free key to avoid mem leak
> - fix error management (set ret before goto out)
> v5:
> - add include ec.h, evp.h, err.h and image.h
> v6:
> - no change
> v7:
> - no change
> v8:
> - no change
> v9:
> - no change
>
> tools/preload_check_sign.c | 30 ++++++++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/tools/preload_check_sign.c b/tools/preload_check_sign.c
> index ebead459273..d94f0509e74 100644
> --- a/tools/preload_check_sign.c
> +++ b/tools/preload_check_sign.c
> @@ -8,9 +8,13 @@
> * complete file. The tool preload_check_sign allows to verify and authenticate
> * a file starting with a preload header.
> */
> +
> +#define OPENSSL_API_COMPAT 0x10101000L
> +
> #include <stdio.h>
> #include <unistd.h>
> #include <openssl/pem.h>
> +#include <openssl/ec.h>
> #include <openssl/evp.h>
> #include <openssl/err.h>
> #include <image.h>
> @@ -144,6 +148,32 @@ int main(int argc, char **argv)
> info.sig_info.key = info.key;
> info.sig_info.keylen = info.key_len;
>
> + /* For ecdsa key, we have to update some values */
> + if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
> + EC_KEY *ecdsa_key;
> + const EC_GROUP *group;
> +
> + ecdsa_key = EVP_PKEY_get1_EC_KEY(pkey);
> + if (!ecdsa_key) {
> + fprintf(stderr, "Can not extract ECDSA key\n");
> + ret = EXIT_FAILURE;
> + goto out;
> + }
> +
> + group = EC_KEY_get0_group(ecdsa_key);
> + if (!group) {
> + fprintf(stderr, "Can not extract ECDSA group\n");
> + EC_KEY_free(ecdsa_key);
> + ret = EXIT_FAILURE;
> + goto out;
> + }
> +
> + info.sig_info.keyfile = keyfile;
> + info.sig_size = (EC_GROUP_order_bits(group) + 7) / 8 * 2;
> +
> + EC_KEY_free(ecdsa_key);
> + }
> +
> /* Check the signature */
> image_pre_load_sig_set_info(&info);
> ret = image_pre_load_sig((ulong)buffer);
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 14/15] test: py: vboot: prepare test for global signature with ecdsa
2026-09-03 8:17 ` [PATCH v9 14/15] test: py: vboot: prepare test for global signature with ecdsa Philippe Reynes
@ 2026-09-03 14:40 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:40 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> The vboot tests only consider rsa for test with global signature.
> To prepare the integration of test with ecdsa test, the signature
> algo is now explicit.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v3:
> - initial version
> v4:
> - no change
> v5:
> - no change
> v6:
> - no change
> v7:
> - no change
> v8:
> - no change
> v9:
> - no change
>
> test/py/tests/test_vboot.py | 12 ++++++------
> ...binman-pss.dts => sandbox-binman-rsa2048-pss.dts} | 0
> ...sandbox-binman.dts => sandbox-binman-rsa2048.dts} | 0
> ...pss.dts => sandbox-u-boot-global-rsa2048-pss.dts} | 0
> ...-global.dts => sandbox-u-boot-global-rsa2048.dts} | 0
> 5 files changed, 6 insertions(+), 6 deletions(-)
> rename test/py/tests/vboot/{sandbox-binman-pss.dts => sandbox-binman-rsa2048-pss.dts} (100%)
> rename test/py/tests/vboot/{sandbox-binman.dts => sandbox-binman-rsa2048.dts} (100%)
> rename test/py/tests/vboot/{sandbox-u-boot-global-pss.dts => sandbox-u-boot-global-rsa2048-pss.dts} (100%)
> rename test/py/tests/vboot/{sandbox-u-boot-global.dts => sandbox-u-boot-global-rsa2048.dts} (100%)
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
> index 89876ff030a..e3996486ab6 100644
> --- a/test/py/tests/test_vboot.py
> +++ b/test/py/tests/test_vboot.py
> @@ -536,7 +536,7 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
> dtb)
> run_bootm(sha_algo, 'multi required key', '', False)
>
> - def test_global_sign(sha_algo, padding, sign_options):
> + def test_global_sign(sha_algo, sig_algo, padding, sign_options):
> """Test global image signature with the given hash algorithm and padding.
>
> Args:
> @@ -545,14 +545,14 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
> rsa signature algorithm.
> """
>
> - dtb = '%ssandbox-u-boot-global%s.dtb' % (tmpdir, padding)
> + dtb = '%ssandbox-u-boot-global%s%s.dtb' % (tmpdir, sig_algo, padding)
> ubman.config.dtb = dtb
>
> # Compile our device tree files for kernel and U-Boot. These are
> # regenerated here since mkimage will modify them (by adding a
> # public key) below.
> dtc('sandbox-kernel.dts', ubman, dtc_args, datadir, tmpdir, dtb)
> - dtc_options('sandbox-u-boot-global%s.dts' % padding, '-p 1024')
> + dtc_options('sandbox-u-boot-global%s%s.dts' % (sig_algo, padding), '-p 1024')
>
> # Build the FIT with dev key (keys NOT required). This adds the
> # signature into sandbox-u-boot.dtb, NOT marked 'required'.
> @@ -561,11 +561,11 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
>
> # Build the dtb for binman that define the pre-load header
> # with the global sigature.
> - dtc('sandbox-binman%s.dts' % padding, ubman, dtc_args, datadir, tmpdir, dtb)
> + dtc('sandbox-binman%s%s.dts' % (sig_algo, padding), ubman, dtc_args, datadir, tmpdir, dtb)
>
> # Run binman to create the final image with the not signed fit
> # and the pre-load header that contains the global signature.
> - run_binman('sandbox-binman%s.dtb' % padding)
> + run_binman('sandbox-binman%s%s.dtb' % (sig_algo, padding))
>
> # Check that the signature is correctly verified by u-boot
> run_bootm(sha_algo, 'global image signature',
> @@ -615,7 +615,7 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
> try:
> ubman.config.dtb = dtb
> if global_sign:
> - test_global_sign(sha_algo, padding, sign_options)
> + test_global_sign(sha_algo, sig_algo, padding, sign_options)
> elif required:
> test_required_key(sha_algo, sig_algo, padding, sign_options)
> else:
> diff --git a/test/py/tests/vboot/sandbox-binman-pss.dts b/test/py/tests/vboot/sandbox-binman-rsa2048-pss.dts
> similarity index 100%
> rename from test/py/tests/vboot/sandbox-binman-pss.dts
> rename to test/py/tests/vboot/sandbox-binman-rsa2048-pss.dts
> diff --git a/test/py/tests/vboot/sandbox-binman.dts b/test/py/tests/vboot/sandbox-binman-rsa2048.dts
> similarity index 100%
> rename from test/py/tests/vboot/sandbox-binman.dts
> rename to test/py/tests/vboot/sandbox-binman-rsa2048.dts
> diff --git a/test/py/tests/vboot/sandbox-u-boot-global-pss.dts b/test/py/tests/vboot/sandbox-u-boot-global-rsa2048-pss.dts
> similarity index 100%
> rename from test/py/tests/vboot/sandbox-u-boot-global-pss.dts
> rename to test/py/tests/vboot/sandbox-u-boot-global-rsa2048-pss.dts
> diff --git a/test/py/tests/vboot/sandbox-u-boot-global.dts b/test/py/tests/vboot/sandbox-u-boot-global-rsa2048.dts
> similarity index 100%
> rename from test/py/tests/vboot/sandbox-u-boot-global.dts
> rename to test/py/tests/vboot/sandbox-u-boot-global-rsa2048.dts
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 15/15] test: py: vboot: add test for global signature with ecdsa
2026-09-03 8:17 ` [PATCH v9 15/15] test: py: vboot: add " Philippe Reynes
@ 2026-09-03 14:41 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 14:41 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> As now u-boot supports pre-load header with ecdsa, we
> add some tests to vboot with ecdsa pre-load header.
>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v3:
> - initial version
> v4:
> - no change
> v5:
> - no change
> v6:
> - no change
> v7:
> - no change
> v8:
> - no change
> v9:
> - no change
>
> test/py/tests/test_vboot.py | 3 +++
> .../tests/vboot/sandbox-binman-ecdsa256.dts | 24 +++++++++++++++++
> .../tests/vboot/sandbox-binman-ecdsa384.dts | 24 +++++++++++++++++
> .../tests/vboot/sandbox-binman-ecdsa521.dts | 24 +++++++++++++++++
> .../vboot/sandbox-u-boot-global-ecdsa256.dts | 27 +++++++++++++++++++
> .../vboot/sandbox-u-boot-global-ecdsa384.dts | 27 +++++++++++++++++++
> .../vboot/sandbox-u-boot-global-ecdsa521.dts | 27 +++++++++++++++++++
> 7 files changed, 156 insertions(+)
> create mode 100644 test/py/tests/vboot/sandbox-binman-ecdsa256.dts
> create mode 100644 test/py/tests/vboot/sandbox-binman-ecdsa384.dts
> create mode 100644 test/py/tests/vboot/sandbox-binman-ecdsa521.dts
> create mode 100644 test/py/tests/vboot/sandbox-u-boot-global-ecdsa256.dts
> create mode 100644 test/py/tests/vboot/sandbox-u-boot-global-ecdsa384.dts
> create mode 100644 test/py/tests/vboot/sandbox-u-boot-global-ecdsa521.dts
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
> index e3996486ab6..ed7e6bb33d2 100644
> --- a/test/py/tests/test_vboot.py
> +++ b/test/py/tests/test_vboot.py
> @@ -102,6 +102,9 @@ TESTDATA_IN = [
> ['algo-arg', 'algo-arg', '', '', '-o sha256,rsa2048', False, False, True, False],
> ['sha256-global-sign', 'sha256', '-rsa2048', '', '', False, False, False, True],
> ['sha256-global-sign-pss', 'sha256', '-rsa2048', '-pss', '', False, False, False, True],
> + ['sha256-global-sign-ecdsa256', 'sha256', '-ecdsa256', '', '', False, False, False, True],
> + ['sha256-global-sign-ecdsa384', 'sha256', '-ecdsa384', '', '', False, False, False, True],
> + ['sha256-global-sign-ecdsa521', 'sha256', '-ecdsa521', '', '', False, False, False, True],
> ]
>
> # Mark all but the first test as slow, so they are not run with '-k not slow'
> diff --git a/test/py/tests/vboot/sandbox-binman-ecdsa256.dts b/test/py/tests/vboot/sandbox-binman-ecdsa256.dts
> new file mode 100644
> index 00000000000..0e84b81078b
> --- /dev/null
> +++ b/test/py/tests/vboot/sandbox-binman-ecdsa256.dts
> @@ -0,0 +1,24 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + binman {
> + filename = "sandbox.img";
> +
> + pre-load {
> + content = <&image>;
> + algo-name = "sha256,ecdsa256";
> + key-name = "dev.pem";
> + header-size = <4096>;
> + version = <1>;
> + };
> +
> + image: blob-ext {
> + filename = "test.fit";
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sandbox-binman-ecdsa384.dts b/test/py/tests/vboot/sandbox-binman-ecdsa384.dts
> new file mode 100644
> index 00000000000..56faf67fe57
> --- /dev/null
> +++ b/test/py/tests/vboot/sandbox-binman-ecdsa384.dts
> @@ -0,0 +1,24 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + binman {
> + filename = "sandbox.img";
> +
> + pre-load {
> + content = <&image>;
> + algo-name = "sha256,ecdsa384";
> + key-name = "dev.pem";
> + header-size = <4096>;
> + version = <1>;
> + };
> +
> + image: blob-ext {
> + filename = "test.fit";
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sandbox-binman-ecdsa521.dts b/test/py/tests/vboot/sandbox-binman-ecdsa521.dts
> new file mode 100644
> index 00000000000..8e2fc3de31d
> --- /dev/null
> +++ b/test/py/tests/vboot/sandbox-binman-ecdsa521.dts
> @@ -0,0 +1,24 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + #address-cells = <1>;
> + #size-cells = <1>;
> +
> + binman {
> + filename = "sandbox.img";
> +
> + pre-load {
> + content = <&image>;
> + algo-name = "sha256,ecdsa521";
> + key-name = "dev.pem";
> + header-size = <4096>;
> + version = <1>;
> + };
> +
> + image: blob-ext {
> + filename = "test.fit";
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sandbox-u-boot-global-ecdsa256.dts b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa256.dts
> new file mode 100644
> index 00000000000..f15ada3987c
> --- /dev/null
> +++ b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa256.dts
> @@ -0,0 +1,27 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + model = "Sandbox Verified Boot Test";
> + compatible = "sandbox";
> +
> + binman {
> + };
> +
> + reset@0 {
> + compatible = "sandbox,reset";
> + };
> +
> + image {
> + pre-load {
> + sig {
> + algo-name = "sha256,ecdsa256";
> + signature-size = <64>;
> + mandatory = "yes";
> +
> + key-name = "dev";
> + };
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sandbox-u-boot-global-ecdsa384.dts b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa384.dts
> new file mode 100644
> index 00000000000..24540ace249
> --- /dev/null
> +++ b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa384.dts
> @@ -0,0 +1,27 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + model = "Sandbox Verified Boot Test";
> + compatible = "sandbox";
> +
> + binman {
> + };
> +
> + reset@0 {
> + compatible = "sandbox,reset";
> + };
> +
> + image {
> + pre-load {
> + sig {
> + algo-name = "sha256,ecdsa384";
> + signature-size = <96>;
> + mandatory = "yes";
> +
> + key-name = "dev";
> + };
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sandbox-u-boot-global-ecdsa521.dts b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa521.dts
> new file mode 100644
> index 00000000000..72fa3b2c790
> --- /dev/null
> +++ b/test/py/tests/vboot/sandbox-u-boot-global-ecdsa521.dts
> @@ -0,0 +1,27 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +/dts-v1/;
> +
> +/ {
> + model = "Sandbox Verified Boot Test";
> + compatible = "sandbox";
> +
> + binman {
> + };
> +
> + reset@0 {
> + compatible = "sandbox,reset";
> + };
> +
> + image {
> + pre-load {
> + sig {
> + algo-name = "sha256,ecdsa521";
> + signature-size = <132>;
> + mandatory = "yes";
> +
> + key-name = "dev";
> + };
> + };
> + };
> +};
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 05/15] drivers: crypto: add software ecdsa support
2026-09-03 14:32 ` Raymond Mao
@ 2026-09-03 15:33 ` Raymond Mao
2026-09-03 18:33 ` Tom Rini
0 siblings, 1 reply; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 15:33 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe
On Thu, Sep 3, 2026 at 10:32 AM Raymond Mao <raymondmaoca@gmail.com> wrote:
>
> Hi Philippe,
>
> On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
> <philippe.reynes@softathome.com> wrote:
> >
> > Add a software ecdsa driver so it is
> > now possible to use ecdsa signature on
> > board without ecdsa hardware support.
> >
> > Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> > Reviewed-by: Simon Glass <sjg@chromium.org>
> > Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> > ---
> > v2:
> > - no change
> > v3:
> > - add depends on ECDSA_VERIFY to ECDSA_SW
> > - change sw_ecdsa_verify to ecdsa_hash_verify
> > - v4
> > - use ECDSA_MBEDTLS to build the driver
> > - clean include (change order)
> > v5:
> > - use $(PHASE_) in the Makefile for the driver
> > v6:
> > - remove include u-boot/ecdsa.h from ecdsa-sw.c
> > v7:
> > - no change
> > v8:
> > - no change
> > v9:
> > - no change
> >
> > drivers/crypto/Makefile | 1 +
> > drivers/crypto/ecdsa/Makefile | 6 ++++++
> > drivers/crypto/ecdsa/ecdsa-sw.c | 32 ++++++++++++++++++++++++++++++++
> > 3 files changed, 39 insertions(+)
> > create mode 100644 drivers/crypto/ecdsa/Makefile
> > create mode 100644 drivers/crypto/ecdsa/ecdsa-sw.c
> >
>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
>
Sorry, there is a new line at the end of the file. Please apply my tag
with this fixed.
Applying: drivers: crypto: add software ecdsa support
.git/rebase-apply/patch:89: new blank line at EOF.
+
warning: 1 line adds whitespace errors.
Thanks!
Regards,
Raymond
> Thanks!
> Regards,
> Raymond
>
> > diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
> > index e4a4482b7f3..8170e4cae9c 100644
> > --- a/drivers/crypto/Makefile
> > +++ b/drivers/crypto/Makefile
> > @@ -4,6 +4,7 @@
> > # http://www.samsung.com
> >
> > obj-$(CONFIG_EXYNOS_ACE_SHA) += ace_sha.o
> > +obj-$(CONFIG_ECDSA) += ecdsa/
> > obj-y += aes/
> > obj-y += rsa_mod_exp/
> > obj-y += fsl/
> > diff --git a/drivers/crypto/ecdsa/Makefile b/drivers/crypto/ecdsa/Makefile
> > new file mode 100644
> > index 00000000000..89be50824cb
> > --- /dev/null
> > +++ b/drivers/crypto/ecdsa/Makefile
> > @@ -0,0 +1,6 @@
> > +# SPDX-License-Identifier: GPL-2.0+
> > +#
> > +# Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
> > +#
> > +
> > +obj-$(CONFIG_$(PHASE_)ECDSA_VERIFY_MBEDTLS) += ecdsa-sw.o
> > diff --git a/drivers/crypto/ecdsa/ecdsa-sw.c b/drivers/crypto/ecdsa/ecdsa-sw.c
> > new file mode 100644
> > index 00000000000..2af1405f73b
> > --- /dev/null
> > +++ b/drivers/crypto/ecdsa/ecdsa-sw.c
> > @@ -0,0 +1,32 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * Copyright (C) 2026 Philippe Reynes <philippe.reynes@softathome.com>
> > + */
> > +#include <crypto/ecdsa-uclass.h>
> > +#include <crypto/internal/ecdsa.h>
> > +#include <dm.h>
> > +#include <linux/types.h>
> > +
> > +static int ops_sw_ecdsa_verify(__always_unused struct udevice *dev,
> > + const struct ecdsa_public_key *pubkey,
> > + const void *hash, size_t hash_len,
> > + const void *signature, size_t sig_len)
> > +{
> > + return ecdsa_hash_verify(pubkey, hash, hash_len, signature, sig_len);
> > +}
> > +
> > +static const struct ecdsa_ops sw_ecdsa_ops = {
> > + .verify = ops_sw_ecdsa_verify,
> > +};
> > +
> > +U_BOOT_DRIVER(sw_ecdsa) = {
> > + .name = "sw_ecdsa",
> > + .id = UCLASS_ECDSA,
> > + .ops = &sw_ecdsa_ops,
> > + .flags = DM_FLAG_PRE_RELOC,
> > +};
> > +
> > +U_BOOT_DRVINFO(sw_ecdsa) = {
> > + .name = "sw_ecdsa",
> > +};
> > +
> > --
> > 2.43.0
> >
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 07/15] test: py: vboot: prepare integration test for ecdsa
2026-09-03 8:16 ` [PATCH v9 07/15] test: py: vboot: prepare integration test for ecdsa Philippe Reynes
@ 2026-09-03 15:42 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 15:42 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> The vboot tests only consider rsa algo for signature.
> To prepare the integration of ecdsa test, the signature
> algo is now explicit.
>
> Reviewed-by: Simon Glass <simon.glass@canonical.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v2:
> - initial version
> v3:
> - no change
> v4:
> - no change
> v5:
> - no change
> v6:
> - no change
> v7:
> - no change
> v8:
> - no change
> v9:
> - some minor update to fix rebase on next
>
> test/py/tests/test_fit_ecdsa.py | 2 +-
> test/py/tests/test_vboot.py | 104 +++++++++---------
> ....its => sign-configs-sha1-rsa2048-pss.its} | 0
> ...sha1.its => sign-configs-sha1-rsa2048.its} | 0
> ... sign-configs-sha256-rsa2048-pss-prod.its} | 0
> ...ts => sign-configs-sha256-rsa2048-pss.its} | 0
> ...56.its => sign-configs-sha256-rsa2048.its} | 0
> ...84.its => sign-configs-sha384-rsa3072.its} | 0
> ...s.its => sign-images-sha1-rsa2048-pss.its} | 0
> ...-sha1.its => sign-images-sha1-rsa2048.its} | 0
> ...its => sign-images-sha256-rsa2048-pss.its} | 0
> ...256.its => sign-images-sha256-rsa2048.its} | 0
> ...384.its => sign-images-sha384-rsa3072.its} | 0
> 13 files changed, 54 insertions(+), 52 deletions(-)
> rename test/py/tests/vboot/{sign-configs-sha1-pss.its => sign-configs-sha1-rsa2048-pss.its} (100%)
> rename test/py/tests/vboot/{sign-configs-sha1.its => sign-configs-sha1-rsa2048.its} (100%)
> rename test/py/tests/vboot/{sign-configs-sha256-pss-prod.its => sign-configs-sha256-rsa2048-pss-prod.its} (100%)
> rename test/py/tests/vboot/{sign-configs-sha256-pss.its => sign-configs-sha256-rsa2048-pss.its} (100%)
> rename test/py/tests/vboot/{sign-configs-sha256.its => sign-configs-sha256-rsa2048.its} (100%)
> rename test/py/tests/vboot/{sign-configs-sha384.its => sign-configs-sha384-rsa3072.its} (100%)
> rename test/py/tests/vboot/{sign-images-sha1-pss.its => sign-images-sha1-rsa2048-pss.its} (100%)
> rename test/py/tests/vboot/{sign-images-sha1.its => sign-images-sha1-rsa2048.its} (100%)
> rename test/py/tests/vboot/{sign-images-sha256-pss.its => sign-images-sha256-rsa2048-pss.its} (100%)
> rename test/py/tests/vboot/{sign-images-sha256.its => sign-images-sha256-rsa2048.its} (100%)
> rename test/py/tests/vboot/{sign-images-sha384.its => sign-images-sha384-rsa3072.its} (100%)
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/test/py/tests/test_fit_ecdsa.py b/test/py/tests/test_fit_ecdsa.py
> index 3e816d68eb6..e59390374af 100644
> --- a/test/py/tests/test_fit_ecdsa.py
> +++ b/test/py/tests/test_fit_ecdsa.py
> @@ -102,7 +102,7 @@ def test_fit_ecdsa(ubman):
> with open(key_file, 'w') as f:
> f.write(key.export_key(format='PEM'))
>
> - assemble_fit_image(fit_file, f'{datadir}/sign-images-sha256.its', tempdir)
> + assemble_fit_image(fit_file, f'{datadir}/sign-images-sha256-rsa2048.its', tempdir)
>
> fit = SignableFitImage(ubman, fit_file)
> nodes = fit.find_signable_image_nodes()
> diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
> index e9259584e32..33cbcea5c24 100644
> --- a/test/py/tests/test_vboot.py
> +++ b/test/py/tests/test_vboot.py
> @@ -84,21 +84,21 @@ def make_fit(its, ubman, mkimage, dtc_args, datadir, fit):
> # Only run the full suite on a few combinations, since it doesn't add any more
> # test coverage.
> TESTDATA_IN = [
> - ['sha1-basic', 'sha1', '', None, False, True, False, False],
> - ['sha1-pad', 'sha1', '', '-E -p 0x10000', False, False, False, False],
> - ['sha1-pss', 'sha1', '-pss', None, False, False, False, False],
> - ['sha1-pss-pad', 'sha1', '-pss', '-E -p 0x10000', False, False, False, False],
> - ['sha256-basic', 'sha256', '', None, False, False, False, False],
> - ['sha256-pad', 'sha256', '', '-E -p 0x10000', False, False, False, False],
> - ['sha256-pss', 'sha256', '-pss', None, False, False, False, False],
> - ['sha256-pss-pad', 'sha256', '-pss', '-E -p 0x10000', False, False, False, False],
> - ['sha256-pss-required', 'sha256', '-pss', None, True, False, False, False],
> - ['sha256-pss-pad-required', 'sha256', '-pss', '-E -p 0x10000', True, True, False, False],
> - ['sha384-basic', 'sha384', '', None, False, False, False, False],
> - ['sha384-pad', 'sha384', '', '-E -p 0x10000', False, False, False, False],
> - ['algo-arg', 'algo-arg', '', '-o sha256,rsa2048', False, False, True, False],
> - ['sha256-global-sign', 'sha256', '', '', False, False, False, True],
> - ['sha256-global-sign-pss', 'sha256', '-pss', '', False, False, False, True],
> + ['sha1-basic', 'sha1', '-rsa2048', '', None, False, True, False, False],
> + ['sha1-pad', 'sha1', '-rsa2048', '', '-E -p 0x10000', False, False, False, False],
> + ['sha1-pss', 'sha1', '-rsa2048', '-pss', None, False, False, False, False],
> + ['sha1-pss-pad', 'sha1', '-rsa2048', '-pss', '-E -p 0x10000', False, False, False, False],
> + ['sha256-basic', 'sha256', '-rsa2048', '', None, False, False, False, False],
> + ['sha256-pad', 'sha256', '-rsa2048', '', '-E -p 0x10000', False, False, False, False],
> + ['sha256-pss', 'sha256', '-rsa2048', '-pss', None, False, False, False, False],
> + ['sha256-pss-pad', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', False, False, False, False],
> + ['sha256-pss-required', 'sha256', '-rsa2048', '-pss', None, True, False, False, False],
> + ['sha256-pss-pad-required', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', True, True, False, False],
> + ['sha384-basic', 'sha384', '-rsa3072', '', None, False, False, False, False],
> + ['sha384-pad', 'sha384', '-rsa3072', '', '-E -p 0x10000', False, False, False, False],
> + ['algo-arg', 'algo-arg', '', '', '-o sha256,rsa2048', False, False, True, False],
> + ['sha256-global-sign', 'sha256', '-rsa2048', '', '', False, False, False, True],
> + ['sha256-global-sign-pss', 'sha256', '-rsa2048', '-pss', '', False, False, False, True],
> ]
>
> # Mark all but the first test as slow, so they are not run with '-k not slow'
> @@ -111,9 +111,9 @@ TESTDATA += [pytest.param(*v, marks=pytest.mark.slow) for v in TESTDATA_IN[1:]]
> @pytest.mark.requiredtool('fdtget')
> @pytest.mark.requiredtool('fdtput')
> @pytest.mark.requiredtool('openssl')
> -@pytest.mark.parametrize("name,sha_algo,padding,sign_options,required,full_test,algo_arg,global_sign",
> +@pytest.mark.parametrize("name,sha_algo,sig_algo,padding,sign_options,required,full_test,algo_arg,global_sign",
> TESTDATA)
> -def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
> +def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
> full_test, algo_arg, global_sign):
> """Test verified boot signing with mkimage and verification with 'bootm'.
>
> @@ -287,7 +287,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
> utils.run_and_log(ubman, 'openssl req -batch -new -x509 -key %s%s.key '
> '-out %s%s.crt' % (tmpdir, name, tmpdir, name))
>
> - def test_with_algo(sha_algo, padding, sign_options):
> + def test_with_algo(sha_algo, sig_algo, padding, sign_options):
> """Test verified boot with the given hash algorithm.
>
> This is the main part of the test code. The same procedure is followed
> @@ -308,7 +308,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
>
> # Build the FIT, but don't sign anything yet
> ubman.log.action('%s: Test FIT with signed images' % sha_algo)
> - make_fit('sign-images-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> + make_fit('sign-images-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> run_bootm(sha_algo, 'unsigned images', ' - OK' if algo_arg else 'dev-', True)
>
> # Sign images with our dev keys
> @@ -319,7 +319,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
> dtc('sandbox-u-boot.dts', ubman, dtc_args, datadir, tmpdir, dtb)
>
> ubman.log.action('%s: Test FIT with signed configuration' % sha_algo)
> - make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> + make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> run_bootm(sha_algo, 'unsigned config', '%s+ OK' % ('sha256' if algo_arg else sha_algo), True)
>
> # Sign images with our dev keys
> @@ -390,7 +390,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
> run_bootm(sha_algo, 'evil clone', 'Bad Data Hash', False, efit)
>
> # Create a new properly signed fit and replace header bytes
> - make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> + make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> sign_fit(sha_algo, sign_options)
> bcfg = ubman.config.buildconfig
> max_size = int(bcfg.get('config_fit_signature_max_size', 0x10000000), 0)
> @@ -424,7 +424,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
>
> # Create a new properly signed fit and replace hashed-strings
> # size property
> - make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> + make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> sign_fit(sha_algo, sign_options)
> utils.run_and_log(ubman, 'fdtput -t x %s %s hashed-strings 0' %
> (fit, sig_node))
> @@ -448,7 +448,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
> 'Bad Data Hash', False)
> ubman.log.action('%s: Check in-bounds hashed-strings size' % sha_algo)
>
> - def test_required_key(sha_algo, padding, sign_options):
> + def test_required_key(sha_algo, sig_algo, padding, sign_options):
> """Test verified boot with the given hash algorithm.
>
> This function tests if U-Boot rejects an image when a required key isn't
> @@ -470,12 +470,12 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
>
> # Build the FIT with prod key (keys required) and sign it. This puts the
> # signature into sandbox-u-boot.dtb, marked 'required'
> - make_fit('sign-configs-%s%s-prod.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> + make_fit('sign-configs-%s%s%s-prod.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> sign_fit(sha_algo, sign_options)
>
> # Build the FIT with dev key (keys NOT required). This adds the
> # signature into sandbox-u-boot.dtb, NOT marked 'required'.
> - make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> + make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> sign_fit_norequire(sha_algo, sign_options)
>
> # So now sandbox-u-boot.dtb two signatures, for the prod and dev keys.
> @@ -487,7 +487,7 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
>
> # Build the FIT with dev key (keys required) and sign it. This puts the
> # signature into sandbox-u-boot.dtb, marked 'required'.
> - make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> + make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> sign_fit(sha_algo, sign_options)
>
> # Set the required-mode policy to "any".
> @@ -567,8 +567,9 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
> dtb = '%ssandbox-u-boot.dtb' % tmpdir
> sig_node = '/configurations/conf-1/signature'
>
> - create_rsa_pair('dev')
> - create_rsa_pair('prod')
> + if sig_algo == "-rsa2048" or sig_algo == "-rsa3072" or sig_algo == "":
> + create_rsa_pair('dev')
> + create_rsa_pair('prod')
>
> # Create a number kernel image with zeroes
> with open('%stest-kernel.bin' % tmpdir, 'wb') as fd:
> @@ -587,9 +588,9 @@ def test_vboot(ubman, name, sha_algo, padding, sign_options, required,
> if global_sign:
> test_global_sign(sha_algo, padding, sign_options)
> elif required:
> - test_required_key(sha_algo, padding, sign_options)
> + test_required_key(sha_algo, sig_algo, padding, sign_options)
> else:
> - test_with_algo(sha_algo, padding, sign_options)
> + test_with_algo(sha_algo, sig_algo, padding, sign_options)
> finally:
> # Go back to the original U-Boot with the correct dtb.
> ubman.config.dtb = old_dtb
> @@ -616,6 +617,7 @@ def test_vboot_ext_data_bounds(ubman):
> by U-Boot to hold public keys from the signing process.
> """
> sha_algo = 'sha256'
> + sig_algo = '-rsa2048'
>
> def run_bootm(test_type, expect_string):
> """Run a 'bootm' command in U-Boot and expect it to fail.
> @@ -684,7 +686,7 @@ def test_vboot_ext_data_bounds(ubman):
> sign_fit() overwrites the FIT, so a new one is built before each test
> case mutates its external-data properties.
> """
> - make_fit('sign-configs-%s.its' % sha_algo, ubman, mkimage, dtc_args,
> + make_fit('sign-configs-%s%s.its' % (sha_algo, sig_algo), ubman, mkimage, dtc_args,
> datadir, fit)
> sign_fit('-E')
>
> @@ -762,21 +764,21 @@ def test_vboot_ext_data_bounds(ubman):
>
>
> TESTDATA_IN = [
> - ['sha1-basic', 'sha1', '', None, False],
> - ['sha1-pad', 'sha1', '', '-E -p 0x10000', False],
> - ['sha1-pss', 'sha1', '-pss', None, False],
> - ['sha1-pss-pad', 'sha1', '-pss', '-E -p 0x10000', False],
> - ['sha256-basic', 'sha256', '', None, False],
> - ['sha256-pad', 'sha256', '', '-E -p 0x10000', False],
> - ['sha256-pss', 'sha256', '-pss', None, False],
> - ['sha256-pss-pad', 'sha256', '-pss', '-E -p 0x10000', False],
> - ['sha256-pss-required', 'sha256', '-pss', None, False],
> - ['sha256-pss-pad-required', 'sha256', '-pss', '-E -p 0x10000', False],
> - ['sha384-basic', 'sha384', '', None, False],
> - ['sha384-pad', 'sha384', '', '-E -p 0x10000', False],
> - ['algo-arg', 'algo-arg', '', '-o sha256,rsa2048', True],
> - ['sha256-global-sign', 'sha256', '', '', False],
> - ['sha256-global-sign-pss', 'sha256', '-pss', '', False],
> + ['sha1-basic', 'sha1', '-rsa2048', '', None, False],
> + ['sha1-pad', 'sha1', '-rsa2048', '', '-E -p 0x10000', False],
> + ['sha1-pss', 'sha1', '-rsa2048', '-pss', None, False],
> + ['sha1-pss-pad', 'sha1', '-rsa2048', '-pss', '-E -p 0x10000', False],
> + ['sha256-basic', 'sha256', '-rsa2048', '', None, False],
> + ['sha256-pad', 'sha256', '-rsa2048', '', '-E -p 0x10000', False],
> + ['sha256-pss', 'sha256', '-rsa2048', '-pss', None, False],
> + ['sha256-pss-pad', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', False],
> + ['sha256-pss-required', 'sha256', '-rsa2048', '-pss', None, False],
> + ['sha256-pss-pad-required', 'sha256', '-rsa2048' , '-pss', '-E -p 0x10000', False],
> + ['sha384-basic', 'sha384', '-rsa3072', '', None, False],
> + ['sha384-pad', 'sha384', '-rsa3072', '', '-E -p 0x10000', False],
> + ['algo-arg', 'algo-arg', '', '', '-o sha256,rsa2048', True],
> + ['sha256-global-sign', 'sha256', '-rsa2048', '', '', False],
> + ['sha256-global-sign-pss', 'sha256', '-rsa2048', '-pss', '', False],
> ]
>
> # Mark all but the first test as slow, so they are not run with '-k not slow'
> @@ -787,8 +789,8 @@ TESTDATA += [pytest.param(*v, marks=pytest.mark.slow) for v in TESTDATA_IN[1:]]
> @pytest.mark.buildconfigspec('fit_signature')
> @pytest.mark.requiredtool('dtc')
> @pytest.mark.requiredtool('openssl')
> -@pytest.mark.parametrize("name,sha_algo,padding,sign_options,algo_arg", TESTDATA)
> -def test_fdt_add_pubkey(ubman, name, sha_algo, padding, sign_options, algo_arg):
> +@pytest.mark.parametrize("name,sha_algo,sig_algo,padding,sign_options,algo_arg", TESTDATA)
> +def test_fdt_add_pubkey(ubman, name, sha_algo, sig_algo, padding, sign_options, algo_arg):
> """Test fdt_add_pubkey utility with bunch of different algo options."""
>
> def sign_fit(sha_algo, options):
> @@ -807,7 +809,7 @@ def test_fdt_add_pubkey(ubman, name, sha_algo, padding, sign_options, algo_arg):
> ubman.log.action('%s: Sign images' % sha_algo)
> utils.run_and_log(ubman, args)
>
> - def test_add_pubkey(sha_algo, padding, sign_options):
> + def test_add_pubkey(sha_algo, sig_algo, padding, sign_options):
> """Test fdt_add_pubkey utility with given hash algorithm and padding.
>
> This function tests if fdt_add_pubkey utility may add public keys into dtb.
> @@ -830,7 +832,7 @@ def test_fdt_add_pubkey(ubman, name, sha_algo, padding, sign_options, algo_arg):
> 'rsa3072' if sha_algo == 'sha384' else 'rsa2048'),
> '-k', tmpdir, '-n', 'dev', '-r', 'conf', dtb])
>
> - make_fit('sign-configs-%s%s.its' % (sha_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
> + make_fit('sign-configs-%s%s%s.its' % (sha_algo, sig_algo, padding), ubman, mkimage, dtc_args, datadir, fit)
>
> # Sign images with our dev keys
> sign_fit(sha_algo, sign_options)
> @@ -852,4 +854,4 @@ def test_fdt_add_pubkey(ubman, name, sha_algo, padding, sign_options, algo_arg):
>
> # keys created in test_vboot test
>
> - test_add_pubkey(sha_algo, padding, sign_options)
> + test_add_pubkey(sha_algo, sig_algo, padding, sign_options)
> diff --git a/test/py/tests/vboot/sign-configs-sha1-pss.its b/test/py/tests/vboot/sign-configs-sha1-rsa2048-pss.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-configs-sha1-pss.its
> rename to test/py/tests/vboot/sign-configs-sha1-rsa2048-pss.its
> diff --git a/test/py/tests/vboot/sign-configs-sha1.its b/test/py/tests/vboot/sign-configs-sha1-rsa2048.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-configs-sha1.its
> rename to test/py/tests/vboot/sign-configs-sha1-rsa2048.its
> diff --git a/test/py/tests/vboot/sign-configs-sha256-pss-prod.its b/test/py/tests/vboot/sign-configs-sha256-rsa2048-pss-prod.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-configs-sha256-pss-prod.its
> rename to test/py/tests/vboot/sign-configs-sha256-rsa2048-pss-prod.its
> diff --git a/test/py/tests/vboot/sign-configs-sha256-pss.its b/test/py/tests/vboot/sign-configs-sha256-rsa2048-pss.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-configs-sha256-pss.its
> rename to test/py/tests/vboot/sign-configs-sha256-rsa2048-pss.its
> diff --git a/test/py/tests/vboot/sign-configs-sha256.its b/test/py/tests/vboot/sign-configs-sha256-rsa2048.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-configs-sha256.its
> rename to test/py/tests/vboot/sign-configs-sha256-rsa2048.its
> diff --git a/test/py/tests/vboot/sign-configs-sha384.its b/test/py/tests/vboot/sign-configs-sha384-rsa3072.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-configs-sha384.its
> rename to test/py/tests/vboot/sign-configs-sha384-rsa3072.its
> diff --git a/test/py/tests/vboot/sign-images-sha1-pss.its b/test/py/tests/vboot/sign-images-sha1-rsa2048-pss.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-images-sha1-pss.its
> rename to test/py/tests/vboot/sign-images-sha1-rsa2048-pss.its
> diff --git a/test/py/tests/vboot/sign-images-sha1.its b/test/py/tests/vboot/sign-images-sha1-rsa2048.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-images-sha1.its
> rename to test/py/tests/vboot/sign-images-sha1-rsa2048.its
> diff --git a/test/py/tests/vboot/sign-images-sha256-pss.its b/test/py/tests/vboot/sign-images-sha256-rsa2048-pss.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-images-sha256-pss.its
> rename to test/py/tests/vboot/sign-images-sha256-rsa2048-pss.its
> diff --git a/test/py/tests/vboot/sign-images-sha256.its b/test/py/tests/vboot/sign-images-sha256-rsa2048.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-images-sha256.its
> rename to test/py/tests/vboot/sign-images-sha256-rsa2048.its
> diff --git a/test/py/tests/vboot/sign-images-sha384.its b/test/py/tests/vboot/sign-images-sha384-rsa3072.its
> similarity index 100%
> rename from test/py/tests/vboot/sign-images-sha384.its
> rename to test/py/tests/vboot/sign-images-sha384-rsa3072.its
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 08/15] test: vboot: add test for ecdsa
2026-09-03 8:16 ` [PATCH v9 08/15] test: vboot: add " Philippe Reynes
@ 2026-09-03 15:43 ` Raymond Mao
0 siblings, 0 replies; 36+ messages in thread
From: Raymond Mao @ 2026-09-03 15:43 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, trini, simon.glass, u-boot,
Simon Glass
Hi Philippe,
On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
<philippe.reynes@softathome.com> wrote:
>
> This commit adds test case for ecdsa on fit, but not (yet) for
> the global image signature (preload).
>
> Reviewed-by: Simon Glass <simon.glass@canonical.com>
> Reviewed-by: Simon Glass <sjg@chromium.org>
> Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> ---
> v2:
> - initial version
> v3:
> - no change
> v4:
> - no change
> v5:
> - no change
> v6:
> - no change
> v7:
> - no change
> v8:
> - no change
> v9:
> - some minor changes to fix rebase on next
>
> test/py/tests/test_vboot.py | 29 ++++++++++++
> .../vboot/sign-configs-sha256-ecdsa256.its | 44 +++++++++++++++++++
> .../vboot/sign-configs-sha256-ecdsa384.its | 44 +++++++++++++++++++
> .../vboot/sign-configs-sha256-ecdsa521.its | 44 +++++++++++++++++++
> .../vboot/sign-images-sha256-ecdsa256.its | 42 ++++++++++++++++++
> .../vboot/sign-images-sha256-ecdsa384.its | 42 ++++++++++++++++++
> .../vboot/sign-images-sha256-ecdsa521.its | 42 ++++++++++++++++++
> 7 files changed, 287 insertions(+)
> create mode 100644 test/py/tests/vboot/sign-configs-sha256-ecdsa256.its
> create mode 100644 test/py/tests/vboot/sign-configs-sha256-ecdsa384.its
> create mode 100644 test/py/tests/vboot/sign-configs-sha256-ecdsa521.its
> create mode 100644 test/py/tests/vboot/sign-images-sha256-ecdsa256.its
> create mode 100644 test/py/tests/vboot/sign-images-sha256-ecdsa384.its
> create mode 100644 test/py/tests/vboot/sign-images-sha256-ecdsa521.its
>
Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
Thanks!
Regards,
Raymond
> diff --git a/test/py/tests/test_vboot.py b/test/py/tests/test_vboot.py
> index 33cbcea5c24..89876ff030a 100644
> --- a/test/py/tests/test_vboot.py
> +++ b/test/py/tests/test_vboot.py
> @@ -94,6 +94,9 @@ TESTDATA_IN = [
> ['sha256-pss-pad', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', False, False, False, False],
> ['sha256-pss-required', 'sha256', '-rsa2048', '-pss', None, True, False, False, False],
> ['sha256-pss-pad-required', 'sha256', '-rsa2048', '-pss', '-E -p 0x10000', True, True, False, False],
> + ['sha256-basic-ecdsa256', 'sha256', '-ecdsa256', '', None, False, False, False, False],
> + ['sha256-basic-ecdsa384', 'sha256', '-ecdsa384', '', None, False, False, False, False],
> + ['sha256-basic-ecdsa521', 'sha256', '-ecdsa521', '', None, False, False, False, False],
> ['sha384-basic', 'sha384', '-rsa3072', '', None, False, False, False, False],
> ['sha384-pad', 'sha384', '-rsa3072', '', '-E -p 0x10000', False, False, False, False],
> ['algo-arg', 'algo-arg', '', '', '-o sha256,rsa2048', False, False, True, False],
> @@ -287,6 +290,29 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
> utils.run_and_log(ubman, 'openssl req -batch -new -x509 -key %s%s.key '
> '-out %s%s.crt' % (tmpdir, name, tmpdir, name))
>
> + def create_ecdsa_pair(name):
> + """Generate a new ECDSA key pair
> +
> + Args:
> + name: Name of the key (e.g. 'dev')
> + """
> +
> + if sig_algo == "-ecdsa256":
> + curve_name = "secp256r1"
> + elif sig_algo == "-ecdsa384":
> + curve_name = "secp384r1"
> + elif sig_algo == "-ecdsa521":
> + curve_name = "secp521r1"
> + else:
> + curve_name = "unknownCurve"
> +
> + utils.run_and_log(ubman, 'openssl ecparam -name %s -genkey -noout -out %s%s.pem' %
> + (curve_name, tmpdir, name))
> +
> + # Create a certificate containing the public key
> + utils.run_and_log(ubman, 'openssl req -batch -new -x509 -key %s%s.pem '
> + '-out %s%s.crt' % (tmpdir, name, tmpdir, name))
> +
> def test_with_algo(sha_algo, sig_algo, padding, sign_options):
> """Test verified boot with the given hash algorithm.
>
> @@ -570,6 +596,9 @@ def test_vboot(ubman, name, sha_algo, sig_algo, padding, sign_options, required,
> if sig_algo == "-rsa2048" or sig_algo == "-rsa3072" or sig_algo == "":
> create_rsa_pair('dev')
> create_rsa_pair('prod')
> + elif sig_algo == "-ecdsa256" or sig_algo == "-ecdsa384" or sig_algo == "-ecdsa521":
> + create_ecdsa_pair('dev')
> + create_ecdsa_pair('prod')
>
> # Create a number kernel image with zeroes
> with open('%stest-kernel.bin' % tmpdir, 'wb') as fd:
> diff --git a/test/py/tests/vboot/sign-configs-sha256-ecdsa256.its b/test/py/tests/vboot/sign-configs-sha256-ecdsa256.its
> new file mode 100644
> index 00000000000..6bd291a40c2
> --- /dev/null
> +++ b/test/py/tests/vboot/sign-configs-sha256-ecdsa256.its
> @@ -0,0 +1,44 @@
> +/dts-v1/;
> +
> +/ {
> + description = "Chrome OS kernel image with one or more FDT blobs";
> + #address-cells = <1>;
> +
> + images {
> + kernel {
> + data = /incbin/("test-kernel.bin");
> + type = "kernel_noload";
> + arch = "sandbox";
> + os = "linux";
> + compression = "none";
> + load = <0x4>;
> + entry = <0x8>;
> + kernel-version = <1>;
> + hash-1 {
> + algo = "sha256";
> + };
> + };
> + fdt-1 {
> + description = "snow";
> + data = /incbin/("sandbox-kernel.dtb");
> + type = "flat_dt";
> + arch = "sandbox";
> + compression = "none";
> + fdt-version = <1>;
> + hash-1 {
> + algo = "sha256";
> + };
> + };
> + };
> + configurations {
> + default = "conf-1";
> + conf-1 {
> + kernel = "kernel";
> + fdt = "fdt-1";
> + signature {
> + algo = "sha256,ecdsa256";
> + key-name-hint = "dev";
> + };
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sign-configs-sha256-ecdsa384.its b/test/py/tests/vboot/sign-configs-sha256-ecdsa384.its
> new file mode 100644
> index 00000000000..68c482acff2
> --- /dev/null
> +++ b/test/py/tests/vboot/sign-configs-sha256-ecdsa384.its
> @@ -0,0 +1,44 @@
> +/dts-v1/;
> +
> +/ {
> + description = "Chrome OS kernel image with one or more FDT blobs";
> + #address-cells = <1>;
> +
> + images {
> + kernel {
> + data = /incbin/("test-kernel.bin");
> + type = "kernel_noload";
> + arch = "sandbox";
> + os = "linux";
> + compression = "none";
> + load = <0x4>;
> + entry = <0x8>;
> + kernel-version = <1>;
> + hash-1 {
> + algo = "sha256";
> + };
> + };
> + fdt-1 {
> + description = "snow";
> + data = /incbin/("sandbox-kernel.dtb");
> + type = "flat_dt";
> + arch = "sandbox";
> + compression = "none";
> + fdt-version = <1>;
> + hash-1 {
> + algo = "sha256";
> + };
> + };
> + };
> + configurations {
> + default = "conf-1";
> + conf-1 {
> + kernel = "kernel";
> + fdt = "fdt-1";
> + signature {
> + algo = "sha256,ecdsa384";
> + key-name-hint = "dev";
> + };
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sign-configs-sha256-ecdsa521.its b/test/py/tests/vboot/sign-configs-sha256-ecdsa521.its
> new file mode 100644
> index 00000000000..f673accd39a
> --- /dev/null
> +++ b/test/py/tests/vboot/sign-configs-sha256-ecdsa521.its
> @@ -0,0 +1,44 @@
> +/dts-v1/;
> +
> +/ {
> + description = "Chrome OS kernel image with one or more FDT blobs";
> + #address-cells = <1>;
> +
> + images {
> + kernel {
> + data = /incbin/("test-kernel.bin");
> + type = "kernel_noload";
> + arch = "sandbox";
> + os = "linux";
> + compression = "none";
> + load = <0x4>;
> + entry = <0x8>;
> + kernel-version = <1>;
> + hash-1 {
> + algo = "sha256";
> + };
> + };
> + fdt-1 {
> + description = "snow";
> + data = /incbin/("sandbox-kernel.dtb");
> + type = "flat_dt";
> + arch = "sandbox";
> + compression = "none";
> + fdt-version = <1>;
> + hash-1 {
> + algo = "sha256";
> + };
> + };
> + };
> + configurations {
> + default = "conf-1";
> + conf-1 {
> + kernel = "kernel";
> + fdt = "fdt-1";
> + signature {
> + algo = "sha256,ecdsa521";
> + key-name-hint = "dev";
> + };
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sign-images-sha256-ecdsa256.its b/test/py/tests/vboot/sign-images-sha256-ecdsa256.its
> new file mode 100644
> index 00000000000..009003bb601
> --- /dev/null
> +++ b/test/py/tests/vboot/sign-images-sha256-ecdsa256.its
> @@ -0,0 +1,42 @@
> +/dts-v1/;
> +
> +/ {
> + description = "Chrome OS kernel image with one or more FDT blobs";
> + #address-cells = <1>;
> +
> + images {
> + kernel {
> + data = /incbin/("test-kernel.bin");
> + type = "kernel_noload";
> + arch = "sandbox";
> + os = "linux";
> + compression = "none";
> + load = <0x4>;
> + entry = <0x8>;
> + kernel-version = <1>;
> + signature {
> + algo = "sha256,ecdsa256";
> + key-name-hint = "dev";
> + };
> + };
> + fdt-1 {
> + description = "snow";
> + data = /incbin/("sandbox-kernel.dtb");
> + type = "flat_dt";
> + arch = "sandbox";
> + compression = "none";
> + fdt-version = <1>;
> + signature {
> + algo = "sha256,ecdsa256";
> + key-name-hint = "dev";
> + };
> + };
> + };
> + configurations {
> + default = "conf-1";
> + conf-1 {
> + kernel = "kernel";
> + fdt = "fdt-1";
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sign-images-sha256-ecdsa384.its b/test/py/tests/vboot/sign-images-sha256-ecdsa384.its
> new file mode 100644
> index 00000000000..567de687a06
> --- /dev/null
> +++ b/test/py/tests/vboot/sign-images-sha256-ecdsa384.its
> @@ -0,0 +1,42 @@
> +/dts-v1/;
> +
> +/ {
> + description = "Chrome OS kernel image with one or more FDT blobs";
> + #address-cells = <1>;
> +
> + images {
> + kernel {
> + data = /incbin/("test-kernel.bin");
> + type = "kernel_noload";
> + arch = "sandbox";
> + os = "linux";
> + compression = "none";
> + load = <0x4>;
> + entry = <0x8>;
> + kernel-version = <1>;
> + signature {
> + algo = "sha256,ecdsa384";
> + key-name-hint = "dev";
> + };
> + };
> + fdt-1 {
> + description = "snow";
> + data = /incbin/("sandbox-kernel.dtb");
> + type = "flat_dt";
> + arch = "sandbox";
> + compression = "none";
> + fdt-version = <1>;
> + signature {
> + algo = "sha256,ecdsa384";
> + key-name-hint = "dev";
> + };
> + };
> + };
> + configurations {
> + default = "conf-1";
> + conf-1 {
> + kernel = "kernel";
> + fdt = "fdt-1";
> + };
> + };
> +};
> diff --git a/test/py/tests/vboot/sign-images-sha256-ecdsa521.its b/test/py/tests/vboot/sign-images-sha256-ecdsa521.its
> new file mode 100644
> index 00000000000..74ed45b21b8
> --- /dev/null
> +++ b/test/py/tests/vboot/sign-images-sha256-ecdsa521.its
> @@ -0,0 +1,42 @@
> +/dts-v1/;
> +
> +/ {
> + description = "Chrome OS kernel image with one or more FDT blobs";
> + #address-cells = <1>;
> +
> + images {
> + kernel {
> + data = /incbin/("test-kernel.bin");
> + type = "kernel_noload";
> + arch = "sandbox";
> + os = "linux";
> + compression = "none";
> + load = <0x4>;
> + entry = <0x8>;
> + kernel-version = <1>;
> + signature {
> + algo = "sha256,ecdsa521";
> + key-name-hint = "dev";
> + };
> + };
> + fdt-1 {
> + description = "snow";
> + data = /incbin/("sandbox-kernel.dtb");
> + type = "flat_dt";
> + arch = "sandbox";
> + compression = "none";
> + fdt-version = <1>;
> + signature {
> + algo = "sha256,ecdsa521";
> + key-name-hint = "dev";
> + };
> + };
> + };
> + configurations {
> + default = "conf-1";
> + conf-1 {
> + kernel = "kernel";
> + fdt = "fdt-1";
> + };
> + };
> +};
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 05/15] drivers: crypto: add software ecdsa support
2026-09-03 15:33 ` Raymond Mao
@ 2026-09-03 18:33 ` Tom Rini
0 siblings, 0 replies; 36+ messages in thread
From: Tom Rini @ 2026-09-03 18:33 UTC (permalink / raw)
To: Raymond Mao
Cc: Philippe Reynes, marko.makela, jonny.green, simon.glass, u-boot,
Simon Glass
[-- Attachment #1: Type: text/plain, Size: 1915 bytes --]
On Thu, Sep 03, 2026 at 11:33:01AM -0400, Raymond Mao wrote:
> Hi Philippe
>
> On Thu, Sep 3, 2026 at 10:32 AM Raymond Mao <raymondmaoca@gmail.com> wrote:
> >
> > Hi Philippe,
> >
> > On Thu, Sep 3, 2026 at 4:17 AM Philippe Reynes
> > <philippe.reynes@softathome.com> wrote:
> > >
> > > Add a software ecdsa driver so it is
> > > now possible to use ecdsa signature on
> > > board without ecdsa hardware support.
> > >
> > > Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> > > Reviewed-by: Simon Glass <sjg@chromium.org>
> > > Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com>
> > > ---
> > > v2:
> > > - no change
> > > v3:
> > > - add depends on ECDSA_VERIFY to ECDSA_SW
> > > - change sw_ecdsa_verify to ecdsa_hash_verify
> > > - v4
> > > - use ECDSA_MBEDTLS to build the driver
> > > - clean include (change order)
> > > v5:
> > > - use $(PHASE_) in the Makefile for the driver
> > > v6:
> > > - remove include u-boot/ecdsa.h from ecdsa-sw.c
> > > v7:
> > > - no change
> > > v8:
> > > - no change
> > > v9:
> > > - no change
> > >
> > > drivers/crypto/Makefile | 1 +
> > > drivers/crypto/ecdsa/Makefile | 6 ++++++
> > > drivers/crypto/ecdsa/ecdsa-sw.c | 32 ++++++++++++++++++++++++++++++++
> > > 3 files changed, 39 insertions(+)
> > > create mode 100644 drivers/crypto/ecdsa/Makefile
> > > create mode 100644 drivers/crypto/ecdsa/ecdsa-sw.c
> > >
> >
> > Reviewed-by: Raymond Mao <raymondmaoca@gmail.com>
> >
>
> Sorry, there is a new line at the end of the file. Please apply my tag
> with this fixed.
>
> Applying: drivers: crypto: add software ecdsa support
> .git/rebase-apply/patch:89: new blank line at EOF.
> +
> warning: 1 line adds whitespace errors.
If there's nothing else to do for the series, you can fix that up when
applying. A v10 for just a spacing issue is a little excessive.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 00/15] add software ecdsa support
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
` (14 preceding siblings ...)
2026-09-03 8:17 ` [PATCH v9 15/15] test: py: vboot: add " Philippe Reynes
@ 2026-09-03 18:35 ` Tom Rini
2026-09-04 8:10 ` Philippe Reynes
15 siblings, 1 reply; 36+ messages in thread
From: Tom Rini @ 2026-09-03 18:35 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, raymondmaoca, simon.glass, u-boot
[-- Attachment #1: Type: text/plain, Size: 1720 bytes --]
On Thu, Sep 03, 2026 at 10:16:50AM +0200, Philippe Reynes wrote:
> This series adds the support of ecdsa with software
> using mbedtls. So boards without ecdsa hardware may
> also use signature with ecdsa.
>
> To achieve this goal, several changes are done:
> - fix the support of secp521r1
> - enable support of ecdsa in mbedtls
> - add software ecdsa signature check using mbedtls
> - add support of ecdsa for internal fit signature
> - add test for ecdsa for internal fit signature in vboot
> - add support of ecdsa for pre-load signature
> - add test for ecdsa for pre-load signature in vboot
> - enable software ecdsa signature check in sandbox
OK, so it's enabled on sandbox.
>
> To test this new feature, just follow those steps:
>
> 0) build u-boot using sandbox_defconfig and adding those options:
>
> CONFIG_ECDSA_MBEDTLS=y
> CONFIG_ECDSA_VERIFY_MBEDTLS=y
> CONFIG_ECDSA=y
> CONFIG_ECDSA_VERIFY=y
>
> 1) add a signature node to an its file
> signature-256 {
> algo = "sha256,ecdsa256";
> key-name-hint = "private-key-256";
> };
>
> 2) generate an ecdsa key
> openssl ecparam -name prime256v1 -genkey -noout -out private-key-256.pem
>
> 3) create the itb file
> ./tools/mkimage -f <file.its> -k . -K arch/sandbox/dts/test.dtb <file.itb>
>
> 4) launch sandbox u-boot
>
> ./u-boot -d arch/sandbox/dts/test.dtb
>
> 5) on sandbox u-boot prompt, load the itb and launch bootm on it
>
> => host load hostfs - 1000000 uboot-ecdsa.itb
> 4628674 bytes read in 1 ms (4.3 GiB/s)
> => bootm 1000000
> ...
> ...
> Verifying Hash Integrity ... sha256,ecdsa256:private-key-256+ OK
Does this mean the new tests aren't run automatically?
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 00/15] add software ecdsa support
2026-09-03 18:35 ` [PATCH v9 00/15] add software ecdsa support Tom Rini
@ 2026-09-04 8:10 ` Philippe Reynes
2026-09-04 14:32 ` Tom Rini
0 siblings, 1 reply; 36+ messages in thread
From: Philippe Reynes @ 2026-09-04 8:10 UTC (permalink / raw)
To: Tom Rini; +Cc: marko.makela, jonny.green, raymondmaoca, simon.glass, u-boot
Hi Tom,
Le 03/09/2026 à 20:35, Tom Rini a écrit :
> On Thu, Sep 03, 2026 at 10:16:50AM +0200, Philippe Reynes wrote:
>
>> This series adds the support of ecdsa with software
>> using mbedtls. So boards without ecdsa hardware may
>> also use signature with ecdsa.
>>
>> To achieve this goal, several changes are done:
>> - fix the support of secp521r1
>> - enable support of ecdsa in mbedtls
>> - add software ecdsa signature check using mbedtls
>> - add support of ecdsa for internal fit signature
>> - add test for ecdsa for internal fit signature in vboot
>> - add support of ecdsa for pre-load signature
>> - add test for ecdsa for pre-load signature in vboot
>> - enable software ecdsa signature check in sandbox
> OK, so it's enabled on sandbox.
>
>> To test this new feature, just follow those steps:
>>
>> 0) build u-boot using sandbox_defconfig and adding those options:
>>
>> CONFIG_ECDSA_MBEDTLS=y
>> CONFIG_ECDSA_VERIFY_MBEDTLS=y
>> CONFIG_ECDSA=y
>> CONFIG_ECDSA_VERIFY=y
>>
>> 1) add a signature node to an its file
>> signature-256 {
>> algo = "sha256,ecdsa256";
>> key-name-hint = "private-key-256";
>> };
>>
>> 2) generate an ecdsa key
>> openssl ecparam -name prime256v1 -genkey -noout -out private-key-256.pem
>>
>> 3) create the itb file
>> ./tools/mkimage -f <file.its> -k . -K arch/sandbox/dts/test.dtb <file.itb>
>>
>> 4) launch sandbox u-boot
>>
>> ./u-boot -d arch/sandbox/dts/test.dtb
>>
>> 5) on sandbox u-boot prompt, load the itb and launch bootm on it
>>
>> => host load hostfs - 1000000 uboot-ecdsa.itb
>> 4628674 bytes read in 1 ms (4.3 GiB/s)
>> => bootm 1000000
>> ...
>> ...
>> Verifying Hash Integrity ... sha256,ecdsa256:private-key-256+ OK
> Does this mean the new tests aren't run automatically?
The tests for software ecdsa are added in vboot, so they are run
automatically.
Ecdsa signature in fit and ecdsa signature in pre-load header are tested.
This last paragraph was for human being, to explain how to use it. Sorry if
this adds confusion.
Best regards,
Philippe
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v9 00/15] add software ecdsa support
2026-09-04 8:10 ` Philippe Reynes
@ 2026-09-04 14:32 ` Tom Rini
0 siblings, 0 replies; 36+ messages in thread
From: Tom Rini @ 2026-09-04 14:32 UTC (permalink / raw)
To: Philippe Reynes
Cc: marko.makela, jonny.green, raymondmaoca, simon.glass, u-boot
[-- Attachment #1: Type: text/plain, Size: 2328 bytes --]
On Fri, Sep 04, 2026 at 10:10:24AM +0200, Philippe Reynes wrote:
> Hi Tom,
>
> Le 03/09/2026 à 20:35, Tom Rini a écrit :
> > On Thu, Sep 03, 2026 at 10:16:50AM +0200, Philippe Reynes wrote:
> >
> > > This series adds the support of ecdsa with software
> > > using mbedtls. So boards without ecdsa hardware may
> > > also use signature with ecdsa.
> > >
> > > To achieve this goal, several changes are done:
> > > - fix the support of secp521r1
> > > - enable support of ecdsa in mbedtls
> > > - add software ecdsa signature check using mbedtls
> > > - add support of ecdsa for internal fit signature
> > > - add test for ecdsa for internal fit signature in vboot
> > > - add support of ecdsa for pre-load signature
> > > - add test for ecdsa for pre-load signature in vboot
> > > - enable software ecdsa signature check in sandbox
> > OK, so it's enabled on sandbox.
> >
> > > To test this new feature, just follow those steps:
> > >
> > > 0) build u-boot using sandbox_defconfig and adding those options:
> > >
> > > CONFIG_ECDSA_MBEDTLS=y
> > > CONFIG_ECDSA_VERIFY_MBEDTLS=y
> > > CONFIG_ECDSA=y
> > > CONFIG_ECDSA_VERIFY=y
> > >
> > > 1) add a signature node to an its file
> > > signature-256 {
> > > algo = "sha256,ecdsa256";
> > > key-name-hint = "private-key-256";
> > > };
> > >
> > > 2) generate an ecdsa key
> > > openssl ecparam -name prime256v1 -genkey -noout -out private-key-256.pem
> > >
> > > 3) create the itb file
> > > ./tools/mkimage -f <file.its> -k . -K arch/sandbox/dts/test.dtb <file.itb>
> > >
> > > 4) launch sandbox u-boot
> > >
> > > ./u-boot -d arch/sandbox/dts/test.dtb
> > >
> > > 5) on sandbox u-boot prompt, load the itb and launch bootm on it
> > >
> > > => host load hostfs - 1000000 uboot-ecdsa.itb
> > > 4628674 bytes read in 1 ms (4.3 GiB/s)
> > > => bootm 1000000
> > > ...
> > > ...
> > > Verifying Hash Integrity ... sha256,ecdsa256:private-key-256+ OK
> > Does this mean the new tests aren't run automatically?
> The tests for software ecdsa are added in vboot, so they are run
> automatically.
> Ecdsa signature in fit and ecdsa signature in pre-load header are tested.
> This last paragraph was for human being, to explain how to use it. Sorry if
> this adds confusion.
Ah, OK, thanks.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2026-09-04 14:33 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-03 8:16 [PATCH v9 00/15] add software ecdsa support Philippe Reynes
2026-09-03 8:16 ` [PATCH v9 01/15] ecdsa: fix support of secp521r1 Philippe Reynes
2026-09-03 14:30 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 02/15] mbedtls: enable support of ecc Philippe Reynes
2026-09-03 14:31 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 03/15] ecdsa: initial support of ecdsa using mbedtls Philippe Reynes
2026-09-03 14:31 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 04/15] test: lib: ecdsa: add initial test Philippe Reynes
2026-09-03 14:32 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 05/15] drivers: crypto: add software ecdsa support Philippe Reynes
2026-09-03 14:32 ` Raymond Mao
2026-09-03 15:33 ` Raymond Mao
2026-09-03 18:33 ` Tom Rini
2026-09-03 8:16 ` [PATCH v9 06/15] test: dm: ecdsa.c: clean this test as software ecdsa is now implemented Philippe Reynes
2026-09-03 14:33 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 07/15] test: py: vboot: prepare integration test for ecdsa Philippe Reynes
2026-09-03 15:42 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 08/15] test: vboot: add " Philippe Reynes
2026-09-03 15:43 ` Raymond Mao
2026-09-03 8:16 ` [PATCH v9 09/15] tools: fit_image_setup_sig: set required_keynode to -1 Philippe Reynes
2026-09-03 14:34 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 10/15] tools: mkimage: pre-load: add support of ecdsa Philippe Reynes
2026-09-03 14:36 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 11/15] tools: binman: " Philippe Reynes
2026-09-03 14:37 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 12/15] boot: " Philippe Reynes
2026-09-03 14:38 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 13/15] tools: preload_check_sign: " Philippe Reynes
2026-09-03 14:39 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 14/15] test: py: vboot: prepare test for global signature with ecdsa Philippe Reynes
2026-09-03 14:40 ` Raymond Mao
2026-09-03 8:17 ` [PATCH v9 15/15] test: py: vboot: add " Philippe Reynes
2026-09-03 14:41 ` Raymond Mao
2026-09-03 18:35 ` [PATCH v9 00/15] add software ecdsa support Tom Rini
2026-09-04 8:10 ` Philippe Reynes
2026-09-04 14:32 ` Tom Rini
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.