u-boot: signature check for u-boot scripts
Heiko Schocher
hs at denx.de
Fri Jan 13 07:22:47 CET 2023
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 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: #
>> 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 {
--
DENX Software Engineering GmbH, Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: hs at denx.de
More information about the U-Boot
mailing list