fit_check_sig not hashing everything.
Martin Bonner
martingreybeard at gmail.com
Thu Jul 7 18:29:24 CEST 2022
I am running fit_check_sig on windows to understand in more details how it
works.
What I really want, is a _precise_ description of exactly which bytes of a
FIT image are fed into the hash function (and in which order) in order to
calculate the hash value. I then want to reproduce that hash function in
python (using the "fdt" module) in order to sign the FIT image offline. I
am expecting to have to reverse engineer this description (signature.txt
isn't nearly detailed enough for me), and that's fine (although if anyone
wants to prove me wrong, that would be wonderful).
I have a 30MB FIT image as input, and I have added some debug to
hash_calculate in rsa-checksum.c to print the amount of data being hashed.
The answer is a rather scary "1106 bytes"! The good news is that I have
also added debug to print out the offset within the FIT image of the
regions being hashed (actually in fit_config_check_sig in image-sig.c), and
used this to zero a single byte of the FIT image well away from the offsets
(allegedly) being hashed - and the verification fails (yay!). So clearly I
don't understand what is going on (!).
Can anyone clarify what is happening?
One slightly strange thing I notice is that fit_config_check_sig appears to
be called four! times.
I am working with 2020.1, and cannot easily upgrade to the latest because
the signature nodes contain @.
Debug:
Verifying Hash Integrity ... In fit_config_verify
MJB fit_config_verify_required_sigs
In fit_config_verify_sig
MJB Verifying signature for node hash at 1
MJB Verifying signature for node signature at 1
sha256,rsa4096:ultra-insecure
Verifying 8 regions:
00 00 00 01 00 00 00 00 00 00 00 03 00 00 00 04 (offset=38 len=180)
00 00 00 03 00 00 00 07 00 00 00 30 6B 65 72 6E (offset=4cee04 len=244)
hash at 1 region (offset=4d5b30 len=176)
00 00 00 03 00 00 00 08 00 00 00 30 72 61 6D 64 (offset=1d4d7b4 len=184)
00 00 00 01 63 6F 6E 66 40 31 00 00 00 00 00 03 (offset=1d4d880 len=124)
00 00 00 02 00 00 00 01 73 69 67 6E 61 74 75 72 (offset=1d4d910 len=20)
00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 02 (offset=1d4dc70 len=20)
64 65 73 63 72 69 70 74 69 6F 6E 00 6E 73 68 69 (offset=1d4dc84 len=158)
Total bytes hashed = 1106+
## Loading kernel from FIT Image at 6ffffe2b0000 ...
Using 'conf at 1' configuration
Verifying Hash Integrity ...
In fit_config_verify
MJB fit_config_verify_required_sigs
In fit_config_verify_sig
MJB Verifying signature for node hash at 1
MJB Verifying signature for node signature at 1
sha256,rsa4096:ultra-insecure
Verifying 8 regions:
00 00 00 01 00 00 00 00 00 00 00 03 00 00 00 04 (offset=38 len=180)
00 00 00 03 00 00 00 07 00 00 00 30 6B 65 72 6E (offset=4cee04 len=244)
hash at 1 region (offset=4d5b30 len=176)
00 00 00 03 00 00 00 08 00 00 00 30 72 61 6D 64 (offset=1d4d7b4 len=184)
00 00 00 01 63 6F 6E 66 40 31 00 00 00 00 00 03 (offset=1d4d880 len=124)
00 00 00 02 00 00 00 01 73 69 67 6E 61 74 75 72 (offset=1d4d910 len=20)
00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 02 (offset=1d4dc70 len=20)
64 65 73 63 72 69 70 74 69 6F 6E 00 6E 73 68 69 (offset=1d4dc84 len=158)
Total bytes hashed = 1106+
OK
Trying 'kernel at 0' kernel subimage
Description: Linux Kernel
Created: Mon Apr 4 09:12:26 2022
Type: Kernel Image
Compression: gzip compressed
Data Size: 5041417 Bytes = 4923.26 KiB = 4.81 MiB
Architecture: PowerPC
OS: Linux
Load Address: 0x00000000
Entry Point: 0x00000000
Hash algo: sha256
Hash value:
d36fb92a4af6184ddb42619691323f8b45f84fdb77f5cc65d0d0cebd115eb6f3
Verifying Hash Integrity ...
sha256+
OK
Uncompressing Kernel Image
Unimplemented compression type 1
## Loading fdt from FIT Image at 6ffffe2b0000 ...
Using 'conf at 1' configuration
Verifying Hash Integrity ...
In fit_config_verify
MJB fit_config_verify_required_sigs
In fit_config_verify_sig
MJB Verifying signature for node hash at 1
MJB Verifying signature for node signature at 1
sha256,rsa4096:ultra-insecure
Verifying 8 regions:
00 00 00 01 00 00 00 00 00 00 00 03 00 00 00 04 (offset=38 len=180)
00 00 00 03 00 00 00 07 00 00 00 30 6B 65 72 6E (offset=4cee04 len=244)
hash at 1 region (offset=4d5b30 len=176)
00 00 00 03 00 00 00 08 00 00 00 30 72 61 6D 64 (offset=1d4d7b4 len=184)
00 00 00 01 63 6F 6E 66 40 31 00 00 00 00 00 03 (offset=1d4d880 len=124)
00 00 00 02 00 00 00 01 73 69 67 6E 61 74 75 72 (offset=1d4d910 len=20)
00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 02 (offset=1d4dc70 len=20)
64 65 73 63 72 69 70 74 69 6F 6E 00 6E 73 68 69 (offset=1d4dc84 len=158)
Total bytes hashed = 1106+
OK
Trying 'fdt at 0' fdt subimage
Description: Flattened Device Tree blob
Created: Mon Apr 4 09:12:26 2022
Type: Flat Device Tree
Compression: uncompressed
Data Size: 27691 Bytes = 27.04 KiB = 0.03 MiB
Architecture: PowerPC
Hash algo: sha256
Hash value:
0a62bdfb741bc77de5a9d1104f311031f8ac33ec909943c17f2860903121a239
Verifying Hash Integrity ...
sha256+
OK
Loading Flat Device Tree
## Loading ramdisk from FIT Image at 6ffffe2b0000 ...
Using 'conf at 1' configuration
Verifying Hash Integrity ...
In fit_config_verify
MJB fit_config_verify_required_sigs
In fit_config_verify_sig
MJB Verifying signature for node hash at 1
MJB Verifying signature for node signature at 1
sha256,rsa4096:ultra-insecure
Verifying 8 regions:
00 00 00 01 00 00 00 00 00 00 00 03 00 00 00 04 (offset=38 len=180)
00 00 00 03 00 00 00 07 00 00 00 30 6B 65 72 6E (offset=4cee04 len=244)
hash at 1 region (offset=4d5b30 len=176)
00 00 00 03 00 00 00 08 00 00 00 30 72 61 6D 64 (offset=1d4d7b4 len=184)
00 00 00 01 63 6F 6E 66 40 31 00 00 00 00 00 03 (offset=1d4d880 len=124)
00 00 00 02 00 00 00 01 73 69 67 6E 61 74 75 72 (offset=1d4d910 len=20)
00 00 00 02 00 00 00 02 00 00 00 02 00 00 00 02 (offset=1d4dc70 len=20)
64 65 73 63 72 69 70 74 69 6F 6E 00 6E 73 68 69 (offset=1d4dc84 len=158)
Total bytes hashed = 1106+
OK
Trying 'ramdisk at 0' ramdisk subimage
Description: RAMDisk
Created: Mon Apr 4 09:12:26 2022
Type: RAMDisk Image
Compression: uncompressed
Data Size: 25656264 Bytes = 25054.95 KiB = 24.47 MiB
Architecture: PowerPC
OS: Linux
Load Address: unavailable
Entry Point: unavailable
Hash algo: sha256
Hash value:
e3ed2c68781d674eaadc2b6c9cf1649df479bf06e655a81bcbc3fa1a01eaecb5
Verifying Hash Integrity ...
sha256+
OK
Loading RAMDisk Image
Signature check OK
ITB converted to ITS (and mostly redacted)
/dts-v1/;
// version: 17
// last_comp_version: 16
// boot_cpuid_phys: 0x0
/ {
timestamp = <0x624AA86A>;
description = "Boot Image for board";
board-version = "13.2.2-101-3a98c931";
#address-cells = <0x1>;
images {
kernel at 0 {
description = "Linux Kernel";
data = [1F 8B 08 00 00 00 00 00 02 03 B4 7D 0B 58 54 47 ... ];
type = "kernel";
arch = "ppc";
os = "linux";
compression = "gzip";
load = <0x0>;
entry = <0x0>;
hash at 1 {
value = <0xD36FB92A 0x4AF6184D 0xDB426196 0x91323F8B
0x45F84FDB 0x77F5CC65 0xD0D0CEBD 0x115EB6F3>;
algo = "sha256";
};
};
fdt at 0 {
description = "Flattened Device Tree blob";
data = [D0 0D FE ED 00 00 6C 2B 00 00 00 38 00 00 65 4C ... ];
type = "flat_dt";
arch = "ppc";
compression = "none";
hash at 1 {
value = <0xA62BDFB 0x741BC77D 0xE5A9D110 0x4F311031 ...>;
algo = "sha256";
};
};
ramdisk at 0 {
description = "RAMDisk";
data = <0xFD377A58 0x5A000001 0x6922DE36 0x4C0E2D5 ... ];
type = "ramdisk";
arch = "ppc";
os = "linux";
compression = "none";
hash at 1 {
value = <0xE3ED2C68 0x781D674E 0xAADC2B6C 0x9CF1649D
0xF479BF06 0xE655A81B 0xCBC3FA1A 0x1EAECB5>;
algo = "sha256";
};
};
};
configurations {
default = "conf at 1";
conf at 1 {
description = "Boot Linux kernel";
kernel = "kernel at 0";
fdt = "fdt at 0";
ramdisk = "ramdisk at 0";
hash at 1 {
algo = "sha256";
};
signature at 1 {
hashed-strings = <0x0 0x9E>;
hashed-nodes = "/", "/configurations/conf at 1",
"/images/kernel at 0", "/images/kernel at 0/hash at 1",
"/images/fdt at 0", "/images/fdt at 0/hash at 1",
"/images/ramdisk at 0", "/images/ramdisk at 0/hash at 1";
timestamp = <0x624AA86A>;
signer-version = "2020.01";
signer-name = "mkimage";
value = <0x660296EF 0xBFAC0948 0x9B43B4F8 0x3958264D
0x39ECE2A9 0xBF14C100 0xD95DD7D5 0x12525F7F
0x26399A47 0xDFA68CA8 0x80625098 0xF303AAC2
0xFE5EAA79 0x69B3264F 0x25BDB130 0x2DA1F423
0xBBD74859 0x2C7CB1A8 0x0BE7668C 0x05A112A2
0x172BA7B1 0x616EE4C2 0xE8C93859 0x05480848
0xAF5C0F8C 0xF8E0C529 0xC87ED77E 0xDADCB9AE
0x4CE2D7EA 0x54D07A8B 0xFF2715AD 0x0C177059
0x2BCCF6EF 0x93511BCA 0xDA0C16DC 0x88366F70
0x1C606BDA 0x9F6C674C 0x4E328990 0x079DC349
0x3ED2FA6E 0x8E2BFB4E 0x96FE25B9 0x4EC9C0B7
0x49D30DE7 0x98F3FABF 0xBEEC8B9B 0xE35C90DE
0x4FB4586B 0xC6952B5B 0x5539C6B9 0xAF21EA3B
0xB0F12811 0x8AF9A242 0x874658CC 0x9517C652
0xCD062B2D 0x3996FEFF 0xE8B03199 0x9333C8AC
0xEDC8F71F 0x9023AC8A 0x38D00EEB 0x0D171F03
0xDD69CCFF 0x95DEE34F 0x394221DF 0xC04EFC49
0xC3191285 0xBFFA0040 0xDFD683B7 0x53614E59
0x35365737 0x0315F22E 0x198557D7 0x1E2D2EEA
0xA444E500 0x2F54A246 0x781E3B92 0x24D5AEB8
0xEF48F5F7 0x66CAF896 0xAAAAD3E8 0xAB5B8D70
0x9D37AA44 0xB517F759 0x5F6ACA9F 0x27F3F380
0x1404A32E 0x94092308 0x1D920C89 0x4B2B3C1E
0x07BEB532 0x6A6D2BD6 0xC86E5896 0x8708BDCD
0xA70AB635 0x03568CED 0x133554DC 0x208730FC
0xEB2FF6F5 0xECA89FA1 0x8F87746F 0xEC250C3D
0xEA8A403F 0x3302323F 0xA29DA5E1 0xDF9B0198
0xB9B97C3F 0x670E286F 0xEEB58FC5 0xB5DE060B
0xCD027B2B 0x85C566E1 0x0D2ABDFF 0xC9FF7372
0x0D7CEAAB 0x9F91DF92 0x207D7E68 0x967A8C1A
0xD6FFE56B 0x79F1DB3F 0x09BD8FCE 0xD8ABB47C
0x4E26BA36 0x0377465A 0x82573591 0x280D6E89>;
algo = "sha256,rsa4096";
key-name-hint = "ultra-insecure";
sign-images = "kernel", "fdt", "ramdisk";
};
};
};
};
Martin
More information about the U-Boot
mailing list