Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Side by Side Diff: src/platform/vboot_reference/vkernel/kernel_image_fw.c

Issue 1732022: VBoot Reference: Make kernel_config a 4K byte block, and move it after the verified boot block. (Closed) Base URL: ssh://git@chromiumos-git/chromeos
Patch Set: Created 10 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 * 4 *
5 * Functions for verifying a verified boot kernel image. 5 * Functions for verifying a verified boot kernel image.
6 * (Firmware portion) 6 * (Firmware portion)
7 */ 7 */
8 8
9 #include "kernel_image_fw.h" 9 #include "kernel_image_fw.h"
10 10
11 #include "cryptolib.h" 11 #include "cryptolib.h"
12 #include "rollback_index.h" 12 #include "rollback_index.h"
13 #include "utility.h" 13 #include "utility.h"
14 14
15 /* Macro to determine the size of a field structure in the KernelImage 15 /* Macro to determine the size of a field structure in the KernelImage
16 * structure. */ 16 * structure. */
17 #define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field)) 17 #define FIELD_LEN(field) (sizeof(((KernelImage*)0)->field))
18 #define KERNEL_CONFIG_FIELD_LEN (FIELD_LEN(kernel_version) + FIELD_LEN(options.v ersion) + \
19 FIELD_LEN(options.cmd_line) + \
20 FIELD_LEN(options.kernel_len) + \
21 FIELD_LEN(options.kernel_load_addr) + \
22 FIELD_LEN(options.kernel_entry_addr))
23 18
24 char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = { 19 char* kVerifyKernelErrors[VERIFY_KERNEL_MAX] = {
25 "Success.", 20 "Success.",
26 "Invalid Image.", 21 "Invalid Image.",
27 "Kernel Key Signature Failed.", 22 "Kernel Key Signature Failed.",
28 "Invalid Kernel Verification Algorithm.", 23 "Invalid Kernel Verification Algorithm.",
29 "Config Signature Failed.", 24 "Config Signature Failed.",
30 "Kernel Signature Failed.", 25 "Kernel Signature Failed.",
31 "Wrong Kernel Magic.", 26 "Wrong Kernel Magic.",
32 }; 27 };
33 28
29 uint64_t GetVblockHeaderSize(const uint8_t* vkernel_blob) {
30 uint64_t len = 0;
31 uint16_t firmware_sign_algorithm;
32 uint16_t kernel_sign_algorithm;
33 int algorithms_offset = (FIELD_LEN(magic) +
34 FIELD_LEN(header_version) +
35 FIELD_LEN(header_len));
36 if (SafeMemcmp(vkernel_blob, KERNEL_MAGIC, KERNEL_MAGIC_SIZE)) {
37 debug("Not a valid verified boot kernel blob.\n");
38 return 0;
39 }
40 Memcpy(&firmware_sign_algorithm,
41 vkernel_blob + algorithms_offset,
42 sizeof(firmware_sign_algorithm));
43 Memcpy(&kernel_sign_algorithm,
44 vkernel_blob + algorithms_offset + FIELD_LEN(kernel_sign_algorithm),
45 sizeof(kernel_sign_algorithm));
46 if (firmware_sign_algorithm >= kNumAlgorithms) {
47 debug("Invalid firmware signing algorithm.\n");
48 return 0;
49 }
50 if (kernel_sign_algorithm >= kNumAlgorithms) {
51 debug("Invalid kernel signing algorithm.\n");
52 return 0;
53 }
54 len = algorithms_offset; /* magic, header length and version. */
55 len += (FIELD_LEN(firmware_sign_algorithm) +
56 FIELD_LEN(kernel_sign_algorithm) +
57 FIELD_LEN(kernel_key_version) +
58 RSAProcessedKeySize(kernel_sign_algorithm) + /* kernel_sign_key */
59 FIELD_LEN(header_checksum) +
60 siglen_map[firmware_sign_algorithm] + /* kernel_key_signature */
61 FIELD_LEN(kernel_version) +
62 FIELD_LEN(kernel_len) +
63 siglen_map[kernel_sign_algorithm] + /* config_signature */
64 siglen_map[kernel_sign_algorithm]); /* kernel_signature */
65 return len;
66 }
67
34 int VerifyKernelHeader(const uint8_t* firmware_key_blob, 68 int VerifyKernelHeader(const uint8_t* firmware_key_blob,
35 const uint8_t* header_blob, 69 const uint8_t* header_blob,
36 const int dev_mode, 70 const int dev_mode,
37 int* firmware_algorithm, 71 int* firmware_algorithm,
38 int* kernel_algorithm, 72 int* kernel_algorithm,
39 int* kernel_header_len) { 73 int* kernel_header_len) {
40 int kernel_sign_key_len; 74 int kernel_sign_key_len;
41 int firmware_sign_key_len; 75 int firmware_sign_key_len;
42 uint16_t header_version, header_len; 76 uint16_t header_version, header_len;
43 uint16_t firmware_sign_algorithm, kernel_sign_algorithm; 77 uint16_t firmware_sign_algorithm, kernel_sign_algorithm;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 firmware_sign_algorithm)) 143 firmware_sign_algorithm))
110 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED; 144 return VERIFY_KERNEL_KEY_SIGNATURE_FAILED;
111 } 145 }
112 return 0; 146 return 0;
113 } 147 }
114 148
115 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key, 149 int VerifyKernelConfig(RSAPublicKey* kernel_sign_key,
116 const uint8_t* config_blob, 150 const uint8_t* config_blob,
117 int algorithm, 151 int algorithm,
118 uint64_t* kernel_len) { 152 uint64_t* kernel_len) {
119 uint64_t len; 153 int signature_len = siglen_map[algorithm];
120 if (!RSAVerifyBinary_f(NULL, kernel_sign_key, /* Key to use */ 154 const uint8_t* config_signature = NULL;
121 config_blob, /* Data to verify */ 155 const uint8_t* kernel_config = NULL;
122 KERNEL_CONFIG_FIELD_LEN, /* Length of data */ 156 uint8_t* digest = NULL;
123 config_blob + KERNEL_CONFIG_FIELD_LEN, /* Expected 157 DigestContext ctx;
124 * Signature */ 158
125 algorithm)) 159 config_signature = config_blob + (FIELD_LEN(kernel_version) +
160 FIELD_LEN(kernel_len));
161 kernel_config = config_signature + 2 * signature_len; /* kernel and config
162 * signature. */
163 /* Since the kernel config signature is computed over the kernel version,
164 * kernel length and config, which does not form a contiguous region memory,
165 * we calculate the message digest ourselves. */
166 DigestInit(&ctx, algorithm);
167 DigestUpdate(&ctx,
168 config_blob,
169 FIELD_LEN(kernel_version) + FIELD_LEN(kernel_len));
170 DigestUpdate(&ctx,
171 kernel_config,
172 FIELD_LEN(kernel_config));
173 digest = DigestFinal(&ctx);
174 if (!RSAVerifyBinaryWithDigest_f(
175 NULL, kernel_sign_key, /* Key to use. */
176 digest, /* Digest of the Data to verify. */
177 config_signature, /* Expected signature. */
178 algorithm)) {
179 Free(digest);
126 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED; 180 return VERIFY_KERNEL_CONFIG_SIGNATURE_FAILED;
127 181 }
128 Memcpy(&len, 182 Free(digest);
129 config_blob + (FIELD_LEN(kernel_version) + FIELD_LEN(options.version) + 183 Memcpy(kernel_len,
130 FIELD_LEN(options.cmd_line)), 184 config_blob + FIELD_LEN(kernel_version),
131 sizeof(len)); 185 FIELD_LEN(kernel_len));
132 *kernel_len = len;
133 return 0; 186 return 0;
134 } 187 }
135 188
136 int VerifyKernelData(RSAPublicKey* kernel_sign_key, 189 int VerifyKernelData(RSAPublicKey* kernel_sign_key,
137 const uint8_t* kernel_config_start, 190 const uint8_t* config_blob,
138 const uint8_t* kernel_data_start, 191 const uint8_t* kernel_data,
139 uint64_t kernel_len, 192 uint64_t kernel_len,
140 int algorithm) { 193 int algorithm) {
141 int signature_len = siglen_map[algorithm]; 194 int signature_len = siglen_map[algorithm];
142 uint8_t* digest; 195 const uint8_t* kernel_signature = NULL;
196 const uint8_t* kernel_config = NULL;
197 uint8_t* digest = NULL;
143 DigestContext ctx; 198 DigestContext ctx;
144 199
145 /* Since the kernel signature is computed over the kernel version, options 200 kernel_signature = config_blob + (FIELD_LEN(kernel_version) +
146 * and data, which does not form a contiguous region of memory, we calculate 201 FIELD_LEN(kernel_len) +
147 * the message digest ourselves. */ 202 signature_len);
203 kernel_config = kernel_signature + signature_len;
204
205 /* Since the kernel signature is computed over the kernel version, length,
206 * config cmd line, and kernel image data, which does not form a contiguous
207 * region of memory, we calculate the message digest ourselves. */
148 DigestInit(&ctx, algorithm); 208 DigestInit(&ctx, algorithm);
149 DigestUpdate(&ctx, kernel_config_start, KERNEL_CONFIG_FIELD_LEN); 209 DigestUpdate(&ctx,
150 DigestUpdate(&ctx, kernel_data_start + signature_len, kernel_len); 210 config_blob,
211 FIELD_LEN(kernel_version) + FIELD_LEN(kernel_len));
212 DigestUpdate(&ctx, kernel_config,
213 FIELD_LEN(kernel_config));
214 DigestUpdate(&ctx, kernel_data, kernel_len);
151 digest = DigestFinal(&ctx); 215 digest = DigestFinal(&ctx);
152 if (!RSAVerifyBinaryWithDigest_f( 216 if (!RSAVerifyBinaryWithDigest_f(
153 NULL, kernel_sign_key, /* Key to use. */ 217 NULL, kernel_sign_key, /* Key to use. */
154 digest, /* Digest of the data to verify. */ 218 digest, /* Digest of the data to verify. */
155 kernel_data_start, /* Expected Signature */ 219 kernel_signature, /* Expected Signature */
156 algorithm)) { 220 algorithm)) {
157 Free(digest); 221 Free(digest);
158 return VERIFY_KERNEL_SIGNATURE_FAILED; 222 return VERIFY_KERNEL_SIGNATURE_FAILED;
159 } 223 }
160 Free(digest); 224 Free(digest);
161 return 0; 225 return 0;
162 } 226 }
163 227
164 int VerifyKernel(const uint8_t* firmware_key_blob, 228 int VerifyKernel(const uint8_t* firmware_key_blob,
165 const uint8_t* kernel_blob, 229 const uint8_t* kernel_blob,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 /* Only continue if config verification succeeds. */ 271 /* Only continue if config verification succeeds. */
208 config_ptr = (header_ptr + header_len + kernel_key_signature_len); 272 config_ptr = (header_ptr + header_len + kernel_key_signature_len);
209 if ((error_code = VerifyKernelConfig(kernel_sign_key, config_ptr, 273 if ((error_code = VerifyKernelConfig(kernel_sign_key, config_ptr,
210 kernel_sign_algorithm, 274 kernel_sign_algorithm,
211 &kernel_len))) { 275 &kernel_len))) {
212 RSAPublicKeyFree(kernel_sign_key); 276 RSAPublicKeyFree(kernel_sign_key);
213 return error_code; /* AKA jump to recovery. */ 277 return error_code; /* AKA jump to recovery. */
214 } 278 }
215 /* Only continue if kernel data verification succeeds. */ 279 /* Only continue if kernel data verification succeeds. */
216 kernel_ptr = (config_ptr + 280 kernel_ptr = (config_ptr +
217 KERNEL_CONFIG_FIELD_LEN + /* Skip config block/signature. */ 281 FIELD_LEN(kernel_version) +
218 kernel_signature_len); 282 FIELD_LEN(kernel_len) +
283 2 * kernel_signature_len + /* config and kernel signature. */
284 FIELD_LEN(kernel_config));
219 285
220 if ((error_code = VerifyKernelData(kernel_sign_key, config_ptr, kernel_ptr, 286 if ((error_code = VerifyKernelData(kernel_sign_key, /* Verification key */
221 kernel_len, 287 config_ptr, /* Start of config block */
288 kernel_ptr, /* Start of kernel image */
289 kernel_len, /* Length of kernel image. */
222 kernel_sign_algorithm))) { 290 kernel_sign_algorithm))) {
223 RSAPublicKeyFree(kernel_sign_key); 291 RSAPublicKeyFree(kernel_sign_key);
224 return error_code; /* AKA jump to recovery. */ 292 return error_code; /* AKA jump to recovery. */
225 } 293 }
226 RSAPublicKeyFree(kernel_sign_key); 294 RSAPublicKeyFree(kernel_sign_key);
227 return 0; /* Success! */ 295 return 0; /* Success! */
228 } 296 }
229 297
230 uint32_t GetLogicalKernelVersion(uint8_t* kernel_blob) { 298 uint32_t GetLogicalKernelVersion(uint8_t* kernel_blob) {
231 uint8_t* kernel_ptr; 299 uint8_t* kernel_ptr;
232 uint16_t kernel_key_version; 300 uint16_t kernel_key_version;
233 uint16_t kernel_version; 301 uint16_t kernel_version;
234 uint16_t firmware_sign_algorithm; 302 uint16_t firmware_sign_algorithm;
235 uint16_t kernel_sign_algorithm; 303 uint16_t kernel_sign_algorithm;
236 int kernel_key_signature_len; 304 int kernel_key_signature_len;
237 int kernel_sign_key_len; 305 int kernel_sign_key_len;
238 kernel_ptr = kernel_blob + (FIELD_LEN(magic) + 306 kernel_ptr = kernel_blob + (FIELD_LEN(magic) +
239 FIELD_LEN(header_version) + 307 FIELD_LEN(header_version) +
240 FIELD_LEN(header_len)); 308 FIELD_LEN(header_len));
241 Memcpy(&firmware_sign_algorithm, kernel_ptr, sizeof(firmware_sign_algorithm)); 309 Memcpy(&firmware_sign_algorithm, kernel_ptr, sizeof(firmware_sign_algorithm));
242 kernel_ptr += FIELD_LEN(firmware_sign_algorithm); 310 kernel_ptr += FIELD_LEN(firmware_sign_algorithm);
243 Memcpy(&kernel_sign_algorithm, kernel_ptr, sizeof(kernel_sign_algorithm)); 311 Memcpy(&kernel_sign_algorithm, kernel_ptr, sizeof(kernel_sign_algorithm));
244 kernel_ptr += FIELD_LEN(kernel_sign_algorithm); 312 kernel_ptr += FIELD_LEN(kernel_sign_algorithm);
245 Memcpy(&kernel_key_version, kernel_ptr, sizeof(kernel_key_version)); 313 Memcpy(&kernel_key_version, kernel_ptr, sizeof(kernel_key_version));
246 314
247 if (firmware_sign_algorithm >= kNumAlgorithms) 315 if (firmware_sign_algorithm >= kNumAlgorithms)
248 return 0; 316 return 0;
249 if (kernel_sign_algorithm >= kNumAlgorithms) 317 if (kernel_sign_algorithm >= kNumAlgorithms)
250 return 0; 318 return 0;
319
251 kernel_key_signature_len = siglen_map[firmware_sign_algorithm]; 320 kernel_key_signature_len = siglen_map[firmware_sign_algorithm];
252 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm); 321 kernel_sign_key_len = RSAProcessedKeySize(kernel_sign_algorithm);
253 kernel_ptr += (FIELD_LEN(kernel_key_version) + 322 kernel_ptr += (FIELD_LEN(kernel_key_version) +
254 kernel_sign_key_len + 323 kernel_sign_key_len +
255 FIELD_LEN(header_checksum) + 324 FIELD_LEN(header_checksum) +
256 kernel_key_signature_len); 325 kernel_key_signature_len);
257 Memcpy(&kernel_version, kernel_ptr, sizeof(kernel_version)); 326 Memcpy(&kernel_version, kernel_ptr, sizeof(kernel_version));
258 return CombineUint16Pair(kernel_key_version, kernel_version); 327 return CombineUint16Pair(kernel_key_version, kernel_version);
259 } 328 }
260 329
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 /* Lock Kernel TPM rollback indices from further writes. 426 /* Lock Kernel TPM rollback indices from further writes.
358 * TODO(gauravsh): Figure out if these can be combined into one 427 * TODO(gauravsh): Figure out if these can be combined into one
359 * 32-bit location since we seem to always use them together. This can help 428 * 32-bit location since we seem to always use them together. This can help
360 * us minimize the number of NVRAM writes/locks (which are limited over flash 429 * us minimize the number of NVRAM writes/locks (which are limited over flash
361 * memory lifetimes. 430 * memory lifetimes.
362 */ 431 */
363 LockStoredVersion(KERNEL_KEY_VERSION); 432 LockStoredVersion(KERNEL_KEY_VERSION);
364 LockStoredVersion(KERNEL_VERSION); 433 LockStoredVersion(KERNEL_VERSION);
365 return kernel_to_boot; 434 return kernel_to_boot;
366 } 435 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698