u-boot: signature check for u-boot scripts

Sean Anderson sean.anderson at seco.com
Tue Jan 10 17:27:57 CET 2023


On 1/10/23 08:18, Heiko Schocher wrote:
> Hello Simon,
> 
> I just digging into the topic "check a signed U-Boot script
> before sourcing it" ...
> 
> Therefore I have packed the U-Boot script into a FIT image
> and enabled FIT_SIGNATURE. In cmd/source.c
> 
> 136                 /* verify integrity */
> 137                 if (verify) {
> 138                         if (!fit_image_verify(fit_hdr, noffset)) {
> 139                                 puts ("Bad Data Hash\n");
> 140                                 return 1;
> 141                         }
> 142                 }
> 
> fit_image_verify() gets called which seems fine .. but
> fit_image_verify() always returns 0 ... and so, script gets always executed,
> also if I source a fitimage containing a script without *any* signature
> nodes, see [1]!
> 
> When I source a signed script and changing the hash before calling it,
> there is output [2] ... at least it shows "sha256,rsa2048:dev-" ... so
> correct detected, that hash is wrong ... but script gets executed...
> 
> comment in boot/image-fit.c fit_image_verify_with_data()
> """
> 1388                         /*
> 1389                          * Show an indication on failure, but do not return
> 1390                          * an error. Only keys marked 'required' can cause
> 1391                          * an image validation failure. See the call to
> 1392                          * fit_image_verify_required_sigs() above.
> 1393                          */
> """
> 
> Hmm... see dump of signature node from u-boot-dtb [3]
> 
> Hmm... It seems I miss something obvious?
> 
> BTW: checking signature of an fitimage (used for booting kernel/dts/ramdisk)
> works fine ...
> 
> May you have an its file as an example for creating a signed script?
> (But at least, it should not execute a script, without any signature info!)
> 
> Am I correct?
> 
> While writting this email ... in [3] the line
> 
>  require = "conf"
> 
> poped into my eyes .... and in fit_image_verify_required_sigs() there is check:
> 
>                 if (!required || strcmp(required, "image"))
>                         continue;
> 
> and yes! changing in [3]
> 
> -required = "conf";
> +required = "image";
> 
> makes sourcing the signed script working (error in case of no
> signature or wrong signature)! ... but booting the signed fitimage
> now breaks ... so it seems, I cannot use configuration signing with
> images signing ?
> 
> I tried to add two key nodes in signature node of u-boot dtb ... one with
> require = "conf" and one with require = "image" ... but no luck...
> 
> Also adding a configurations section to scripts its file did not helped
> (which will not prevent the problem sourcing a not signed script)

As you discovered, you must either have required = "image", in which case

    source :

will be secure. Otherwise, you must use

    source \#

Any other way is not secure.

--Sean

