1

I'm trying to use ECDSA (prime256v1) for signature verification in U-Boot (git tag "v2025.10"). I used the sample configuration from Verified Boot on the Beaglebone Black as a template. When using RSA-2048 to sign the FIT in u-boot, everything works as expected; booting with RSA signed image boots fine, but ECDSA signed image fails to boot as expected.

I copied the working RSA FIT its file and renamed it to "ec256fit.its"; I then modified the algo and key-name-hint fields for ECDSA:

/dts-v1/;

/ {
    description = "Simple image with single Linux kernel and FDT blob";
    #address-cells = <1>;

    images {
        kernel {
            description = "Linux kernel";
            data = /incbin/("./zImage");
            type = "kernel";
            arch = "arm";
            os = "linux";
            compression = "none";
            load = <0x60100000>;
            entry = <0x60100000>;
            hash-1 {
                algo = "sha256";
            };
        };
        fdt-1 {
            description = "Flattened Device Tree blob";
            data = /incbin/("./vexpress-v2p-ca9.dtb");
            type = "flat_dt";
            arch = "arm";
            compression = "none";
            hash-1 {
                algo = "sha256";
            };
        };
    };

    configurations {
        default = "conf-1";
        conf-1 {
            description = "Boot Linux kernel with FDT blob";
            kernel = "kernel";
            fdt = "fdt-1";
            signature-1 {
                algo = "sha256,ecdsa256";
                key-name-hint = "ec256"; 
                sign-images = "fdt", "kernel";
            };            
        };
    };
};

I generated ECDSA keys using openssl:

openssl ecparam -name prime256v1 -genkey -out $KEY_DIR/ec256.key
openssl req -batch -new -x509 -key $KEY_DIR/ec256.key -out $KEY_DIR/ec256.crt

I then signed the image:

$UBOOT_DIR/tools/mkimage -f $IMAGE_DIR/fit/ec256fit.its -K $IMAGE_DIR/fit/vexpress-v2p-ca9-pub-ec256.dtb -k $KEY_DIR -r $IMAGE_DIR/fit/ec256signed.fit
Can not get key file '/home/james/Projects/system/images/keys/ec256.pem'
Failed to sign 'signature-1' signature node in 'conf-1' conf node

mkimage complained about not finding ec256.pem, so I created a symlink to ec256.key and ran mkimage again; this time no warnings or errors.

$  $UBOOT_DIR/tools/mkimage -f $IMAGE_DIR/fit/ec256fit.its -K $IMAGE_DIR/fit/vexpress-v2p-ca9-pub-ec256.dtb -k $KEY_DIR -r $IMAGE_DIR/fit/ec256signed.fit                        
FIT description: Simple image with single Linux kernel and FDT blob
Created:         Thu Nov 20 12:35:56 2025
 Image 0 (kernel)
  Description:  Linux kernel
  Created:      Thu Nov 20 12:35:56 2025
  Type:         Kernel Image
  Compression:  uncompressed
  Data Size:    5818864 Bytes = 5682.48 KiB = 5.55 MiB
  Architecture: ARM
  OS:           Linux
  Load Address: 0x60100000
  Entry Point:  0x60100000
  Hash algo:    sha256
  Hash value:   112939b1e0884ac2e09ca11e6d5f9bf541b2cf3f7dd3a0e4259d5696caa7ebc0
 Image 1 (fdt-1)
  Description:  Flattened Device Tree blob
  Created:      Thu Nov 20 12:35:56 2025
  Type:         Flat Device Tree
  Compression:  uncompressed
  Data Size:    13728 Bytes = 13.41 KiB = 0.01 MiB
  Architecture: ARM
  Hash algo:    sha256
  Hash value:   cc8806f7514eaf6e313bc0ac0f7758361a8ebd6ddb2ecb926047952eb252c762
 Default Configuration: 'conf-1'
 Configuration 0 (conf-1)
  Description:  Boot Linux kernel with FDT blob
  Kernel:       kernel
  FDT:          fdt-1
  Sign algo:    sha256,ecdsa256:ec256
  Sign value:   533a1b08715c7d63e15e56d6195ea26144f7a08403793445b26524ff6db2d79942a52f75e0c82110d59846ef235278ccc3aa012ff3af1e825a365047d5782cad
  Timestamp:    Thu Nov 20 12:35:56 2025
