u-boot: signature check for u-boot scripts

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)
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@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@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"; }; }; }; };

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@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@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"; }; }; };
};

Hello Sean,
Thanks for your answer!
On 10.01.23 17:27, Sean Anderson wrote:
On 1/10/23 08:18, Heiko Schocher wrote:
Hello Simon,
[...]
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.
My "hack" checks a configuration signature in fitimage with script in it... so also "secure" ...
BTW: why we need a env variable to enable checking in cmd/source.c? I would say, if verify fit images is enabled we always should check signature ... but this is another question...
So I tried your suggestion:
=> tftp 100000 script.bin.signed;setenv verify 1;source #100000 Speed: 1000, full duplex Using ethernet@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: # 233.4 KiB/s done Bytes transferred = 1679 (68f hex) ## Executing script at 00000000 Wrong image format for "source" command =>
same for
=> source #100000:script-1 ## Executing script at 00000000 Wrong image format for "source" command =>
Which is the error message from the switch in image_source_script() from cmd/source.c ...
(check if fitimage "is okay"): => source 100000 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-2 ## Executing script at 00100000 Can't find 'script-2' FIT subimage =>
and changing hash in fitimages signature leads to: => mw 1001c0 0 1 => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev- Hallo from script =>
As I described ... problem "hash is detected, but script is executed", as public key in u-boots dtb has required = "conf"; (as it is used also for fitimage boot, where we use conf signing)
May you have an example (u-boot.dtb, its and complete working command for a signed fitimage script)?
The main problem is (I think) that we check for fitimages which are used for booting kernels, a "signed configuration" and in fitimage for scripts only "image" signatures ... and a combination of both is not possible (except I also sign the image nodes in kernel fitimage too ... which than leads in checking configuration signature and image signature on boot... but may a way to go (and disabling hash check) ?
bye, Heiko

On 1/11/23 01:13, Heiko Schocher wrote:
Hello Sean,
Thanks for your answer!
On 10.01.23 17:27, Sean Anderson wrote:
On 1/10/23 08:18, Heiko Schocher wrote:
Hello Simon,
[...]
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.
My "hack" checks a configuration signature in fitimage with script in it... so also "secure" ...
BTW: why we need a env variable to enable checking in cmd/source.c? I would say, if verify fit images is enabled we always should check signature ... but this is another question...
I think it's to allow disabling things for debugging. If the variable does not exist, it defaults to verifying.
So I tried your suggestion:
=> tftp 100000 script.bin.signed;setenv verify 1;source #100000 Speed: 1000, full duplex Using ethernet@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: # 233.4 KiB/s done Bytes transferred = 1679 (68f hex) ## Executing script at 00000000 Wrong image format for "source" command =>
same for
=> source #100000:script-1 ## Executing script at 00000000 Wrong image format for "source" command =>
Which is the error message from the switch in image_source_script() from cmd/source.c ...
Right.
What kind of image is your script? Do you have CONFIG_FIT (and *only* CONFIG_FIT) enabled?
(check if fitimage "is okay"): => source 100000 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-2 ## Executing script at 00100000 Can't find 'script-2' FIT subimage =>
and changing hash in fitimages signature leads to: => mw 1001c0 0 1 => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev- Hallo from script =>
As I described ... problem "hash is detected, but script is executed", as public key in u-boots dtb has required = "conf"; (as it is used also for fitimage boot, where we use conf signing)
May you have an example (u-boot.dtb, its and complete working command for a signed fitimage script)?
$ cat << EOF >> dm-verity.its /dts-v1/;
/ { description = "dm-verity boot parameters"; #address-cells = <1>;
images { dm-verity { data = /incbin/("dm-verity.scr"); type = "script"; arch = "arm64"; compression = "none"; hash-1 { algo = "sha256"; }; }; };
configurations { default = "conf"; conf { description = "Load dm-verity boot parameters"; script = "dm-verity"; signature { algo = "sha256,rsa2048"; key-name-hint = "u-boot"; sign-images = "script"; }; }; }; }; EOF $ uboot-mkimage -EB 0x40 -f dm-verity.its dm-verity.itb $ uboot-mkimage -EB 0x40 -r -F -k /path/to/keys dm-verity.itb
The main problem is (I think) that we check for fitimages which are used for booting kernels, a "signed configuration" and in fitimage for scripts only "image" signatures ... and a combination of both is not possible (except I also sign the image nodes in kernel fitimage too ... which than leads in checking configuration signature and image signature on boot... but may a way to go (and disabling hash check) ?
Yes, which is why you need to have # in the source command to force only using configurations. IMO we should also check image-only FITs, but Simon disagrees.
--Sean

Hi,
On Thu, 12 Jan 2023 at 09:03, Sean Anderson sean.anderson@seco.com wrote:
On 1/11/23 01:13, Heiko Schocher wrote:
Hello Sean,
Thanks for your answer!
On 10.01.23 17:27, Sean Anderson wrote:
On 1/10/23 08:18, Heiko Schocher wrote:
Hello Simon,
[...]
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.
My "hack" checks a configuration signature in fitimage with script in it... so also "secure" ...
BTW: why we need a env variable to enable checking in cmd/source.c? I would say, if verify fit images is enabled we always should check signature ... but this is another question...
I think it's to allow disabling things for debugging. If the variable does not exist, it defaults to verifying.
So I tried your suggestion:
=> tftp 100000 script.bin.signed;setenv verify 1;source #100000 Speed: 1000, full duplex Using ethernet@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: # 233.4 KiB/s done Bytes transferred = 1679 (68f hex) ## Executing script at 00000000 Wrong image format for "source" command =>
same for
=> source #100000:script-1 ## Executing script at 00000000 Wrong image format for "source" command =>
Which is the error message from the switch in image_source_script() from cmd/source.c ...
Right.
What kind of image is your script? Do you have CONFIG_FIT (and *only* CONFIG_FIT) enabled?
(check if fitimage "is okay"): => source 100000 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-2 ## Executing script at 00100000 Can't find 'script-2' FIT subimage =>
and changing hash in fitimages signature leads to: => mw 1001c0 0 1 => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev- Hallo from script =>
As I described ... problem "hash is detected, but script is executed", as public key in u-boots dtb has required = "conf"; (as it is used also for fitimage boot, where we use conf signing)
May you have an example (u-boot.dtb, its and complete working command for a signed fitimage script)?
$ cat << EOF >> dm-verity.its /dts-v1/;
/ { description = "dm-verity boot parameters"; #address-cells = <1>;
images { dm-verity { data = /incbin/("dm-verity.scr"); type = "script"; arch = "arm64"; compression = "none"; hash-1 { algo = "sha256"; }; }; }; configurations { default = "conf"; conf { description = "Load dm-verity boot parameters"; script = "dm-verity"; signature { algo = "sha256,rsa2048"; key-name-hint = "u-boot"; sign-images = "script"; }; }; };
}; EOF $ uboot-mkimage -EB 0x40 -f dm-verity.its dm-verity.itb $ uboot-mkimage -EB 0x40 -r -F -k /path/to/keys dm-verity.itb
The main problem is (I think) that we check for fitimages which are used for booting kernels, a "signed configuration" and in fitimage for scripts only "image" signatures ... and a combination of both is not possible (except I also sign the image nodes in kernel fitimage too ... which than leads in checking configuration signature and image signature on boot... but may a way to go (and disabling hash check) ?
Yes, which is why you need to have # in the source command to force only using configurations. IMO we should also check image-only FITs, but Simon disagrees.
I'm not sure what I disagree with, exactly. Signing images leaves one open to a mix-and-match attack, so I believe it is better to put the script into the config so it is signed along with the kernel, etc. But I am fine with us supporting signed images containing scripts...in fact I thought we already did?
Regards, Simon

Hello Simon,
On 13.01.23 00:43, Simon Glass wrote:
Hi,
On Thu, 12 Jan 2023 at 09:03, Sean Anderson sean.anderson@seco.com wrote:
On 1/11/23 01:13, Heiko Schocher wrote:
Hello Sean,
Thanks for your answer!
On 10.01.23 17:27, Sean Anderson wrote:
On 1/10/23 08:18, Heiko Schocher wrote:
Hello Simon,
[...]
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.
My "hack" checks a configuration signature in fitimage with script in it... so also "secure" ...
BTW: why we need a env variable to enable checking in cmd/source.c? I would say, if verify fit images is enabled we always should check signature ... but this is another question...
I think it's to allow disabling things for debugging. If the variable does not exist, it defaults to verifying.
So I tried your suggestion:
=> tftp 100000 script.bin.signed;setenv verify 1;source #100000 Speed: 1000, full duplex Using ethernet@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: # 233.4 KiB/s done Bytes transferred = 1679 (68f hex) ## Executing script at 00000000 Wrong image format for "source" command =>
same for
=> source #100000:script-1 ## Executing script at 00000000 Wrong image format for "source" command =>
Which is the error message from the switch in image_source_script() from cmd/source.c ...
Right.
What kind of image is your script? Do you have CONFIG_FIT (and *only* CONFIG_FIT) enabled?
(check if fitimage "is okay"): => source 100000 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-2 ## Executing script at 00100000 Can't find 'script-2' FIT subimage =>
and changing hash in fitimages signature leads to: => mw 1001c0 0 1 => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev- Hallo from script =>
As I described ... problem "hash is detected, but script is executed", as public key in u-boots dtb has required = "conf"; (as it is used also for fitimage boot, where we use conf signing)
May you have an example (u-boot.dtb, its and complete working command for a signed fitimage script)?
$ cat << EOF >> dm-verity.its /dts-v1/;
/ { description = "dm-verity boot parameters"; #address-cells = <1>;
images { dm-verity { data = /incbin/("dm-verity.scr"); type = "script"; arch = "arm64"; compression = "none"; hash-1 { algo = "sha256"; }; }; }; configurations { default = "conf"; conf { description = "Load dm-verity boot parameters"; script = "dm-verity"; signature { algo = "sha256,rsa2048"; key-name-hint = "u-boot"; sign-images = "script"; }; }; };
}; EOF $ uboot-mkimage -EB 0x40 -f dm-verity.its dm-verity.itb $ uboot-mkimage -EB 0x40 -r -F -k /path/to/keys dm-verity.itb
The main problem is (I think) that we check for fitimages which are used for booting kernels, a "signed configuration" and in fitimage for scripts only "image" signatures ... and a combination of both is not possible (except I also sign the image nodes in kernel fitimage too ... which than leads in checking configuration signature and image signature on boot... but may a way to go (and disabling hash check) ?
Yes, which is why you need to have # in the source command to force only using configurations. IMO we should also check image-only FITs, but Simon disagrees.
I'm not sure what I disagree with, exactly. Signing images leaves one open to a mix-and-match attack, so I believe it is better to put the script into the config so it is signed along with the kernel, etc. But I am fine with us supporting signed images containing scripts...in fact I thought we already did?
If you have a fitimage with only one script image ... it is a little bit overhead to need also a configurations section ... I made this mistake ...
I have a public key in u-boot.dtb which has 'required = "conf";' so only bad signed "configurations" are stopped from booting or in case of script from sourcing ... a bad signed fitimage with only signed images still gets executed ... also a not signed fitimage got executed, because I called "source <loadaddr>" ... so at all user error or may this is all just theoretical problems, as in case of secure boot, you should not allow to enter commandline at all, and of course you need to use protected environment in such a setup...
I could not add simply another public key with required = "image";
else on "boot of kernel fitimage", it needs signatures for all images in images section...
But I am fine with adding a configurations node in the its for the bootscript.
Sorry for the confusion.
bye, Heiko

On 1/12/23 18:43, Simon Glass wrote:
Hi,
On Thu, 12 Jan 2023 at 09:03, Sean Anderson sean.anderson@seco.com wrote:
On 1/11/23 01:13, Heiko Schocher wrote:
Hello Sean,
Thanks for your answer!
On 10.01.23 17:27, Sean Anderson wrote:
On 1/10/23 08:18, Heiko Schocher wrote:
Hello Simon,
[...]
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.
My "hack" checks a configuration signature in fitimage with script in it... so also "secure" ...
BTW: why we need a env variable to enable checking in cmd/source.c? I would say, if verify fit images is enabled we always should check signature ... but this is another question...
I think it's to allow disabling things for debugging. If the variable does not exist, it defaults to verifying.
So I tried your suggestion:
=> tftp 100000 script.bin.signed;setenv verify 1;source #100000 Speed: 1000, full duplex Using ethernet@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: # 233.4 KiB/s done Bytes transferred = 1679 (68f hex) ## Executing script at 00000000 Wrong image format for "source" command =>
same for
=> source #100000:script-1 ## Executing script at 00000000 Wrong image format for "source" command =>
Which is the error message from the switch in image_source_script() from cmd/source.c ...
Right.
What kind of image is your script? Do you have CONFIG_FIT (and *only* CONFIG_FIT) enabled?
(check if fitimage "is okay"): => source 100000 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-2 ## Executing script at 00100000 Can't find 'script-2' FIT subimage =>
and changing hash in fitimages signature leads to: => mw 1001c0 0 1 => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev- Hallo from script =>
As I described ... problem "hash is detected, but script is executed", as public key in u-boots dtb has required = "conf"; (as it is used also for fitimage boot, where we use conf signing)
May you have an example (u-boot.dtb, its and complete working command for a signed fitimage script)?
$ cat << EOF >> dm-verity.its /dts-v1/;
/ { description = "dm-verity boot parameters"; #address-cells = <1>;
images { dm-verity { data = /incbin/("dm-verity.scr"); type = "script"; arch = "arm64"; compression = "none"; hash-1 { algo = "sha256"; }; }; }; configurations { default = "conf"; conf { description = "Load dm-verity boot parameters"; script = "dm-verity"; signature { algo = "sha256,rsa2048"; key-name-hint = "u-boot"; sign-images = "script"; }; }; };
}; EOF $ uboot-mkimage -EB 0x40 -f dm-verity.its dm-verity.itb $ uboot-mkimage -EB 0x40 -r -F -k /path/to/keys dm-verity.itb
The main problem is (I think) that we check for fitimages which are used for booting kernels, a "signed configuration" and in fitimage for scripts only "image" signatures ... and a combination of both is not possible (except I also sign the image nodes in kernel fitimage too ... which than leads in checking configuration signature and image signature on boot... but may a way to go (and disabling hash check) ?
Yes, which is why you need to have # in the source command to force only using configurations. IMO we should also check image-only FITs, but Simon disagrees.
I'm not sure what I disagree with, exactly. Signing images leaves one open to a mix-and-match attack, so I believe it is better to put the script into the config so it is signed along with the kernel, etc. But I am fine with us supporting signed images containing scripts...in fact I thought we already did?
I suppose we do, but we just call fit_image_verify which works only if you have `required = "images"`. But this is problematic for boot images, so you need `required = "images", "configs"` and end up signing both (not the worst I suppose).
--Sean

Hello Sean,
On 12.01.23 17:03, Sean Anderson wrote:
On 1/11/23 01:13, Heiko Schocher wrote:
Hello Sean,
Thanks for your answer!
On 10.01.23 17:27, Sean Anderson wrote:
On 1/10/23 08:18, Heiko Schocher wrote:
Hello Simon,
[...]
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.
My "hack" checks a configuration signature in fitimage with script in it... so also "secure" ...
BTW: why we need a env variable to enable checking in cmd/source.c? I would say, if verify fit images is enabled we always should check signature ... but this is another question...
I think it's to allow disabling things for debugging. If the variable does not exist, it defaults to verifying.
Hmm... so you need also protected environment, to be secure, but hey, that should be the case in a secure boot setup...
So I tried your suggestion:
=> tftp 100000 script.bin.signed;setenv verify 1;source #100000 Speed: 1000, full duplex Using ethernet@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: # 233.4 KiB/s done Bytes transferred = 1679 (68f hex) ## Executing script at 00000000 Wrong image format for "source" command =>
same for
=> source #100000:script-1 ## Executing script at 00000000 Wrong image format for "source" command =>
Which is the error message from the switch in image_source_script() from cmd/source.c ...
Right.
What kind of image is your script? Do you have CONFIG_FIT (and *only* CONFIG_FIT) enabled?
fitimage
(check if fitimage "is okay"): => source 100000 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-2 ## Executing script at 00100000 Can't find 'script-2' FIT subimage =>
and changing hash in fitimages signature leads to: => mw 1001c0 0 1 => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev- Hallo from script =>
As I described ... problem "hash is detected, but script is executed", as public key in u-boots dtb has required = "conf"; (as it is used also for fitimage boot, where we use conf signing)
May you have an example (u-boot.dtb, its and complete working command for a signed fitimage script)?
$ cat << EOF >> dm-verity.its /dts-v1/;
/ { description = "dm-verity boot parameters"; #address-cells = <1>;
images { dm-verity { data = /incbin/("dm-verity.scr"); type = "script"; arch = "arm64"; compression = "none"; hash-1 { algo = "sha256"; }; }; }; configurations { default = "conf"; conf { description = "Load dm-verity boot parameters"; script = "dm-verity"; signature { algo = "sha256,rsa2048"; key-name-hint = "u-boot"; sign-images = "script"; }; }; };
}; EOF $ uboot-mkimage -EB 0x40 -f dm-verity.its dm-verity.itb $ uboot-mkimage -EB 0x40 -r -F -k /path/to/keys dm-verity.itb
Thanks!
Hmm... I get now:
=> source #100000 ## Executing script at 00100000 Could not find config 100000 =>
See my dump[1] ...
Ah! I got it, now it works when calling:
=> source #conf ## Executing script at 00100000 sha256,rsa2048:dev+ sha256+ Hallo from script =>
Many thanks for your help!
The main problem is (I think) that we check for fitimages which are used for booting kernels, a "signed configuration" and in fitimage for scripts only "image" signatures ... and a combination of both is not possible (except I also sign the image nodes in kernel fitimage too ... which than leads in checking configuration signature and image signature on boot... but may a way to go (and disabling hash check) ?
Yes, which is why you need to have # in the source command to force only using configurations. IMO we should also check image-only FITs, but Simon disagrees.
bye, Heiko
[1] dumps ## Executing script at 00100000 Could not find config 100000 => fdt addr 100000 Working FDT set to 100000 => fdt print / { timestamp = <0x4d9b9ef0>; description = "Bootscript"; #address-cells = <0x00000001>; images { signed-script { data = "echo Hallo from script "; type = "script"; arch = "powerpc"; compression = "none"; hash-1 { value = <0x4f9ef4c9 0x64b6027a 0xc0bf7019 0x2f21411f 0x3a03bb96 0x526e6cc0 0x172a6203 0x07ebd90e>; algo = "sha256"; }; }; }; configurations { default = "conf"; conf { description = "signed script"; script = "signed-script"; signature { hashed-strings = <0x00000000 0x00000074>; hashed-nodes = "/", "/configurations/conf", "/images/signed-script", "/images/signed-script/hash-1"; timestamp = <0x4d9b9ef0>; signer-version = "2023.01"; signer-name = "mkimage"; value = <0x96974a88 0x62b8906e 0x78bff7b8 0x9db6d123 0xe26d2337 0xfec3f4d3 0x618db24a 0xccec126f 0x89067d44 0xaefc162f 0x80d7fa16 0x4c9e18d2 0x87d4ece5 0x2846cfa3 0xfda412c3 0x80b0c104 0x0a201350 0xbe1b8265 0xdf2a7f7d 0xfe388fdc 0xd4de31c7 0x72ebaa1e 0xede78761 0x805eb41c 0x7f653832 0x0b12d572 0xbfa7b5b5 0xb0233634 0x81239f79 0x02a4c20d 0x6c107772 0x2eac0ba4 0x553fbedd 0x7550ff57 0x9260573a 0xb3ca3064 0xd5f78b11 0xd598c0a7 0x267fcdda 0x7b746a25 0xea82f622 0x6c73e1a3 0x837fc059 0xc2e4b1fd 0xf8e8b685 0x3b0d1b0b 0x6b2c83db 0xfb76eac1 0x2f83d3df 0x3696dee8 0xb5a91e65 0x29e204bb 0xb8505017 0x10f77969 0xbc960cfe 0x094134cf 0x1f1090ae 0xdb49cb26 0xf4761d1c 0x64f753b8 0xa86f8164 0x87cc3287 0xfe84a3d7 0xb9ddf904>; algo = "sha256,rsa2048"; key-name-hint = "dev"; sign-images = "script"; }; }; }; }; => bd [...] fdt_blob = 0x1fb49fa0 new_fdt = 0x1fb49fa0 [...] => fdt addr 0x1fb49fa0 Working FDT set to 1fb49fa0 => fdt print / { model = "abb,socrates"; compatible = "abb,socrates"; #address-cells = <0x00000001>; #size-cells = <0x00000001>; signature { key-dev { required = "conf"; algo = "sha256,rsa2048"; rsa,r-squared = <0x04d76ec8 0x32c73f36 0x1885a88a 0x38c5f9da 0x76058623 0x144a9f4e 0x03b68693 0x12a3a7c3 0x63fe3d39 0x64050d31 0x3b4d47ec 0x43c0d6c0 0x5b473005 0x6ba07db0 0x834b69cf 0xc77d3d18 0x90a16449 0xca7ea292 0xbd5c7e8d 0xb12873b2 0xbd9854e6 0xa12bd2ca 0x49524aca 0x666fa5ad 0x60b46068 0x00f8beb7 0x4f035cac 0x3d7f0d00 0x307cb78a 0xf7d69d41 0x4458b11e 0x796593b4 0x70f5d606 0x730a7eea 0x0facdf9c 0x944a88a0 0x91485179 0x86f28224 0xc753ad58 0xa108107c 0x7211253d 0x48c11ce4 0xaabdd41f 0x0867090c 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 0x0e41796a 0xec9a7d09 0xad858e31 0xc95e53f9 0x5384346f 0x31f05039 0xe1121bd4 0x6c039a05>; rsa,exponent = <0x00000000 0x00010001>; rsa,n0-inverse = <0x38aadd33>; rsa,num-bits = <0x00000800>; key-name-hint = "dev"; }; }; cpus {

Hello Sean,
YFI: now I know why it made me so much problems
=> source #conf
does only work since your commit
commit bcc85b96b5ff: ("cmd: source: Support specifying config name")
which is not on 2023.01 with which I tested for the customer!
With current HEAD it works fine!
So again, sorry for the confusion...
bye, Heiko
On 13.01.23 07:22, Heiko Schocher wrote:
Hello Sean,
On 12.01.23 17:03, Sean Anderson wrote:
On 1/11/23 01:13, Heiko Schocher wrote:
Hello Sean,
Thanks for your answer!
On 10.01.23 17:27, Sean Anderson wrote:
On 1/10/23 08:18, Heiko Schocher wrote:
Hello Simon,
[...]
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.
My "hack" checks a configuration signature in fitimage with script in it... so also "secure" ...
BTW: why we need a env variable to enable checking in cmd/source.c? I would say, if verify fit images is enabled we always should check signature ... but this is another question...
I think it's to allow disabling things for debugging. If the variable does not exist, it defaults to verifying.
Hmm... so you need also protected environment, to be secure, but hey, that should be the case in a secure boot setup...
So I tried your suggestion:
=> tftp 100000 script.bin.signed;setenv verify 1;source #100000 Speed: 1000, full duplex Using ethernet@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: # 233.4 KiB/s done Bytes transferred = 1679 (68f hex) ## Executing script at 00000000 Wrong image format for "source" command =>
same for
=> source #100000:script-1 ## Executing script at 00000000 Wrong image format for "source" command =>
Which is the error message from the switch in image_source_script() from cmd/source.c ...
Right.
What kind of image is your script? Do you have CONFIG_FIT (and *only* CONFIG_FIT) enabled?
fitimage
(check if fitimage "is okay"): => source 100000 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev+ Hallo from script => source 100000:script-2 ## Executing script at 00100000 Can't find 'script-2' FIT subimage =>
and changing hash in fitimages signature leads to: => mw 1001c0 0 1 => source 100000:script-1 ## Executing script at 00100000 sha256+ sha256,rsa2048:dev- Hallo from script =>
As I described ... problem "hash is detected, but script is executed", as public key in u-boots dtb has required = "conf"; (as it is used also for fitimage boot, where we use conf signing)
May you have an example (u-boot.dtb, its and complete working command for a signed fitimage script)?
$ cat << EOF >> dm-verity.its /dts-v1/;
/ { description = "dm-verity boot parameters"; #address-cells = <1>;
images { dm-verity { data = /incbin/("dm-verity.scr"); type = "script"; arch = "arm64"; compression = "none"; hash-1 { algo = "sha256"; }; }; }; configurations { default = "conf"; conf { description = "Load dm-verity boot parameters"; script = "dm-verity"; signature { algo = "sha256,rsa2048"; key-name-hint = "u-boot"; sign-images = "script"; }; }; };
}; EOF $ uboot-mkimage -EB 0x40 -f dm-verity.its dm-verity.itb $ uboot-mkimage -EB 0x40 -r -F -k /path/to/keys dm-verity.itb
Thanks!
Hmm... I get now:
=> source #100000 ## Executing script at 00100000 Could not find config 100000 =>
See my dump[1] ...
Ah! I got it, now it works when calling:
=> source #conf ## Executing script at 00100000 sha256,rsa2048:dev+ sha256+ Hallo from script =>
Many thanks for your help!
The main problem is (I think) that we check for fitimages which are used for booting kernels, a "signed configuration" and in fitimage for scripts only "image" signatures ... and a combination of both is not possible (except I also sign the image nodes in kernel fitimage too ... which than leads in checking configuration signature and image signature on boot... but may a way to go (and disabling hash check) ?
Yes, which is why you need to have # in the source command to force only using configurations. IMO we should also check image-only FITs, but Simon disagrees.
bye, Heiko
[1] dumps ## Executing script at 00100000 Could not find config 100000 => fdt addr 100000 Working FDT set to 100000 => fdt print / { timestamp = <0x4d9b9ef0>; description = "Bootscript"; #address-cells = <0x00000001>; images { signed-script { data = "echo Hallo from script "; type = "script"; arch = "powerpc"; compression = "none"; hash-1 { value = <0x4f9ef4c9 0x64b6027a 0xc0bf7019 0x2f21411f 0x3a03bb96 0x526e6cc0 0x172a6203 0x07ebd90e>; algo = "sha256"; }; }; }; configurations { default = "conf"; conf { description = "signed script"; script = "signed-script"; signature { hashed-strings = <0x00000000 0x00000074>; hashed-nodes = "/", "/configurations/conf", "/images/signed-script", "/images/signed-script/hash-1"; timestamp = <0x4d9b9ef0>; signer-version = "2023.01"; signer-name = "mkimage"; value = <0x96974a88 0x62b8906e 0x78bff7b8 0x9db6d123 0xe26d2337 0xfec3f4d3 0x618db24a 0xccec126f 0x89067d44 0xaefc162f 0x80d7fa16 0x4c9e18d2 0x87d4ece5 0x2846cfa3 0xfda412c3 0x80b0c104 0x0a201350 0xbe1b8265 0xdf2a7f7d 0xfe388fdc 0xd4de31c7 0x72ebaa1e 0xede78761 0x805eb41c 0x7f653832 0x0b12d572 0xbfa7b5b5 0xb0233634 0x81239f79 0x02a4c20d 0x6c107772 0x2eac0ba4 0x553fbedd 0x7550ff57 0x9260573a 0xb3ca3064 0xd5f78b11 0xd598c0a7 0x267fcdda 0x7b746a25 0xea82f622 0x6c73e1a3 0x837fc059 0xc2e4b1fd 0xf8e8b685 0x3b0d1b0b 0x6b2c83db 0xfb76eac1 0x2f83d3df 0x3696dee8 0xb5a91e65 0x29e204bb 0xb8505017 0x10f77969 0xbc960cfe 0x094134cf 0x1f1090ae 0xdb49cb26 0xf4761d1c 0x64f753b8 0xa86f8164 0x87cc3287 0xfe84a3d7 0xb9ddf904>; algo = "sha256,rsa2048"; key-name-hint = "dev"; sign-images = "script"; }; }; }; }; => bd [...] fdt_blob = 0x1fb49fa0 new_fdt = 0x1fb49fa0 [...] => fdt addr 0x1fb49fa0 Working FDT set to 1fb49fa0 => fdt print / { model = "abb,socrates"; compatible = "abb,socrates"; #address-cells = <0x00000001>; #size-cells = <0x00000001>; signature { key-dev { required = "conf"; algo = "sha256,rsa2048"; rsa,r-squared = <0x04d76ec8 0x32c73f36 0x1885a88a 0x38c5f9da 0x76058623 0x144a9f4e 0x03b68693 0x12a3a7c3 0x63fe3d39 0x64050d31 0x3b4d47ec 0x43c0d6c0 0x5b473005 0x6ba07db0 0x834b69cf 0xc77d3d18 0x90a16449 0xca7ea292 0xbd5c7e8d 0xb12873b2 0xbd9854e6 0xa12bd2ca 0x49524aca 0x666fa5ad 0x60b46068 0x00f8beb7 0x4f035cac 0x3d7f0d00 0x307cb78a 0xf7d69d41 0x4458b11e 0x796593b4 0x70f5d606 0x730a7eea 0x0facdf9c 0x944a88a0 0x91485179 0x86f28224 0xc753ad58 0xa108107c 0x7211253d 0x48c11ce4 0xaabdd41f 0x0867090c 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 0x0e41796a 0xec9a7d09 0xad858e31 0xc95e53f9 0x5384346f 0x31f05039 0xe1121bd4 0x6c039a05>; rsa,exponent = <0x00000000 0x00010001>; rsa,n0-inverse = <0x38aadd33>; rsa,num-bits = <0x00000800>; key-name-hint = "dev"; }; }; cpus {
participants (3)
-
Heiko Schocher
-
Sean Anderson
-
Simon Glass