All of lore.kernel.org
 help / color / mirror / Atom feed
* fit_check_sig not hashing everything.
@ 2022-07-07 16:29 Martin Bonner
  2022-07-08  7:10 ` Martin Bonner
  0 siblings, 1 reply; 3+ messages in thread
From: Martin Bonner @ 2022-07-07 16:29 UTC (permalink / raw)
  To: u-boot

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@1
    MJB Verifying signature for node signature@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@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@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@1
    MJB Verifying signature for node signature@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@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@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@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@1
    MJB Verifying signature for node signature@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@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@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@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@1
    MJB Verifying signature for node signature@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@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@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@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@1 {
                value = <0xD36FB92A 0x4AF6184D 0xDB426196 0x91323F8B
0x45F84FDB 0x77F5CC65 0xD0D0CEBD 0x115EB6F3>;
                algo = "sha256";
            };
        };
        fdt@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@1 {
                value = <0xA62BDFB 0x741BC77D 0xE5A9D110 0x4F311031 ...>;
                algo = "sha256";
            };
        };
        ramdisk@0 {
            description = "RAMDisk";
            data = <0xFD377A58 0x5A000001 0x6922DE36 0x4C0E2D5 ... ];
            type = "ramdisk";
            arch = "ppc";
            os = "linux";
            compression = "none";
            hash@1 {
                value = <0xE3ED2C68 0x781D674E 0xAADC2B6C 0x9CF1649D
0xF479BF06 0xE655A81B 0xCBC3FA1A 0x1EAECB5>;
                algo = "sha256";
            };
        };
    };
    configurations {
        default = "conf@1";
        conf@1 {
            description = "Boot Linux kernel";
            kernel = "kernel@0";
            fdt = "fdt@0";
            ramdisk = "ramdisk@0";
            hash@1 {
                algo = "sha256";
            };
            signature@1 {
                hashed-strings = <0x0 0x9E>;
                hashed-nodes = "/", "/configurations/conf@1",
"/images/kernel@0", "/images/kernel@0/hash@1",
                    "/images/fdt@0", "/images/fdt@0/hash@1",
"/images/ramdisk@0", "/images/ramdisk@0/hash@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

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: fit_check_sig not hashing everything.
  2022-07-07 16:29 fit_check_sig not hashing everything Martin Bonner
@ 2022-07-08  7:10 ` Martin Bonner
  2022-07-12 10:58   ` Simon Glass
  0 siblings, 1 reply; 3+ messages in thread
From: Martin Bonner @ 2022-07-08  7:10 UTC (permalink / raw)
  To: u-boot

On Thu, 7 Jul 2022 at 17:29, Martin Bonner <martingreybeard@gmail.com>
wrote:

> 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"! ...
>
> Can anyone clarify what is happening?
>

Never mind.  I have found fit_image_check_hash in image-fit.c (yay for gdb
read watchpoints!)  So the algorithm is basically "verify that the hashes
of each image is correct", then calculate a hash which includes the hashes
of the images (but not their data), and sign that.  (I think it's
overcomplicated, and complexity is the enemy of security - but it's much
too late to change that.)

Martin

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: fit_check_sig not hashing everything.
  2022-07-08  7:10 ` Martin Bonner
@ 2022-07-12 10:58   ` Simon Glass
  0 siblings, 0 replies; 3+ messages in thread
From: Simon Glass @ 2022-07-12 10:58 UTC (permalink / raw)
  To: Martin Bonner; +Cc: U-Boot Mailing List

Hi Martin,

On Fri, 8 Jul 2022 at 01:11, Martin Bonner <martingreybeard@gmail.com> wrote:
>
> On Thu, 7 Jul 2022 at 17:29, Martin Bonner <martingreybeard@gmail.com>
> wrote:
>
> > 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"! ...
> >
> > Can anyone clarify what is happening?
> >
>
> Never mind.  I have found fit_image_check_hash in image-fit.c (yay for gdb
> read watchpoints!)  So the algorithm is basically "verify that the hashes
> of each image is correct", then calculate a hash which includes the hashes
> of the images (but not their data), and sign that.  (I think it's
> overcomplicated, and complexity is the enemy of security - but it's much
> too late to change that.)

Some reasons:
- it is faster to hash things only once (i.e. use the image hash we
already have)
- It is faster to hash smaller things (i.e. the meta data)

This of this as a tree of hashes...

Regards,
Simon

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-07-12 11:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-07 16:29 fit_check_sig not hashing everything Martin Bonner
2022-07-08  7:10 ` Martin Bonner
2022-07-12 10:58   ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.