Signature written to '/home/james/Projects/system/images/fit/ec256signed.fit', node '/configurations/conf-1/signature-1'
Public key written to '/home/james/Projects/system/images/fit/vexpress-v2p-ca9-pub-ec256.dtb', node '/signature/ec256'

It stated that the signature has been written to "ec256signed.fit" in node "/configurations/conf-1/signature-1" and the public key to "vexpress-v2p-ca9-pub-ec256.dtb". I verified that the public key was indeed in the dtb file by decompiling it into dts file:

...
    signature {

        ec256 {
            required = "conf";
            algo = "sha256,ecdsa256";
            ecdsa,y-point = <0x3cf7b533 0x15e22ecd 0xa183a2d5 0x59504031 0x42ba7cbb 0xfd30b358 0x7d1820fb 0xee2587b>;
            ecdsa,x-point = <0x86e2a451 0x12d94ee2 0x20c481c3 0x13fcfab3 0x3694b8e0 0x52d8a2aa 0xf2de6cd1 0x18377409>;
            ecdsa,curve = "prime256v1";
            key-name-hint = "ec256";
        };
    };
...

I verified the signed image:

$UBOOT_DIR/tools/fit_check_sign -f $IMAGE_DIR/fit/ec256signed.fit -k $IMAGE_DIR/fit/vexpress-v2p-ca9-pub-ec256.dtb                                                   
Loading ECDSA key: curve=prime256v1, bits=256
Successfully loaded ECDSA key from FDT node 172
Verifying Hash Integrity for node 'conf-1'... sha256,ecdsa256:ec256+ 
Verified OK, loading images
## Loading kernel (any) from FIT Image at 7163ca400000 ...
   Using 'conf-1' configuration
   Verifying Hash Integrity ... 
Loading ECDSA key: curve=prime256v1, bits=256
Successfully loaded ECDSA key from FDT node 172
sha256,ecdsa256:ec256+ 
OK

   Trying 'kernel' kernel subimage
     Description:  Linux kernel
     Created:      Thu Nov 20 12:35:56 2025
     Type:         Kernel Image
     Compression:  uncompressed
     Data Size:    5818864 Bytes = 5682.48 KiB = 5.55 MiB
     Architecture: ARM
     OS:           Linux
     Load Address: 0x60100000
     Entry Point:  0x60100000
     Hash algo:    sha256
     Hash value:   112939b1e0884ac2e09ca11e6d5f9bf541b2cf3f7dd3a0e4259d5696caa7ebc0
   Verifying Hash Integrity ... 
sha256+ 
OK

   Decrypting Data ... 
OK

   Loading Kernel Image to 0
## Loading fdt (any) from FIT Image at 7163ca400000 ...
   Using 'conf-1' configuration
   Verifying Hash Integrity ... 
Loading ECDSA key: curve=prime256v1, bits=256
Successfully loaded ECDSA key from FDT node 172
sha256,ecdsa256:ec256+ 
OK

   Trying 'fdt-1' fdt subimage
     Description:  Flattened Device Tree blob
     Created:      Thu Nov 20 12:35:56 2025
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Size:    13728 Bytes = 13.41 KiB = 0.01 MiB
     Architecture: ARM
     Hash algo:    sha256
     Hash value:   cc8806f7514eaf6e313bc0ac0f7758361a8ebd6ddb2ecb926047952eb252c762
   Verifying Hash Integrity ... 
sha256+ 
OK

   Decrypting Data ... 
OK

   Loading Flat Device Tree to 0
## Loading ramdisk (any) from FIT Image at 7163ca400000 ...
   Using 'conf-1' configuration
   Verifying Hash Integrity ... 