> Any ideas?
> 
> (In the meantime I mamanged to get it working, by adding also a configuration
>  node to my its file, and adding configuration parsing in cmd/source.c, see [4],
>  which solves all above problems ... but no idea if there is an eleganter
>  solution?)
> 
> Thanks!
> 
> bye,
> Heiko
> 
> [1] log (with some printfs in code)
> 
> => tftp 100000 script.bin;setenv verify 1;source 100000
> Speed: 1000, full duplex
> Using ethernet at 24000 device
> TFTP from server 192.168.3.1; our IP address is 192.168.3.40
> Filename 'script.bin'.
> Load address: 0x100000
> Loading: #
>          150.4 KiB/s
> done
> Bytes transferred = 464 (1d0 hex)
> ## Executing script at 00100000
> image_source_script: fit_uname: script-1
> fit_image_verify_with_data: ------------
> fit_image_verify_required_sigs: ------------ key_node: 96
> fit_image_verify_with_data: ------------ after fit_image_verify_required_sigs verify_all: 1
> fit_image_verify_with_data: ------------ name: hash-1 FIT_SIG_NODENAME: signature
> sha256+ Hallo from script
> => fdt addr 100000
> Working FDT set to 100000
> => fdt print
> / {
>         timestamp = <0x63bd2ea4>;
>         description = "Bootscript";
>         #address-cells = <0x00000001>;
>         images {
>                 default = "script-1";
>                 script-1 {
>                         data = "echo Hallo from script
> ";
>                         type = "script";
>                         compression = "none";
>                         hash-1 {
>                                 value = <0x4f9ef4c9 0x64b6027a 0xc0bf7019 0x2f21411f 0x3a03bb96
> 0x526e6cc0 0x172a6203 0x07ebd90e>;
>                                 algo = "sha256";
>                         };
>                 };
>         };
> };
> =>
> 
> [2] executing signed script but with changing hash
> 
> => tftp 100000 script.bin.signed;setenv verify 1;mw 001001c0 0 1;source 100000
> Speed: 1000, full duplex
> Using ethernet at 24000 device
> TFTP from server 192.168.3.1; our IP address is 192.168.3.40
> Filename 'script.bin.signed'.
> Load address: 0x100000
> Loading: #
>          230.5 KiB/s
> done
> Bytes transferred = 947 (3b3 hex)
> ## Executing script at 00100000
> image_source_script: fit_uname: script-1
> fit_image_verify_with_data: ------------
> fit_image_verify_required_sigs: ------------ key_node: 96
> fit_image_verify_with_data: ------------ after fit_image_verify_required_sigs verify_all: 1
> fit_image_verify_with_data: ------------ name: hash-1 FIT_SIG_NODENAME: signature
> sha256+ fit_image_verify_with_data: ------------ name: signature FIT_SIG_NODENAME: signature
> sha256,rsa2048:dev- Hallo from script
> =>
> => fdt addr 100000
> Working FDT set to 100000
> => fdt print
> / {
>         timestamp = <0x63bd4956>;
>         description = "Bootscript";
>         #address-cells = <0x00000001>;
>         images {
>                 default = "script-1";
>                 script-1 {
>                         data = "echo Hallo from script
> ";
>                         type = "script";
>                         compression = "none";
>                         hash-1 {
>                                 value = <0x4f9ef4c9 0x64b6027a 0xc0bf7019 0x2f21411f 0x3a03bb96
> 0x526e6cc0 0x172a6203 0x07ebd90e>;
>                                 algo = "sha256";
>                         };
>                         signature {
>                                 timestamp = <0x63bd4956>;
>                                 signer-version = "2023.01";
>                                 signer-name = "mkimage";
>                                 value = <0x2e93fd56 0xe68c3438 0x29440a3d 0x96a84453 0xfbf74c67
> 0x1ca47d4c 0xe712e5b0 0xa02a20ee 0xeda24836 0xab68efda 0xdae0e1a6 0x40b084e8 0x3adf3f72 0x977167dc
> 0x222b8897 0xb04323da 0x48b00d5a 0x00000000 0x23589310 0x8e5c84d1 0xf1b90ae0 0x37a96c48 0x1de295ed
> 0xdd02fbc4 0x7d97da60 0x2bfb9254 0xafff2fe9 0xb49034b5 0xc709f2aa 0xb7035c1c 0xc4219f9c 0x68f68b7d
> 0x8be03f02 0x83dc2a25 0x7b9056c0 0x1f6dbb5d 0xdc409948 0x9265fd61 0x10e78ef6 0xd7d6ba6a 0x0f45f622
> 0xaee09fee 0x65347dcd 0xbf1e640a 0x91f2aa7d 0x6a1aad9e 0x40edda89 0x7b4e1074 0xf0bda924 0xff8f95bf
> 0x6a743aa6 0x739cf6cc 0x77455534 0x958a79b0 0xf58a0f77 0x546d55ae 0xb4332204 0x2b69d4bf 0xcf2277b3
> 0xe6a5b9fa 0xbe0c2984 0x2a9b3a06 0xb1bfee79 0x1719227f>;
>                                 algo = "sha256,rsa2048";
>                                 key-name-hint = "dev";
>                                 sign-images = "script";
>                         };
>                 };
>         };
> };
> =>
> 
> [3] u-boot.dtb
>         signature {
> 
>                 key-dev {
>                         required = "conf";
>                         algo = "sha256,rsa2048";
>                         rsa,r-squared = < 0x4d76ec8 0x32c73f36 0x1885a88a 0x38c5f9da 0x76058623
> 0x144a9f4e 0x3b68693 0x12a3a7c3 0x63fe3d39 0x64050d31 0x3b4d47ec 0x43c0d6c0 0x5b473005 0x6ba07db0
> 0x834b69cf 0xc77d3d18 0x90a16449 0xca7ea292 0xbd5c7e8d 0xb12873b2 0xbd9854e6 0xa12bd2ca 0x49524aca
> 0x666fa5ad 0x60b46068 0xf8beb7 0x4f035cac 0x3d7f0d00 0x307cb78a 0xf7d69d41 0x4458b11e 0x796593b4
> 0x70f5d606 0x730a7eea 0xfacdf9c 0x944a88a0 0x91485179 0x86f28224 0xc753ad58 0xa108107c 0x7211253d
> 0x48c11ce4 0xaabdd41f 0x867090c 0x908feb8b 0x2eb6c136 0x723d4628 0xfa398444 0x5ce50ddc 0xf213d06e
> 0x5109ec8d 0xa7aa27ec 0x31877d93 0x140a82b8 0x5637d12e 0x1df9457d 0xfa461126 0x284b3222 0x40251e90
> 0x921ed1cb 0xeb1d610a 0xa4350b0a 0x35c82d04 0x6d1de495 >;
>                         rsa,modulus = < 0xb389fbdd 0xeac4c5c2 0xd5cdc76d 0x6bc8baef 0xcb1ccbb8
> 0xb045b4bc 0x61050af2 0x6fb72ee2 0x2cd1ebda 0x1935151a 0x1737507b 0xd99d7fcc 0xf7260741 0xcf27e93c
> 0x20e10005 0xa50b6358 0x6d5425d0 0x46668c49 0xa0e6d424 0x58be4ea2 0xd150aad9 0x15e48d65 0x96015d2e
> 0xf51eff2b 0x60490625 0xfa3e9e42 0x7c73be97 0x45e478be 0x52f57239 0x1682038d 0xd967dabc 0xafda9fd7
> 0xfe33a251 0xa5dc776c 0x966b36ab 0xeff0e172 0xdd3ab637 0xd061cbbd 0x5f498c4b 0xfdbb51df 0xb2dd74c4
> 0x98211ba0 0x3f711d0a 0xdf10c112 0x482ad0b2 0x7e48cea4 0x98ad8437 0x3aa3da75 0x3054d5fd 0x23c77cc5
> 0x3bc2ba2e 0x303d7d57 0x2a2d54e0 0xf740c870 0x1df2aca7 0x456dd158 0xe41796a 0xec9a7d09 0xad858e31
> 0xc95e53f9 0x5384346f 0x31f05039 0xe1121bd4 0x6c039a05 >;
>                         rsa,exponent = < 0x00 0x10001 >;
>                         rsa,n0-inverse = < 0x38aadd33 >;
>                         rsa,num-bits = < 0x800 >;
>                         key-name-hint = "dev";
>                 };
>         };
> 
> [4] hack to get signed scripts working
> diff --git a/cmd/source.c b/cmd/source.c
> index 698d9f86d9..c658a77ea3 100644
> --- a/cmd/source.c
> +++ b/cmd/source.c
> @@ -134,10 +134,23 @@ int image_source_script(ulong addr, const char *fit_uname)
> 
>                 /* verify integrity */
>                 if (verify) {
> +                       int cfg_noffset;
> +
>                         if (!fit_image_verify(fit_hdr, noffset)) {
>                                 puts ("Bad Data Hash\n");
>                                 return 1;
>                         }
> +
> +                       cfg_noffset = fdt_path_offset(fit_hdr, "/configurations/conf-1");
> +                       if (cfg_noffset < 0) {
> +                               puts("no config node\n");
> +                               return 1;
> +                       }
> +
> +                       if (fit_config_verify(fit_hdr, cfg_noffset)) {
> +                               puts("Bad Data Hash\n");
> +                               return 1;
> +                       }
>                 }
> 
>                 /* get script subimage data address and length */
> 
> [5] its file to get [4] working
> $ cat temp/script.its
> /dts-v1/;
> 
> / {
> 
>         description = "Bootscript";
>         #address-cells = <1>;
>         images {
>                 default = "script-1";
>                 script-1 {
>                         data = /incbin/("/work/big2/hs/temp/script.scr");
>                         type = "script";
>                         compression = "none";
>                         hash-1 {
>                                 algo = "sha256";
>                         };
>                 };
>         };
> 
>         configurations {
>                 default = "conf-1";
>                 conf-1 {
>                         description = "First signed script";
>                         script = "script-1";
>                         signature {
>                                 algo = "sha256,rsa2048";
>                                 key-name-hint = "dev";
>                                 sign-images = "script";
>                         };
>                 };
>         };
> };



More information about the U-Boot mailing list