blob: d5b054970c1a3d3465272f32ef34de9c68a612a0 [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"
21#include "utility.h"
22
Gaurav Shah08df9b82010-02-23 16:16:23 -080023/* Macro to determine the size of a field structure in the FirmwareImage
24 * structure. */
25#define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field))
Gaurav Shah431b9882010-02-12 15:54:37 -080026
27FirmwareImage* FirmwareImageNew(void) {
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080028 FirmwareImage* image = (FirmwareImage*) Malloc(sizeof(FirmwareImage));
29 if (image) {
30 image->sign_key = NULL;
31 image->preamble_signature = NULL;
32 image->firmware_signature = NULL;
33 image->firmware_data = NULL;
34 }
35 return image;
Gaurav Shah431b9882010-02-12 15:54:37 -080036}
37
38void FirmwareImageFree(FirmwareImage* image) {
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080039 if (image) {
40 Free(image->sign_key);
41 Free(image->preamble_signature);
42 Free(image->firmware_signature);
43 Free(image->firmware_data);
44 }
Gaurav Shah431b9882010-02-12 15:54:37 -080045}
46
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080047FirmwareImage* ReadFirmwareImage(const char* input_file) {
48 uint32_t file_size;
Gaurav Shah431b9882010-02-12 15:54:37 -080049 int image_len = 0; /* Total size of the firmware image. */
50 int header_len = 0;
51 int sign_key_len;
52 int signature_len;
53 uint8_t* firmware_buf;
54 MemcpyState st;
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080055 FirmwareImage* image = FirmwareImageNew();
Gaurav Shah431b9882010-02-12 15:54:37 -080056
57 if (!image)
58 return NULL;
59
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080060 firmware_buf = BufferFromFile(input_file, &file_size);
61 image_len = file_size;
Gaurav Shah431b9882010-02-12 15:54:37 -080062
63 st.remaining_len = image_len;
64 st.remaining_buf = firmware_buf;
65
66 /* Read and compare magic bytes. */
67 if (!StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE))
68 goto parse_failure;
69
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");
72 goto parse_failure;
73 }
74
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080075 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len));
76 StatefulMemcpy(&st, &image->sign_algorithm, FIELD_LEN(sign_algorithm));
Gaurav Shah431b9882010-02-12 15:54:37 -080077
78 /* Valid Algorithm? */
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080079 if (image->sign_algorithm >= kNumAlgorithms)
Gaurav Shah431b9882010-02-12 15:54:37 -080080 goto parse_failure;
81
82 /* Compute size of pre-processed RSA public key and signature. */
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080083 sign_key_len = RSAProcessedKeySize(image->sign_algorithm);
Gaurav Shahcae5fa62010-02-28 20:02:29 -080084 signature_len = siglen_map[image->sign_algorithm];
Gaurav Shah431b9882010-02-12 15:54:37 -080085
86
87 /* Check whether the header length is correct. */
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080088 header_len = (FIELD_LEN(header_len) +
89 FIELD_LEN(sign_algorithm) +
90 sign_key_len +
91 FIELD_LEN(key_version) +
92 FIELD_LEN(header_checksum));
Gaurav Shah431b9882010-02-12 15:54:37 -080093 if (header_len != image->header_len) {
Gaurav Shah23a2f3a2010-02-26 15:09:43 -080094 fprintf(stderr, "Header length mismatch. Got: %d Expected: %d\n",
95 image->header_len, header_len);
Gaurav Shah431b9882010-02-12 15:54:37 -080096 goto parse_failure;
97 }
98
99 /* Read pre-processed public half of the sign key. */
100 image->sign_key = (uint8_t*) Malloc(sign_key_len);
101 StatefulMemcpy(&st, image->sign_key, sign_key_len);
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800102 StatefulMemcpy(&st, &image->key_version, FIELD_LEN(key_version));
103 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum));
Gaurav Shah431b9882010-02-12 15:54:37 -0800104
105 /* Read key signature. */
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800106 StatefulMemcpy(&st, image->key_signature, FIELD_LEN(key_signature));
Gaurav Shah431b9882010-02-12 15:54:37 -0800107
108 /* Read the firmware preamble. */
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800109 StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version));
110 StatefulMemcpy(&st, &image->firmware_len, FIELD_LEN(firmware_len));
111 StatefulMemcpy(&st, image->preamble, FIELD_LEN(preamble));
Gaurav Shah431b9882010-02-12 15:54:37 -0800112
113 /* Read firmware preamble signature. */
114 image->preamble_signature = (uint8_t*) Malloc(signature_len);
115 StatefulMemcpy(&st, image->preamble_signature, signature_len);
116
117 image->firmware_signature = (uint8_t*) Malloc(signature_len);
118 StatefulMemcpy(&st, image->firmware_signature, signature_len);
119
120 image->firmware_data = (uint8_t*) Malloc(image->firmware_len);
121 StatefulMemcpy(&st, image->firmware_data, image->firmware_len);
122
123 if(st.remaining_len != 0) /* Overrun or underrun. */
124 goto parse_failure;
125
126 Free(firmware_buf);
127 return image;
128
129parse_failure:
130 Free(firmware_buf);
131 return NULL;
132}
133
134void WriteFirmwareHeader(int fd, FirmwareImage* image) {
135 int sign_key_len;
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800136 write(fd, &image->header_len, FIELD_LEN(header_len));
137 write(fd, &image->sign_algorithm, FIELD_LEN(header_len));
138 sign_key_len = (image->header_len - FIELD_LEN(header_len) -
139 FIELD_LEN(sign_algorithm) -
140 FIELD_LEN(key_version) -
141 FIELD_LEN(header_checksum));
Gaurav Shah431b9882010-02-12 15:54:37 -0800142 write(fd, image->sign_key, sign_key_len);
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800143 write(fd, &image->key_version, FIELD_LEN(key_version));
144 write(fd, &image->header_checksum, FIELD_LEN(header_checksum));
Gaurav Shah431b9882010-02-12 15:54:37 -0800145}
146
147void WriteFirmwarePreamble(int fd, FirmwareImage* image) {
148 write(fd, &image->firmware_version,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800149 FIELD_LEN(firmware_version));
150 write(fd, &image->firmware_len, FIELD_LEN(firmware_len));
151 write(fd, image->preamble, FIELD_LEN(preamble));
Gaurav Shah431b9882010-02-12 15:54:37 -0800152}
153
Gaurav Shah08df9b82010-02-23 16:16:23 -0800154FirmwareImage* WriteFirmwareImage(const char* input_file,
155 FirmwareImage* image) {
156 int fd;
157 int signature_len;
Gaurav Shah431b9882010-02-12 15:54:37 -0800158
Gaurav Shah08df9b82010-02-23 16:16:23 -0800159 if (!image)
160 return NULL;
161 if (-1 == (fd = creat(input_file, S_IRWXU))) {
162 fprintf(stderr, "Couldn't open file for writing.\n");
163 return NULL;
164 }
Gaurav Shah431b9882010-02-12 15:54:37 -0800165
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800166 write(fd, image->magic, FIELD_LEN(magic));
Gaurav Shah08df9b82010-02-23 16:16:23 -0800167 WriteFirmwareHeader(fd, image);
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800168 write(fd, image->key_signature, FIELD_LEN(key_signature));
Gaurav Shahcae5fa62010-02-28 20:02:29 -0800169 signature_len = siglen_map[image->sign_algorithm];
Gaurav Shah08df9b82010-02-23 16:16:23 -0800170 WriteFirmwarePreamble(fd, image);
171 write(fd, image->preamble_signature, signature_len);
172 write(fd, image->firmware_signature, signature_len);
173 write(fd, image->firmware_data, image->firmware_len);
Gaurav Shah431b9882010-02-12 15:54:37 -0800174
Gaurav Shah08df9b82010-02-23 16:16:23 -0800175 close(fd);
176 return image;
Gaurav Shah431b9882010-02-12 15:54:37 -0800177}
178
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800179void PrintFirmwareImage(const FirmwareImage* image) {
Gaurav Shah431b9882010-02-12 15:54:37 -0800180 if (!image)
181 return;
182
183 /* Print header. */
184 printf("Header Length = %d\n"
185 "Algorithm Id = %d\n"
186 "Signature Algorithm = %s\n"
187 "Key Version = %d\n\n",
188 image->header_len,
189 image->sign_algorithm,
190 algo_strings[image->sign_algorithm],
191 image->key_version);
192 /* TODO(gauravsh): Output hash and key signature here? */
193 /* Print preamble. */
194 printf("Firmware Version = %d\n"
195 "Firmware Length = %d\n\n",
196 image->firmware_version,
197 image->firmware_len);
198 /* Output key signature here? */
199}
200
Gaurav Shah08df9b82010-02-23 16:16:23 -0800201char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX] = {
202 "Success.",
203 "Invalid Image.",
204 "Root Key Signature Failed.",
205 "Invalid Verification Algorithm.",
206 "Preamble Signature Failed.",
207 "Firmware Signature Failed.",
208 "Wrong Firmware Magic.",
209};
210
211int VerifyFirmwareHeader(const uint8_t* root_key_blob,
212 const uint8_t* header_blob,
213 const int dev_mode,
214 int* algorithm,
215 int* header_len) {
216 int sign_key_len;
217 int root_key_len;
218 uint16_t hlen, algo;
219 uint8_t* header_checksum = NULL;
220
221 /* Base Offset for the header_checksum field. Actual offset is
222 * this + sign_key_len. */
223 int base_header_checksum_offset = (FIELD_LEN(header_len) +
224 FIELD_LEN(sign_algorithm) +
225 FIELD_LEN(key_version));
226
227
228 root_key_len = RSAProcessedKeySize(ROOT_SIGNATURE_ALGORITHM);
229 Memcpy(&hlen, header_blob, sizeof(hlen));
230 Memcpy(&algo,
231 header_blob + FIELD_LEN(sign_algorithm),
232 sizeof(algo));
233 if (algo >= kNumAlgorithms)
234 return VERIFY_FIRMWARE_INVALID_ALGORITHM;
235 *algorithm = (int) algo;
236 sign_key_len = RSAProcessedKeySize(*algorithm);
237
238 /* Verify if header len is correct? */
239 if (hlen != (base_header_checksum_offset +
240 sign_key_len +
241 FIELD_LEN(header_checksum)))
242 return VERIFY_FIRMWARE_INVALID_IMAGE;
243
244 *header_len = (int) hlen;
245
246 /* Verify if the hash of the header is correct. */
247 header_checksum = DigestBuf(header_blob,
248 *header_len - FIELD_LEN(header_checksum),
249 SHA512_DIGEST_ALGORITHM);
250 if (SafeMemcmp(header_checksum,
251 header_blob + (base_header_checksum_offset + sign_key_len),
252 FIELD_LEN(header_checksum))) {
253 Free(header_checksum);
254 return VERIFY_FIRMWARE_INVALID_IMAGE;
255 }
256 Free(header_checksum);
257
258 /* Verify root key signature unless we are in dev mode. */
259 if (!dev_mode) {
260 if (!RSAVerifyBinary_f(root_key_blob, NULL, /* Key to use */
261 header_blob, /* Data to verify */
262 *header_len, /* Length of data */
263 header_blob + *header_len, /* Expected Signature */
264 ROOT_SIGNATURE_ALGORITHM))
265 return VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED;
266 }
267 return 0;
268}
269
270int VerifyFirmwarePreamble(RSAPublicKey* sign_key,
271 const uint8_t* preamble_blob,
272 int algorithm,
273 int* firmware_len) {
274 uint32_t len;
275 int preamble_len;
276 preamble_len = (FIELD_LEN(firmware_version) +
277 FIELD_LEN(firmware_len) +
278 FIELD_LEN(preamble));
279 if (!RSAVerifyBinary_f(NULL, sign_key, /* Key to use */
280 preamble_blob, /* Data to verify */
281 preamble_len, /* Length of data */
282 preamble_blob + preamble_len, /* Expected Signature */
283 algorithm))
284 return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED;
285
286 Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version),
287 sizeof(len));
288 *firmware_len = (int) len;
289 return 0;
290}
291
292int VerifyFirmwareData(RSAPublicKey* sign_key,
293 const uint8_t* firmware_data_start,
294 int firmware_len,
295 int algorithm) {
Gaurav Shahcae5fa62010-02-28 20:02:29 -0800296 int signature_len = siglen_map[algorithm];
Gaurav Shah08df9b82010-02-23 16:16:23 -0800297 if (!RSAVerifyBinary_f(NULL, sign_key, /* Key to use. */
298 firmware_data_start + signature_len, /* Data to
299 * verify */
300 firmware_len, /* Length of data. */
301 firmware_data_start, /* Expected Signature */
302 algorithm))
303 return VERIFY_FIRMWARE_SIGNATURE_FAILED;
304 return 0;
305}
306
307int VerifyFirmware(const uint8_t* root_key_blob,
308 const uint8_t* firmware_blob,
Gaurav Shah431b9882010-02-12 15:54:37 -0800309 const int dev_mode) {
Gaurav Shah08df9b82010-02-23 16:16:23 -0800310 int error_code;
311 int algorithm; /* Signing key algorithm. */
312 RSAPublicKey* sign_key;
313 int sign_key_len, signature_len, header_len, firmware_len;
314 const uint8_t* header_ptr; /* Pointer to header. */
315 const uint8_t* sign_key_ptr; /* Pointer to signing key. */
316 const uint8_t* preamble_ptr; /* Pointer to preamble block. */
317 const uint8_t* firmware_ptr; /* Pointer to firmware signature/data. */
318
319 /* Note: All the offset calculations are based on struct FirmwareImage which
320 * is defined in include/firmware_image.h. */
321
322 /* Compare magic bytes. */
323 if (SafeMemcmp(firmware_blob, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE))
324 return VERIFY_FIRMWARE_WRONG_MAGIC;
325 header_ptr = firmware_blob + FIRMWARE_MAGIC_SIZE;
326
327 /* Only continue if header verification succeeds. */
328 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, dev_mode,
329 &algorithm, &header_len)))
330 return error_code; /* AKA jump to revovery. */
331
332 /* Parse signing key into RSAPublicKey structure since it is required multiple
333 * times. */
334 sign_key_len = RSAProcessedKeySize(algorithm);
335 sign_key_ptr = header_ptr + (FIELD_LEN(header_len) +
336 FIELD_LEN(sign_algorithm));
337 sign_key = RSAPublicKeyFromBuf(sign_key_ptr, sign_key_len);
Gaurav Shahcae5fa62010-02-28 20:02:29 -0800338 signature_len = siglen_map[algorithm];
Gaurav Shah08df9b82010-02-23 16:16:23 -0800339
340 /* Only continue if preamble verification succeeds. */
341 preamble_ptr = (header_ptr + header_len +
342 FIELD_LEN(key_signature));
343 if ((error_code = VerifyFirmwarePreamble(sign_key, preamble_ptr, algorithm,
344 &firmware_len)))
345 return error_code; /* AKA jump to recovery. */
346
347 /* Only continue if firmware data verification succeeds. */
348 firmware_ptr = (preamble_ptr +
349 FIELD_LEN(firmware_version) +
350 FIELD_LEN(firmware_len) +
351 FIELD_LEN(preamble) +
352 signature_len);
353
354 if ((error_code = VerifyFirmwareData(sign_key, firmware_ptr, firmware_len,
355 algorithm)))
356 return error_code; /* AKA jump to recovery. */
357
358 return 0; /* Success! */
359}
360
361int VerifyFirmwareImage(const RSAPublicKey* root_key,
362 const FirmwareImage* image,
363 const int dev_mode) {
Gaurav Shah431b9882010-02-12 15:54:37 -0800364 RSAPublicKey* sign_key;
365 uint8_t* header_digest = NULL;
366 uint8_t* preamble_digest = NULL;
367 uint8_t* firmware_digest = NULL;
368 int sign_key_size;
369 int signature_size;
370 int error_code = 0;
371 DigestContext ctx;
372
373 if (!image)
Gaurav Shah08df9b82010-02-23 16:16:23 -0800374 return VERIFY_FIRMWARE_INVALID_IMAGE;
Gaurav Shah431b9882010-02-12 15:54:37 -0800375
376 /* Verify root key signature on the sign key header if we
Gaurav Shah08df9b82010-02-23 16:16:23 -0800377 * are not in dev mode.
378 *
379 * TODO(gauravsh): Add additional sanity checks here for:
380 * 1) verifying the header length is correct.
381 * 2) header_checksum is correct.
382 */
Gaurav Shah431b9882010-02-12 15:54:37 -0800383 if (!dev_mode) {
384 DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM);
385 DigestUpdate(&ctx, (uint8_t*) &image->header_len,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800386 FIELD_LEN(header_len));
Gaurav Shah431b9882010-02-12 15:54:37 -0800387 DigestUpdate(&ctx, (uint8_t*) &image->sign_algorithm,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800388 FIELD_LEN(sign_algorithm));
Gaurav Shah431b9882010-02-12 15:54:37 -0800389 DigestUpdate(&ctx, image->sign_key,
390 RSAProcessedKeySize(image->sign_algorithm));
391 DigestUpdate(&ctx, (uint8_t*) &image->key_version,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800392 FIELD_LEN(key_version));
Gaurav Shah08df9b82010-02-23 16:16:23 -0800393 DigestUpdate(&ctx, image->header_checksum,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800394 FIELD_LEN(header_checksum));
Gaurav Shah431b9882010-02-12 15:54:37 -0800395 header_digest = DigestFinal(&ctx);
396 if (!RSA_verify(root_key, image->key_signature,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800397 FIELD_LEN(key_signature),
Gaurav Shah431b9882010-02-12 15:54:37 -0800398 ROOT_SIGNATURE_ALGORITHM,
399 header_digest)) {
Gaurav Shah08df9b82010-02-23 16:16:23 -0800400 error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED;
Gaurav Shah431b9882010-02-12 15:54:37 -0800401 goto verify_failure;
402 }
403 }
404
405 /* Get sign key to verify the rest of the firmware. */
406 sign_key_size = RSAProcessedKeySize(image->sign_algorithm);
407 sign_key = RSAPublicKeyFromBuf(image->sign_key,
408 sign_key_size);
Gaurav Shahcae5fa62010-02-28 20:02:29 -0800409 signature_size = siglen_map[image->sign_algorithm];
Gaurav Shah431b9882010-02-12 15:54:37 -0800410
411 if (image->sign_algorithm >= kNumAlgorithms)
Gaurav Shah08df9b82010-02-23 16:16:23 -0800412 return VERIFY_FIRMWARE_INVALID_ALGORITHM;
Gaurav Shah431b9882010-02-12 15:54:37 -0800413
414 /* Verify firmware preamble signature. */
415 DigestInit(&ctx, image->sign_algorithm);
416 DigestUpdate(&ctx, (uint8_t*) &image->firmware_version,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800417 FIELD_LEN(firmware_version));
Gaurav Shah431b9882010-02-12 15:54:37 -0800418 DigestUpdate(&ctx, (uint8_t*) &image->firmware_len,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800419 FIELD_LEN(firmware_len));
Gaurav Shah431b9882010-02-12 15:54:37 -0800420 DigestUpdate(&ctx, (uint8_t*) &image->preamble,
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800421 FIELD_LEN(preamble));
Gaurav Shah431b9882010-02-12 15:54:37 -0800422 preamble_digest = DigestFinal(&ctx);
423 if (!RSA_verify(sign_key, image->preamble_signature,
424 signature_size, image->sign_algorithm,
425 preamble_digest)) {
Gaurav Shah08df9b82010-02-23 16:16:23 -0800426 error_code = VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED;
Gaurav Shah431b9882010-02-12 15:54:37 -0800427 goto verify_failure;
428 }
429
430 /* Verify firmware signature. */
431 firmware_digest = DigestBuf(image->firmware_data,
432 image->firmware_len,
433 image->sign_algorithm);
434 if(!RSA_verify(sign_key, image->firmware_signature,
435 signature_size, image->sign_algorithm,
436 firmware_digest)) {
437 error_code = VERIFY_FIRMWARE_SIGNATURE_FAILED;
438 goto verify_failure;
439 }
440
441verify_failure:
442 Free(firmware_digest);
443 Free(preamble_digest);
444 Free(header_digest);
445 return error_code;
446}
447
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800448const char* VerifyFirmwareErrorString(int error) {
449 return kVerifyFirmwareErrors[error];
450}
Gaurav Shah431b9882010-02-12 15:54:37 -0800451
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800452int AddFirmwareKeySignature(FirmwareImage* image, const char* root_key_file) {
Gaurav Shah431b9882010-02-12 15:54:37 -0800453 int tmp_hdr_fd;
454 char* tmp_hdr_file = ".tmpHdrFile";
455 uint8_t* signature;
456
457 if(-1 == (tmp_hdr_fd = creat(tmp_hdr_file, S_IRWXU))) {
458 fprintf(stderr, "Could not open temporary file for writing "
459 "firmware header.\n");
460 return 0;
461 }
462 WriteFirmwareHeader(tmp_hdr_fd, image);
463 close(tmp_hdr_fd);
464
465 if (!(signature = SignatureFile(tmp_hdr_file, root_key_file,
466 ROOT_SIGNATURE_ALGORITHM)))
467 return 0;
468 Memcpy(image->key_signature, signature, RSA8192NUMBYTES);
469 return 1;
470}
471
Gaurav Shah23a2f3a2010-02-26 15:09:43 -0800472int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file,
Gaurav Shah431b9882010-02-12 15:54:37 -0800473 int algorithm) {
474 int tmp_preamble_fd;
475 char* tmp_preamble_file = ".tmpPreambleFile";
476 int tmp_firmware_fd;
477 char* tmp_firmware_file = ".tmpFirmwareFile";
478 uint8_t* preamble_signature;
479 uint8_t* firmware_signature;
Gaurav Shahcae5fa62010-02-28 20:02:29 -0800480 int signature_len = siglen_map[algorithm];
Gaurav Shah431b9882010-02-12 15:54:37 -0800481
482 /* Write preamble to a file. */
483 if(-1 == (tmp_preamble_fd = creat(tmp_preamble_file, S_IRWXU))) {
484 fprintf(stderr, "Could not open temporary file for writing "
Gaurav Shah08df9b82010-02-23 16:16:23 -0800485 "firmware preamble.\n");
Gaurav Shah431b9882010-02-12 15:54:37 -0800486 return 0;
487 }
488 WriteFirmwarePreamble(tmp_preamble_fd, image);
489 close(tmp_preamble_fd);
490 if (!(preamble_signature = SignatureFile(tmp_preamble_file, signing_key_file,
491 algorithm)))
492 return 0;
493 image->preamble_signature = (uint8_t*) Malloc(signature_len);
494 Memcpy(image->preamble_signature, preamble_signature, signature_len);
495 Free(preamble_signature);
496
497 if (-1 == (tmp_firmware_fd = creat(tmp_firmware_file, S_IRWXU))) {
498 fprintf(stderr, "Could not open temporary file for writing "
499 "firmware.\n");
500 return 0;
501 }
502 write(tmp_firmware_fd, image->firmware_data, image->firmware_len);
503 close(tmp_firmware_fd);
504
505 if (!(firmware_signature = SignatureFile(tmp_firmware_file, signing_key_file,
506 algorithm))) {
507 fprintf(stderr, "Could not open temporary file for writing "
508 "firmware.\n");
509 return 0;
510 }
511 image->firmware_signature = (uint8_t*) Malloc(signature_len);
512 Memcpy(image->firmware_signature, firmware_signature, signature_len);
513 Free(firmware_signature);
514 return 1;
515}