Loading ECDSA key: curve=prime256v1, bits=256
Successfully loaded ECDSA key from FDT node 172
sha256,ecdsa256:ec256+ 
OK

Could not find subimage node type 'ramdisk'
Signature check OK

No error was reported, so I rebuilt the U-Boot using the checked dtb:

make clean && make O=b/vexpress_ca9x4 EXT_DTB=${IMAGE_DIR}/fit/vexpress-v2p-ca9-pub-ec256.dtb

The U-Boot .config file is as follows:

CONFIG_ECDSA=y
CONFIG_ECDSA_VERIFY=y
CONFIG_RSA=y
CONFIG_RSA_VERIFY=y
CONFIG_SHA256=y
CONFIG_FIT_VERBOSE=y
CONFIG_OF_LIBFDT=y
CONFIG_FIT=y
CONFIG_FIT_ENABLE_SHA256_SUPPORT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_OF_CONTROL=y

When I tried to load the signed image, I get the following error:

> load mmc 0:1 ${loadaddr} ec256signed.fit
5834321 bytes read in 2109 ms (2.6 MiB/s)
=> iminfo ${loadaddr}

## Checking Image at 61000000 ...
   FIT image found
   FIT description: Simple image with single Linux kernel and FDT blob
    Image 0 (kernel)
     Description:  Linux kernel
     Type:         Kernel Image
     Compression:  uncompressed
     Data Start:   0x610000e0
     Data Size:    5818864 Bytes = 5.5 MiB
     Architecture: ARM
     OS:           Linux
     Load Address: 0x60100000
     Entry Point:  0x60100000
     Hash algo:    sha256
     Hash value:   112939b1e0884ac2e09ca11e6d5f9bf541b2cf3f7dd3a0e4259d5696caa7ebc0
    Image 1 (fdt-1)
     Description:  Flattened Device Tree blob
     Type:         Flat Device Tree
     Compression:  uncompressed
     Data Start:   0x6158cbd0
     Data Size:    13728 Bytes = 13.4 KiB
     Architecture: ARM
     Hash algo:    sha256
     Hash value:   cc8806f7514eaf6e313bc0ac0f7758361a8ebd6ddb2ecb926047952eb252c762
    Default Configuration: 'conf-1'
    Configuration 0 (conf-1)
     Description:  Boot Linux kernel with FDT blob
     Kernel:       kernel
     FDT:          fdt-1
     Sign algo:    sha256,ecdsa256:ec256
     Sign value:   533a1b08715c7d63e15e56d6195ea26144f7a08403793445b26524ff6db2d79942a52f75e0c82110d59846ef235278ccc3aa012ff3af1e825a365047d5782cad
## Checking hash(es) for FIT Image at 61000000 ...
   Hash(es) for Image 0 (kernel): sha256+ 
   Hash(es) for Image 1 (fdt-1): sha256+ 

=> bootm ${loadaddr}
## Loading kernel (any) from FIT Image at 61000000 ...
   Using 'conf-1' configuration
   Verifying Hash Integrity ... sha256,ecdsa256:ec256-  error!
Verification failed for '<NULL>' hash node in 'conf-1' config node
Failed to verify required signature 'ec256'
Bad Data Hash
ERROR -2: can't get kernel image!

I can no longer boot using the RSA signed image; this implies that the public key and signatures have been updated in the U-Boot as well. The iminfo command shows the signature value that matches the signature from fit_check_sign command. Seems like the fit image file contains the signature, but U-Boot is unable to verify it because the public key wasn't extracted from the dtb file when I rebuilt U-Boot.

1 Answer 1

0

Looks like U-Boot does not support ECDSA signature verification. I looked at the source code and the signature verification is not included on the target device; only the host tools (mkimage/fit_check_sign) supports ECDSA via Openssl. So you can sign and verify on the host, but when you load the U-Boot image on the board, signature verification will fail.

I wish the document had made this clear rather than implying that ECDSA signature verification is available by stating that x and y values for ECDSA is required for signature.

New contributor
James is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.