blob: c5838ffaed556dc5d172343bdc0d082bfdd9d019 [file] [log] [blame]
Gaurav Shah431b9882010-02-12 15:54:37 -08001/* 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
3 * found in the LICENSE file.
4 *
5 * Functions for generating and manipulating a verified boot firmware image.
6 */
7
8#include "firmware_image.h"
9
10#include <fcntl.h>
11#include <limits.h>
12#include <stdio.h>
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <unistd.h>
16
Gaurav Shah08df9b82010-02-23 16:16:23 -080017#include "file_keys.h"
Gaurav Shah431b9882010-02-12 15:54:37 -080018#include "padding.h"
19#include "rsa_utility.h"
20#include "sha_utility.h"
Gaurav Shahf5564fa2010-03-02 15:40:01 -080021#include "signature_digest.h"
Gaurav Shah431b9882010-02-12 15:54:37 -080022#include "utility.h"
23
Gaurav Shah08df9b82010-02-23 16:16:23 -080024/* Macro to determine the size of a field structure in the FirmwareImage
25 * structure. */
26#define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field))
Gaurav Shah431b9882010-02-12 15:54:37 -080027
28FirmwareImage* FirmwareImageNew(void) {
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080029 FirmwareImage* image = (FirmwareImage*) Malloc(sizeof(FirmwareImage));
30 if (image) {
Gaurav Shahf5564fa2010-03-02 15:40:01 -080031 image->firmware_sign_key = NULL;
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080032 image->preamble_signature = NULL;
33 image->firmware_signature = NULL;
34 image->firmware_data = NULL;
35 }
36 return image;
Gaurav Shah431b9882010-02-12 15:54:37 -080037}
38
39void FirmwareImageFree(FirmwareImage* image) {
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080040 if (image) {
Gaurav Shahf5564fa2010-03-02 15:40:01 -080041 Free(image->firmware_sign_key);
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080042 Free(image->preamble_signature);
43 Free(image->firmware_signature);
44 Free(image->firmware_data);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080045 Free(image);
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080046 }
Gaurav Shah431b9882010-02-12 15:54:37 -080047}
48
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080049FirmwareImage* ReadFirmwareImage(const char* input_file) {
50 uint32_t file_size;
Gaurav Shah431b9882010-02-12 15:54:37 -080051 int image_len = 0; /* Total size of the firmware image. */
52 int header_len = 0;
Gaurav Shahf5564fa2010-03-02 15:40:01 -080053 int firmware_sign_key_len;
Gaurav Shah431b9882010-02-12 15:54:37 -080054 int signature_len;
55 uint8_t* firmware_buf;
56 MemcpyState st;
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080057 FirmwareImage* image = FirmwareImageNew();
Gaurav Shah431b9882010-02-12 15:54:37 -080058
59 if (!image)
60 return NULL;
61
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080062 firmware_buf = BufferFromFile(input_file, &file_size);
63 image_len = file_size;
Gaurav Shah431b9882010-02-12 15:54:37 -080064
65 st.remaining_len = image_len;
66 st.remaining_buf = firmware_buf;
67
68 /* Read and compare magic bytes. */
Gaurav Shahf5564fa2010-03-02 15:40:01 -080069 StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE);
Gaurav Shah08df9b82010-02-23 16:16:23 -080070 if (SafeMemcmp(image->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) {
Gaurav Shah431b9882010-02-12 15:54:37 -080071 fprintf(stderr, "Wrong Firmware Magic.\n");
Gaurav Shahf5564fa2010-03-02 15:40:01 -080072 Free(firmware_buf);
73 return NULL;
Gaurav Shah431b9882010-02-12 15:54:37 -080074 }
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080075 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len));
Gaurav Shahf5564fa2010-03-02 15:40:01 -080076 StatefulMemcpy(&st, &image->firmware_sign_algorithm,
77 FIELD_LEN(firmware_sign_algorithm));
Gaurav Shah431b9882010-02-12 15:54:37 -080078
79 /* Valid Algorithm? */
Gaurav Shahf5564fa2010-03-02 15:40:01 -080080 if (image->firmware_sign_algorithm >= kNumAlgorithms) {
81 Free(firmware_buf);
82 return NULL;
83 }
Gaurav Shah431b9882010-02-12 15:54:37 -080084
85 /* Compute size of pre-processed RSA public key and signature. */
Gaurav Shahf5564fa2010-03-02 15:40:01 -080086 firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm);
87 signature_len = siglen_map[image->firmware_sign_algorithm];
Gaurav Shah431b9882010-02-12 15:54:37 -080088
89 /* Check whether the header length is correct. */
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080090 header_len = (FIELD_LEN(header_len) +
Gaurav Shahf5564fa2010-03-02 15:40:01 -080091 FIELD_LEN(firmware_sign_algorithm) +
92 firmware_sign_key_len +
93 FIELD_LEN(firmware_key_version) +
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080094 FIELD_LEN(header_checksum));
Gaurav Shah431b9882010-02-12 15:54:37 -080095 if (header_len != image->header_len) {
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080096 fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n",
97 image->header_len, header_len);
Gaurav Shahf5564fa2010-03-02 15:40:01 -080098 Free(firmware_buf);
99 return NULL;
Gaurav Shah431b9882010-02-12 15:54:37 -0800100 }
101
102 /* Read pre-processed public half of the sign key. */
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800103 image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len);
104 StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len);
105 StatefulMemcpy(&st, &image->firmware_key_version,
106 FIELD_LEN(firmware_key_version));
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800107 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum));
Gaurav Shah431b9882010-02-12 15:54:37 -0800108
109 /* Read key signature. */
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800110 StatefulMemcpy(&st, image->firmware_key_signature,
111 FIELD_LEN(firmware_key_signature));
Gaurav Shah431b9882010-02-12 15:54:37 -0800112
113 /* Read the firmware preamble. */
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800114 StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version));
115 StatefulMemcpy(&st, &image->firmware_len, FIELD_LEN(firmware_len));
116 StatefulMemcpy(&st, image->preamble, FIELD_LEN(preamble));
Gaurav Shah431b9882010-02-12 15:54:37 -0800117
118 /* Read firmware preamble signature. */
119 image->preamble_signature = (uint8_t*) Malloc(signature_len);
120 StatefulMemcpy(&st, image->preamble_signature, signature_len);
121
122 image->firmware_signature = (uint8_t*) Malloc(signature_len);
123 StatefulMemcpy(&st, image->firmware_signature, signature_len);
124
125 image->firmware_data = (uint8_t*) Malloc(image->firmware_len);
126 StatefulMemcpy(&st, image->firmware_data, image->firmware_len);
127
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800128 if(st.remaining_len != 0) { /* Overrun or underrun. */
129 Free(firmware_buf);
Gaurav Shah08df9b82010-02-23 16:16:23 -0800130 return NULL;
131 }
Gaurav Shah431b9882010-02-12 15:54:37 -0800132
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800133 Free(firmware_buf);
Gaurav Shah08df9b82010-02-23 16:16:23 -0800134 return image;
Gaurav Shah431b9882010-02-12 15:54:37 -0800135}
136
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800137int GetFirmwareHeaderLen(const FirmwareImage* image) {
Gaurav Shah80d129b2010-03-03 17:58:43 -0800138 return (FIELD_LEN(header_len) + FIELD_LEN(firmware_sign_algorithm) +
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800139 RSAProcessedKeySize(image->firmware_sign_algorithm) +
140 FIELD_LEN(firmware_key_version) + FIELD_LEN(header_checksum));
141}
142
143uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) {
144 uint8_t* header_blob = NULL;
145 MemcpyState st;
146
147 header_blob = (uint8_t*) Malloc(GetFirmwareHeaderLen(image));
148 st.remaining_len = GetFirmwareHeaderLen(image);
149 st.remaining_buf = header_blob;
150
151 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len));
152 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, FIELD_LEN(header_len));
153 StatefulMemcpy_r(&st, image->firmware_sign_key,
154 RSAProcessedKeySize(image->firmware_sign_algorithm));
155 StatefulMemcpy_r(&st, &image->firmware_key_version,
156 FIELD_LEN(firmware_key_version));
157 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum));
158
159 if (st.remaining_len != 0) { /* Underrun or Overrun. */
160 Free(header_blob);
161 return NULL;
162 }
163 return header_blob;
164}
165
166int GetFirmwarePreambleLen(const FirmwareImage* image) {
167 return (FIELD_LEN(firmware_version) + FIELD_LEN(firmware_len) +
168 FIELD_LEN(preamble));
169}
170
171uint8_t* GetFirmwarePreambleBlob(const FirmwareImage* image) {
172 uint8_t* preamble_blob = NULL;
173 MemcpyState st;
174
175 preamble_blob = (uint8_t*) Malloc(GetFirmwarePreambleLen(image));
176 st.remaining_len = GetFirmwarePreambleLen(image);
177 st.remaining_buf = preamble_blob;
178
179 StatefulMemcpy_r(&st, &image->firmware_version, FIELD_LEN(firmware_version));
180 StatefulMemcpy_r(&st, &image->firmware_len, FIELD_LEN(firmware_len));
181 StatefulMemcpy_r(&st, image->preamble, FIELD_LEN(preamble));
182
183 if (st.remaining_len != 0 ) { /* Underrun or Overrun. */
184 Free(preamble_blob);
185 return NULL;
186 }
187 return preamble_blob;
188}
189
190
191uint8_t* GetFirmwareBlob(const FirmwareImage* image, int* blob_len) {
192 int firmware_signature_len;
193 uint8_t* firmware_blob = NULL;
194 uint8_t* header_blob = NULL;
195 uint8_t* preamble_blob = NULL;
196 MemcpyState st;
197
198 if (!image)
199 return NULL;
200
201 firmware_signature_len = siglen_map[image->firmware_sign_algorithm];
202 *blob_len = (FIELD_LEN(magic) +
203 GetFirmwareHeaderLen(image) +
204 FIELD_LEN(firmware_key_signature) +
205 GetFirmwarePreambleLen(image) +
206 2 * firmware_signature_len +
207 image->firmware_len);
208 firmware_blob = (uint8_t*) Malloc(*blob_len);
209 st.remaining_len = *blob_len;
210 st.remaining_buf = firmware_blob;
211
212 header_blob = GetFirmwareHeaderBlob(image);
213 preamble_blob = GetFirmwarePreambleBlob(image);
214
215 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic));
216 StatefulMemcpy_r(&st, header_blob, GetFirmwareHeaderLen(image));
217 StatefulMemcpy_r(&st, image->firmware_key_signature,
218 FIELD_LEN(firmware_key_signature));
219 StatefulMemcpy_r(&st, preamble_blob, GetFirmwarePreambleLen(image));
220 StatefulMemcpy_r(&st, image->preamble_signature, firmware_signature_len);
221 StatefulMemcpy_r(&st, image->firmware_signature, firmware_signature_len);
222 StatefulMemcpy_r(&st, image->firmware_data, image->firmware_len);
223
224 Free(preamble_blob);
225 Free(header_blob);
226
227 if (st.remaining_len != 0) { /* Underrun or Overrun. */
228 Free(firmware_blob);
229 return NULL;
230 }
231 return firmware_blob;
232}
233
234int WriteFirmwareImage(const char* input_file,
235 const FirmwareImage* image) {
236 int fd;
237 uint8_t* firmware_blob;
238 int blob_len;
239
240 if (!image)
241 return 0;
242 if (-1 == (fd = creat(input_file, S_IRWXU))) {
243 fprintf(stderr, "Couldn't open file for writing.\n");
244 return 0;
245 }
246
247 firmware_blob = GetFirmwareBlob(image, &blob_len);
248 if (!firmware_blob) {
249 fprintf(stderr, "Couldn't create firmware blob from FirmwareImage.\n");
250 return 0;
251 }
252 if (blob_len != write(fd, firmware_blob, blob_len)) {
253 fprintf(stderr, "Couldn't write Firmware Image to file: %s\n", input_file);
254 Free(firmware_blob);
255 close(fd);
256 return 0;
257 }
258 Free(firmware_blob);
259 close(fd);
260 return 1;
261}
262
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800263void PrintFirmwareImage(const FirmwareImage* image) {
Gaurav Shah431b9882010-02-12 15:54:37 -0800264 if (!image)
265 return;
266
267 /* Print header. */
268 printf("Header Length = %d\n"
269 "Algorithm Id = %d\n"
270 "Signature Algorithm = %s\n"
271 "Key Version = %d\n\n",
272 image->header_len,
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800273 image->firmware_sign_algorithm,
274 algo_strings[image->firmware_sign_algorithm],
275 image->firmware_key_version);
Gaurav Shah431b9882010-02-12 15:54:37 -0800276 /* TODO(gauravsh): Output hash and key signature here? */
277 /* Print preamble. */
278 printf("Firmware Version = %d\n"
279 "Firmware Length = %d\n\n",
280 image->firmware_version,
281 image->firmware_len);
282 /* Output key signature here? */
283}
284
Gaurav Shah08df9b82010-02-23 16:16:23 -0800285char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX] = {
286 "Success.",
287 "Invalid Image.",
288 "Root Key Signature Failed.",
289 "Invalid Verification Algorithm.",
290 "Preamble Signature Failed.",
291 "Firmware Signature Failed.",
292 "Wrong Firmware Magic.",
293};
294
295int VerifyFirmwareHeader(const uint8_t* root_key_blob,
296 const uint8_t* header_blob,
297 const int dev_mode,
298 int* algorithm,
299 int* header_len) {
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800300 int firmware_sign_key_len;
Gaurav Shah08df9b82010-02-23 16:16:23 -0800301 int root_key_len;
302 uint16_t hlen, algo;
303 uint8_t* header_checksum = NULL;
304
305 /* Base Offset for the header_checksum field. Actual offset is
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800306 * this + firmware_sign_key_len. */
Gaurav Shah08df9b82010-02-23 16:16:23 -0800307 int base_header_checksum_offset = (FIELD_LEN(header_len) +
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800308 FIELD_LEN(firmware_sign_algorithm) +
309 FIELD_LEN(firmware_key_version));
Gaurav Shah08df9b82010-02-23 16:16:23 -0800310
311
312 root_key_len = RSAProcessedKeySize(ROOT_SIGNATURE_ALGORITHM);
313 Memcpy(&hlen, header_blob, sizeof(hlen));
314 Memcpy(&algo,
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800315 header_blob + FIELD_LEN(firmware_sign_algorithm),
Gaurav Shah08df9b82010-02-23 16:16:23 -0800316 sizeof(algo));
317 if (algo >= kNumAlgorithms)
318 return VERIFY_FIRMWARE_INVALID_ALGORITHM;
319 *algorithm = (int) algo;
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800320 firmware_sign_key_len = RSAProcessedKeySize(*algorithm);
Gaurav Shah08df9b82010-02-23 16:16:23 -0800321
322 /* Verify if header len is correct? */
323 if (hlen != (base_header_checksum_offset +
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800324 firmware_sign_key_len +
Gaurav Shah08df9b82010-02-23 16:16:23 -0800325 FIELD_LEN(header_checksum)))
326 return VERIFY_FIRMWARE_INVALID_IMAGE;
327
328 *header_len = (int) hlen;
329
330 /* Verify if the hash of the header is correct. */
331 header_checksum = DigestBuf(header_blob,
332 *header_len - FIELD_LEN(header_checksum),
333 SHA512_DIGEST_ALGORITHM);
334 if (SafeMemcmp(header_checksum,
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800335 header_blob + (base_header_checksum_offset +
336 firmware_sign_key_len),
Gaurav Shah08df9b82010-02-23 16:16:23 -0800337 FIELD_LEN(header_checksum))) {
338 Free(header_checksum);
339 return VERIFY_FIRMWARE_INVALID_IMAGE;
340 }
341 Free(header_checksum);
342
343 /* Verify root key signature unless we are in dev mode. */
344 if (!dev_mode) {
345 if (!RSAVerifyBinary_f(root_key_blob, NULL, /* Key to use */
346 header_blob, /* Data to verify */
347 *header_len, /* Length of data */
348 header_blob + *header_len, /* Expected Signature */
349 ROOT_SIGNATURE_ALGORITHM))
350 return VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED;
351 }
352 return 0;
353}
354
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800355int VerifyFirmwarePreamble(RSAPublicKey* firmware_sign_key,
Gaurav Shah08df9b82010-02-23 16:16:23 -0800356 const uint8_t* preamble_blob,
357 int algorithm,
358 int* firmware_len) {
359 uint32_t len;
360 int preamble_len;
361 preamble_len = (FIELD_LEN(firmware_version) +
362 FIELD_LEN(firmware_len) +
363 FIELD_LEN(preamble));
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800364 if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use */
Gaurav Shah08df9b82010-02-23 16:16:23 -0800365 preamble_blob, /* Data to verify */
366 preamble_len, /* Length of data */
367 preamble_blob + preamble_len, /* Expected Signature */
368 algorithm))
369 return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED;
370
371 Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version),
372 sizeof(len));
373 *firmware_len = (int) len;
374 return 0;
375}
376
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800377int VerifyFirmwareData(RSAPublicKey* firmware_sign_key,
Gaurav Shah08df9b82010-02-23 16:16:23 -0800378 const uint8_t* firmware_data_start,
379 int firmware_len,
380 int algorithm) {
Gaurav Shahcae5fa62010-02-28 20:02:29 -0800381 int signature_len = siglen_map[algorithm];
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800382 if (!RSAVerifyBinary_f(NULL, firmware_sign_key, /* Key to use. */
Gaurav Shah08df9b82010-02-23 16:16:23 -0800383 firmware_data_start + signature_len, /* Data to
384 * verify */
385 firmware_len, /* Length of data. */
386 firmware_data_start, /* Expected Signature */
387 algorithm))
388 return VERIFY_FIRMWARE_SIGNATURE_FAILED;
389 return 0;
390}
391
392int VerifyFirmware(const uint8_t* root_key_blob,
393 const uint8_t* firmware_blob,
Gaurav Shah431b9882010-02-12 15:54:37 -0800394 const int dev_mode) {
Gaurav Shah08df9b82010-02-23 16:16:23 -0800395 int error_code;
396 int algorithm; /* Signing key algorithm. */
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800397 RSAPublicKey* firmware_sign_key;
398 int firmware_sign_key_len, signature_len, header_len, firmware_len;
Gaurav Shah08df9b82010-02-23 16:16:23 -0800399 const uint8_t* header_ptr; /* Pointer to header. */
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800400 const uint8_t* firmware_sign_key_ptr; /* Pointer to signing key. */
Gaurav Shah08df9b82010-02-23 16:16:23 -0800401 const uint8_t* preamble_ptr; /* Pointer to preamble block. */
402 const uint8_t* firmware_ptr; /* Pointer to firmware signature/data. */
403
404 /* Note: All the offset calculations are based on struct FirmwareImage which
405 * is defined in include/firmware_image.h. */
406
407 /* Compare magic bytes. */
408 if (SafeMemcmp(firmware_blob, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE))
409 return VERIFY_FIRMWARE_WRONG_MAGIC;
410 header_ptr = firmware_blob + FIRMWARE_MAGIC_SIZE;
411
412 /* Only continue if header verification succeeds. */
413 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, dev_mode,
414 &algorithm, &header_len)))
415 return error_code; /* AKA jump to revovery. */
416
417 /* Parse signing key into RSAPublicKey structure since it is required multiple
418 * times. */
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800419 firmware_sign_key_len = RSAProcessedKeySize(algorithm);
420 firmware_sign_key_ptr = header_ptr + (FIELD_LEN(header_len) +
421 FIELD_LEN(firmware_sign_algorithm));
422 firmware_sign_key = RSAPublicKeyFromBuf(firmware_sign_key_ptr,
423 firmware_sign_key_len);
Gaurav Shahcae5fa62010-02-28 20:02:29 -0800424 signature_len = siglen_map[algorithm];
Gaurav Shah08df9b82010-02-23 16:16:23 -0800425
426 /* Only continue if preamble verification succeeds. */
427 preamble_ptr = (header_ptr + header_len +
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800428 FIELD_LEN(firmware_key_signature));
429 if ((error_code = VerifyFirmwarePreamble(firmware_sign_key, preamble_ptr,
430 algorithm,
Gaurav Shah08df9b82010-02-23 16:16:23 -0800431 &firmware_len)))
432 return error_code; /* AKA jump to recovery. */
433
434 /* Only continue if firmware data verification succeeds. */
435 firmware_ptr = (preamble_ptr +
436 FIELD_LEN(firmware_version) +
437 FIELD_LEN(firmware_len) +
438 FIELD_LEN(preamble) +
439 signature_len);
440
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800441 if ((error_code = VerifyFirmwareData(firmware_sign_key, firmware_ptr,
442 firmware_len,
Gaurav Shah08df9b82010-02-23 16:16:23 -0800443 algorithm)))
444 return error_code; /* AKA jump to recovery. */
445
446 return 0; /* Success! */
447}
448
449int VerifyFirmwareImage(const RSAPublicKey* root_key,
450 const FirmwareImage* image,
451 const int dev_mode) {
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800452 RSAPublicKey* firmware_sign_key;
Gaurav Shah431b9882010-02-12 15:54:37 -0800453 uint8_t* header_digest = NULL;
454 uint8_t* preamble_digest = NULL;
455 uint8_t* firmware_digest = NULL;
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800456 int firmware_sign_key_size;
Gaurav Shah431b9882010-02-12 15:54:37 -0800457 int signature_size;
458 int error_code = 0;
459 DigestContext ctx;
460
461 if (!image)
Gaurav Shah08df9b82010-02-23 16:16:23 -0800462 return VERIFY_FIRMWARE_INVALID_IMAGE;
Gaurav Shah431b9882010-02-12 15:54:37 -0800463
464 /* Verify root key signature on the sign key header if we
Gaurav Shah08df9b82010-02-23 16:16:23 -0800465 * are not in dev mode.
466 *
467 * TODO(gauravsh): Add additional sanity checks here for:
468 * 1) verifying the header length is correct.
469 * 2) header_checksum is correct.
470 */
Gaurav Shah431b9882010-02-12 15:54:37 -0800471 if (!dev_mode) {
472 DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM);
473 DigestUpdate(&ctx, (uint8_t*) &image->header_len,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800474 FIELD_LEN(header_len));
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800475 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm,
476 FIELD_LEN(firmware_sign_algorithm));
477 DigestUpdate(&ctx, image->firmware_sign_key,
478 RSAProcessedKeySize(image->firmware_sign_algorithm));
479 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version,
480 FIELD_LEN(firmware_key_version));
Gaurav Shah08df9b82010-02-23 16:16:23 -0800481 DigestUpdate(&ctx, image->header_checksum,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800482 FIELD_LEN(header_checksum));
Gaurav Shah431b9882010-02-12 15:54:37 -0800483 header_digest = DigestFinal(&ctx);
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800484 if (!RSAVerify(root_key, image->firmware_key_signature,
485 FIELD_LEN(firmware_key_signature),
Gaurav Shah431b9882010-02-12 15:54:37 -0800486 ROOT_SIGNATURE_ALGORITHM,
487 header_digest)) {
Gaurav Shah08df9b82010-02-23 16:16:23 -0800488 error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED;
Gaurav Shah431b9882010-02-12 15:54:37 -0800489 goto verify_failure;
490 }
491 }
492
493 /* Get sign key to verify the rest of the firmware. */
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800494 firmware_sign_key_size = RSAProcessedKeySize(image->firmware_sign_algorithm);
495 firmware_sign_key = RSAPublicKeyFromBuf(image->firmware_sign_key,
496 firmware_sign_key_size);
497 signature_size = siglen_map[image->firmware_sign_algorithm];
Gaurav Shah431b9882010-02-12 15:54:37 -0800498
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800499 if (image->firmware_sign_algorithm >= kNumAlgorithms)
Gaurav Shah08df9b82010-02-23 16:16:23 -0800500 return VERIFY_FIRMWARE_INVALID_ALGORITHM;
Gaurav Shah431b9882010-02-12 15:54:37 -0800501
502 /* Verify firmware preamble signature. */
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800503 DigestInit(&ctx, image->firmware_sign_algorithm);
Gaurav Shah431b9882010-02-12 15:54:37 -0800504 DigestUpdate(&ctx, (uint8_t*) &image->firmware_version,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800505 FIELD_LEN(firmware_version));
Gaurav Shah431b9882010-02-12 15:54:37 -0800506 DigestUpdate(&ctx, (uint8_t*) &image->firmware_len,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800507 FIELD_LEN(firmware_len));
Gaurav Shah431b9882010-02-12 15:54:37 -0800508 DigestUpdate(&ctx, (uint8_t*) &image->preamble,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800509 FIELD_LEN(preamble));
Gaurav Shah431b9882010-02-12 15:54:37 -0800510 preamble_digest = DigestFinal(&ctx);
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800511 if (!RSAVerify(firmware_sign_key, image->preamble_signature,
512 signature_size, image->firmware_sign_algorithm,
Gaurav Shah431b9882010-02-12 15:54:37 -0800513 preamble_digest)) {
Gaurav Shah08df9b82010-02-23 16:16:23 -0800514 error_code = VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED;
Gaurav Shah431b9882010-02-12 15:54:37 -0800515 goto verify_failure;
516 }
517
518 /* Verify firmware signature. */
519 firmware_digest = DigestBuf(image->firmware_data,
520 image->firmware_len,
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800521 image->firmware_sign_algorithm);
522 if (!RSAVerify(firmware_sign_key, image->firmware_signature,
523 signature_size, image->firmware_sign_algorithm,
Gaurav Shah431b9882010-02-12 15:54:37 -0800524 firmware_digest)) {
525 error_code = VERIFY_FIRMWARE_SIGNATURE_FAILED;
526 goto verify_failure;
527 }
528
529verify_failure:
530 Free(firmware_digest);
531 Free(preamble_digest);
532 Free(header_digest);
533 return error_code;
534}
535
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800536const char* VerifyFirmwareErrorString(int error) {
537 return kVerifyFirmwareErrors[error];
538}
Gaurav Shah431b9882010-02-12 15:54:37 -0800539
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800540int AddFirmwareKeySignature(FirmwareImage* image, const char* root_key_file) {
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800541 uint8_t* header_blob = NULL;
Gaurav Shah431b9882010-02-12 15:54:37 -0800542 uint8_t* signature;
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800543 if (!image || !root_key_file)
544 return 0;
545 header_blob = GetFirmwareHeaderBlob(image);
546 if (!header_blob)
547 return 0;
548 if (!(signature = SignatureBuf(header_blob,
549 GetFirmwareHeaderLen(image),
550 root_key_file,
551 ROOT_SIGNATURE_ALGORITHM))) {
552 Free(header_blob);
Gaurav Shah431b9882010-02-12 15:54:37 -0800553 return 0;
554 }
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800555 Memcpy(image->firmware_key_signature, signature, RSA8192NUMBYTES);
556 Free(header_blob);
557 Free(signature);
Gaurav Shah431b9882010-02-12 15:54:37 -0800558 return 1;
559}
560
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800561int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file) {
562 uint8_t* preamble_blob;
Gaurav Shah431b9882010-02-12 15:54:37 -0800563 uint8_t* preamble_signature;
564 uint8_t* firmware_signature;
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800565 int signature_len = siglen_map[image->firmware_sign_algorithm];
Gaurav Shah431b9882010-02-12 15:54:37 -0800566
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800567 preamble_blob = GetFirmwarePreambleBlob(image);
568 if (!(preamble_signature = SignatureBuf(preamble_blob,
569 GetFirmwarePreambleLen(image),
570 signing_key_file,
571 image->firmware_sign_algorithm))) {
572 Free(preamble_blob);
Gaurav Shah431b9882010-02-12 15:54:37 -0800573 return 0;
574 }
Gaurav Shah431b9882010-02-12 15:54:37 -0800575 image->preamble_signature = (uint8_t*) Malloc(signature_len);
576 Memcpy(image->preamble_signature, preamble_signature, signature_len);
577 Free(preamble_signature);
578
Gaurav Shahf5564fa2010-03-02 15:40:01 -0800579 if (!(firmware_signature = SignatureBuf(image->firmware_data,
580 image->firmware_len,
581 signing_key_file,
582 image->firmware_sign_algorithm)))
Gaurav Shah431b9882010-02-12 15:54:37 -0800583 return 0;
Gaurav Shah431b9882010-02-12 15:54:37 -0800584 image->firmware_signature = (uint8_t*) Malloc(signature_len);
585 Memcpy(image->firmware_signature, firmware_signature, signature_len);
586 Free(firmware_signature);
587 return 1;
588}