This repository has been archived by the owner on Sep 14, 2024. It is now read-only.
forked from f-secure-foundry/advisories
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Security_Advisory-Ref_FSC-HWSEC-VR2020-0001-U-Boot_verified_boot_bypass.txt
196 lines (169 loc) · 6.23 KB
/
Security_Advisory-Ref_FSC-HWSEC-VR2020-0001-U-Boot_verified_boot_bypass.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
Improper image signature verification
=====================================
Description
-----------
Das U-Boot typically is employed as a second-stage boot loader responsible for
loading the Linux operating system's kernel and related images and passing
control further to the OS. The bootloader is also responsible to verify
integrity and authenticity of the loaded images to ensure only authentic
software is allowed to run. U-Boot's verified boot feature [1,2] is used to
achieve this. This method only applies to the flattened image tree (FIT) image
format.
The FIT image is based on previously developed device tree format used in both
U-Boot and the Linux kernel to store and pass configuration information. An
example image tree source (the text format used to generate FIT images) from
the documentation is reproduced below to illustrate the concept:
```
/ {
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...>;
};
};
};
};
```
This image tree source describes two kernels with two flattened device tree
blobs (FDTs) as well as two configurations denoting which images are to be
used together. The complete configuration may also include other images e.g.
RAM disks. Hash values for individual images are computed during image build.
When an image is signed using the mkimage tool provided with U-Boot, the image
is modified by adding several properties to corresponding signature nodes,
specifically `hashed-strings`, `hashed-nodes`, `timestamp`, `signer-version`,
`signer-name`, and `value`. The `value` property holds the actual signature,
while the `hashed-strings` and `hashed-nodes` properties represent the elements
that were used to compute the signed hash value. For example:
```
conf@1 {
description = [REMOVED];
kernel = "kernel@1";
fdt = "fdt@1";
ramdisk = "ramdisk@1";
signature@1 {
hashed-strings = [00 00 00 00 00 00 00 8e];
hashed-nodes = "/", "/configurations/conf@1", "/images/fdt@1", "/images/fdt@1/hash@1", "/images/kernel@1", "/images/kernel@1/hash@1", "/images/ramdisk@1", "/images/ramdisk@1/hash@1";
timestamp = [5d cb 49 dc];
signer-version = "2019.07";
signer-name = "mkimage";
value = [03 d9 d7 e8 5a cf ..];
algo = "sha256,rsa4096";
key-name-hint = [REMOVED];
sign-images = "fdt", "kernel", "ramdisk";
};
};
```
The string block data starting from offset 0 to offset 0x8E was included in the
hash computation along with enumarated tree nodes, which produces the given RSA
signature.
It was found that U-Boot does not verify the contents of `hashed-nodes`
correlate with the sub-images required to be loaded by the configuration,
specified e.g. in the `kernel`, `fdt`, and `ramdisk` configuration properties.
This allows to craft another configuration with the same signature node but
referencing a different sub-image(s):
```
conf@2 {
description = "Super 1337 Configuration";
kernel = "kernel@2";
fdt = "fdt@1";
ramdisk = "ramdisk@1";
signature@1 {
hashed-strings = [00 00 00 00 00 00 00 8e];
hashed-nodes = "/", "/configurations/conf@1", "/images/fdt@1", "/images/fdt@1/hash@1", "/images/kernel@1", "/images/kernel@1/hash@1", "/images/ramdisk@1", "/images/ramdisk@1/hash@1";
timestamp = [5d cb 49 dc];
signer-version = "2019.07";
signer-name = "mkimage";
value = [03 d9 d7 e8 5a cf ..];
algo = "sha256,rsa4096";
key-name-hint = [REMOVED];
sign-images = "fdt", "kernel", "ramdisk";
};
};
```
As by design [3] only certain parts of the FIT image are hashed, it is possible
to insert arbitrary FIT nodes after configurations have been signed without
invalidating any signatures, adding both arbitrary configurations as well as
arbitrary sub-images. Note that this fact is explicitly documented. It is also
possible to change the default property of the configurations node to suggest
the crafted configuration to be chosen.
Impact
------
An attacker having a properly signed FIT image is able to craft arbitrary FIT
images that would pass signature validation, resulting in booting and
execution of untrusted code.
The exploitation relies on the fact that the crafted configuration will be
chosen to be booted. This may occur, for example, when the attacker is able to
modify the `default` property of the `configurations` node and the setup does
not explicitly choose to boot a specific configuration. Consequently, one way of
mitigating the issue is to explicitly specify the configuration name as part of
the `bootm` command arguments, for example: `bootm ${loadaddr}#conf@1 - ${fdtaddr}`
Affected versions
-----------------
U-Boot versions 2018.03 and 2020.01 were verified to be affected. Versions
prior to 2018.03 may be affected as well.
Solution
--------
Apply patches or update to a fixed version when available.
Preliminary patches have been posted to the mailing list [4] for review.
CVE assignment
--------------
CVE-2020-10648 should be used to track this issue.
Credit
------
Dmitry Janushkevich (@infosecdj) of the Hardware Security team, F-Secure
Timeline
--------
2020-01-22: Discovery of the issue.
2020-01-24: Details sent to maintainers Tom Rini and Simon Glass.
2020-02-26: Patches provided for review by Simon Glass.
2020-03-11: Release date agreed to be March 18.
2020-03-17: CVE assignment.
2020-03-18: Public release.
References
----------
[1] https://github.com/u-boot/u-boot/blob/master/doc/uImage.FIT/verified-boot.txt
[2] https://github.com/u-boot/u-boot/blob/master/doc/uImage.FIT/signature.txt
[3] See documentation for the fdt_find_regions() function in include/linux/libfdt.h
[4] https://lists.denx.de/pipermail/u-boot/2020-March/403409.html