Merge branch 'master' of git://git.denx.de/u-boot-arm
[kernel/u-boot.git] / doc / uImage.FIT / signature.txt
index 0d145e0..bc9f3fa 100644 (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