diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/uImage.FIT/sign-configs.its | 45 | ||||
-rw-r--r-- | doc/uImage.FIT/signature.txt | 168 |
2 files changed, 212 insertions, 1 deletions
diff --git a/doc/uImage.FIT/sign-configs.its b/doc/uImage.FIT/sign-configs.its new file mode 100644 index 00000000000..3c17f040de0 --- /dev/null +++ b/doc/uImage.FIT/sign-configs.its @@ -0,0 +1,45 @@ +/dts-v1/; + +/ { + description = "Chrome OS kernel image with one or more FDT blobs"; + #address-cells = <1>; + + images { + kernel@1 { + data = /incbin/("test-kernel.bin"); + type = "kernel_noload"; + arch = "sandbox"; + os = "linux"; + compression = "lzo"; + load = <0x4>; + entry = <0x8>; + kernel-version = <1>; + hash@1 { + algo = "sha1"; + }; + }; + fdt@1 { + description = "snow"; + data = /incbin/("sandbox-kernel.dtb"); + type = "flat_dt"; + arch = "sandbox"; + compression = "none"; + fdt-version = <1>; + hash@1 { + algo = "sha1"; + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "fdt@1"; + signature@1 { + algo = "sha1,rsa2048"; + key-name-hint = "dev"; + sign-images = "fdt", "kernel"; + }; + }; + }; +}; diff --git a/doc/uImage.FIT/signature.txt b/doc/uImage.FIT/signature.txt index 0d145e00714..bc9f3fa6e13 100644 --- a/doc/uImage.FIT/signature.txt +++ b/doc/uImage.FIT/signature.txt @@ -105,8 +105,27 @@ When the image is signed, the following properties are optional: - comment: Additional information about the signer or image +For config bindings (see Signed Configurations below), the following +additional properties are optional: -Example: See sign-images.its for an example image tree source file. +- sign-images: A list of images to sign, each being a property of the conf +node that contains then. The default is "kernel,fdt" which means that these +two images will be looked up in the config and signed if present. + +For config bindings, these properties are added by the signer: + +- hashed-nodes: A list of nodes which were hashed by the signer. Each is + a string - the full path to node. A typical value might be: + + hashed-nodes = "/", "/configurations/conf@1", "/images/kernel@1", + "/images/kernel@1/hash@1", "/images/fdt@1", + "/images/fdt@1/hash@1"; + +- hashed-strings: The start and size of the string region of the FIT that + was hashed + +Example: See sign-images.its for an example image tree source file and +sign-configs.its for config signing. Public Key Storage @@ -144,6 +163,153 @@ For RSA the following are mandatory: - rsa,n0-inverse: -1 / modulus[0] mod 2^32 +Signed Configurations +--------------------- +While signing images is useful, it does not provide complete protection +against several types of attack. For example, it it possible to create a +FIT with the same signed images, but with the configuration changed such +that a different one is selected (mix and match attack). It is also possible +to substitute a signed image from an older FIT version into a newer FIT +(roll-back attack). + +As an example, consider this FIT: + +/ { + images { + kernel@1 { + data = <data for kernel1> + signature@1 { + algo = "sha1,rsa2048"; + value = <...kernel signature 1...> + }; + }; + kernel@2 { + data = <data for kernel2> + signature@1 { + algo = "sha1,rsa2048"; + value = <...kernel signature 2...> + }; + }; + fdt@1 { + data = <data for fdt1>; + signature@1 { + algo = "sha1,rsa2048"; + vaue = <...fdt signature 1...> + }; + }; + fdt@2 { + data = <data for fdt2>; + signature@1 { + algo = "sha1,rsa2048"; + vaue = <...fdt signature 2...> + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "fdt@1"; + }; + conf@1 { + kernel = "kernel@2"; + fdt = "fdt@2"; + }; + }; +}; + +Since both kernels are signed it is easy for an attacker to add a new +configuration 3 with kernel 1 and fdt 2: + + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "fdt@1"; + }; + conf@1 { + kernel = "kernel@2"; + fdt = "fdt@2"; + }; + conf@3 { + kernel = "kernel@1"; + fdt = "fdt@2"; + }; + }; + +With signed images, nothing protects against this. Whether it gains an +advantage for the attacker is debatable, but it is not secure. + +To solved this problem, we support signed configurations. In this case it +is the configurations that are signed, not the image. Each image has its +own hash, and we include the hash in the configuration signature. + +So the above example is adjusted to look like this: + +/ { + images { + kernel@1 { + data = <data for kernel1> + hash@1 { + algo = "sha1"; + value = <...kernel hash 1...> + }; + }; + kernel@2 { + data = <data for kernel2> + hash@1 { + algo = "sha1"; + value = <...kernel hash 2...> + }; + }; + fdt@1 { + data = <data for fdt1>; + hash@1 { + algo = "sha1"; + value = <...fdt hash 1...> + }; + }; + fdt@2 { + data = <data for fdt2>; + hash@1 { + algo = "sha1"; + value = <...fdt hash 2...> + }; + }; + }; + configurations { + default = "conf@1"; + conf@1 { + kernel = "kernel@1"; + fdt = "fdt@1"; + signature@1 { + algo = "sha1,rsa2048"; + value = <...conf 1 signature...>; + }; + }; + conf@2 { + kernel = "kernel@2"; + fdt = "fdt@2"; + signature@1 { + algo = "sha1,rsa2048"; + value = <...conf 1 signature...>; + }; + }; + }; +}; + + +You can see that we have added hashes for all images (since they are no +longer signed), and a signature to each configuration. In the above example, +mkimage will sign configurations/conf@1, the kernel and fdt that are +pointed to by the configuration (/images/kernel@1, /images/kernel@1/hash@1, +/images/fdt@1, /images/fdt@1/hash@1) and the root structure of the image +(so that it isn't possible to add or remove root nodes). The signature is +written into /configurations/conf@1/signature@1/value. It can easily be +verified later even if the FIT has been signed with other keys in the +meantime. + + Verification ------------ FITs are verified when loaded. After the configuration is selected a list |