1
0
mirror of https://xff.cz/git/u-boot/ synced 2025-09-01 08:42:12 +02:00

image: Add support for signing of FIT 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).

Add support for signing of FIT configurations using the libfdt's region
support.

Please see doc/uImage.FIT/signature.txt for more information.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2013-06-13 15:10:09 -07:00
committed by Tom Rini
parent 3e06cd1f97
commit 4d0985295b
5 changed files with 798 additions and 3 deletions

View File

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

View File

@@ -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