OLD | NEW |
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 generating and manipulating a verified boot firmware image. | 5 * Functions for generating and manipulating a verified boot firmware image. |
6 */ | 6 */ |
7 | 7 |
8 #include "firmware_image.h" | 8 #include "firmware_image.h" |
9 | 9 |
10 #include <fcntl.h> | 10 #include <fcntl.h> |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 } | 46 } |
47 } | 47 } |
48 | 48 |
49 FirmwareImage* ReadFirmwareImage(const char* input_file) { | 49 FirmwareImage* ReadFirmwareImage(const char* input_file) { |
50 uint64_t file_size; | 50 uint64_t file_size; |
51 int image_len = 0; /* Total size of the firmware image. */ | 51 int image_len = 0; /* Total size of the firmware image. */ |
52 int header_len = 0; | 52 int header_len = 0; |
53 int firmware_sign_key_len; | 53 int firmware_sign_key_len; |
54 int signature_len; | 54 int signature_len; |
55 uint8_t* firmware_buf; | 55 uint8_t* firmware_buf; |
| 56 uint8_t header_checksum[FIELD_LEN(header_checksum)]; |
56 MemcpyState st; | 57 MemcpyState st; |
57 FirmwareImage* image = FirmwareImageNew(); | 58 FirmwareImage* image = FirmwareImageNew(); |
58 | 59 |
59 if (!image) | 60 if (!image) |
60 return NULL; | 61 return NULL; |
61 | 62 |
62 firmware_buf = BufferFromFile(input_file, &file_size); | 63 firmware_buf = BufferFromFile(input_file, &file_size); |
63 image_len = file_size; | 64 image_len = file_size; |
64 | 65 |
65 st.remaining_len = image_len; | 66 st.remaining_len = image_len; |
(...skipping 29 matching lines...) Expand all Loading... |
95 return NULL; | 96 return NULL; |
96 } | 97 } |
97 | 98 |
98 /* Read pre-processed public half of the sign key. */ | 99 /* Read pre-processed public half of the sign key. */ |
99 image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len); | 100 image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len); |
100 StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len); | 101 StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len); |
101 StatefulMemcpy(&st, &image->firmware_key_version, | 102 StatefulMemcpy(&st, &image->firmware_key_version, |
102 FIELD_LEN(firmware_key_version)); | 103 FIELD_LEN(firmware_key_version)); |
103 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); | 104 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); |
104 | 105 |
| 106 /* Check whether the header checksum matches. */ |
| 107 CalculateFirmwareHeaderChecksum(image, header_checksum); |
| 108 if (SafeMemcmp(header_checksum, image->header_checksum, |
| 109 FIELD_LEN(header_checksum))) { |
| 110 fprintf(stderr, "Invalid firmware header checksum!\n"); |
| 111 Free(firmware_buf); |
| 112 return NULL; |
| 113 } |
| 114 |
105 /* Read key signature. */ | 115 /* Read key signature. */ |
106 StatefulMemcpy(&st, image->firmware_key_signature, | 116 StatefulMemcpy(&st, image->firmware_key_signature, |
107 FIELD_LEN(firmware_key_signature)); | 117 FIELD_LEN(firmware_key_signature)); |
108 | 118 |
109 /* Read the firmware preamble. */ | 119 /* Read the firmware preamble. */ |
110 StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version)); | 120 StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version)); |
111 StatefulMemcpy(&st, &image->firmware_len, FIELD_LEN(firmware_len)); | 121 StatefulMemcpy(&st, &image->firmware_len, FIELD_LEN(firmware_len)); |
112 StatefulMemcpy(&st, image->preamble, FIELD_LEN(preamble)); | 122 StatefulMemcpy(&st, image->preamble, FIELD_LEN(preamble)); |
113 | 123 |
114 /* Read firmware preamble signature. */ | 124 /* Read firmware preamble signature. */ |
(...skipping 14 matching lines...) Expand all Loading... |
129 Free(firmware_buf); | 139 Free(firmware_buf); |
130 return image; | 140 return image; |
131 } | 141 } |
132 | 142 |
133 int GetFirmwareHeaderLen(const FirmwareImage* image) { | 143 int GetFirmwareHeaderLen(const FirmwareImage* image) { |
134 return (FIELD_LEN(header_len) + FIELD_LEN(firmware_sign_algorithm) + | 144 return (FIELD_LEN(header_len) + FIELD_LEN(firmware_sign_algorithm) + |
135 RSAProcessedKeySize(image->firmware_sign_algorithm) + | 145 RSAProcessedKeySize(image->firmware_sign_algorithm) + |
136 FIELD_LEN(firmware_key_version) + FIELD_LEN(header_checksum)); | 146 FIELD_LEN(firmware_key_version) + FIELD_LEN(header_checksum)); |
137 } | 147 } |
138 | 148 |
| 149 void CalculateFirmwareHeaderChecksum(const FirmwareImage* image, |
| 150 uint8_t* header_checksum) { |
| 151 uint8_t* checksum; |
| 152 DigestContext ctx; |
| 153 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); |
| 154 DigestUpdate(&ctx, (uint8_t*) &image->header_len, |
| 155 sizeof(image->header_len)); |
| 156 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, |
| 157 sizeof(image->firmware_sign_algorithm)); |
| 158 DigestUpdate(&ctx, image->firmware_sign_key, |
| 159 RSAProcessedKeySize(image->firmware_sign_algorithm)); |
| 160 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version, |
| 161 sizeof(image->firmware_key_version)); |
| 162 checksum = DigestFinal(&ctx); |
| 163 Memcpy(header_checksum, checksum, FIELD_LEN(header_checksum)); |
| 164 Free(checksum); |
| 165 return; |
| 166 } |
| 167 |
| 168 |
139 uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) { | 169 uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) { |
140 uint8_t* header_blob = NULL; | 170 uint8_t* header_blob = NULL; |
141 MemcpyState st; | 171 MemcpyState st; |
142 | 172 |
143 header_blob = (uint8_t*) Malloc(GetFirmwareHeaderLen(image)); | 173 header_blob = (uint8_t*) Malloc(GetFirmwareHeaderLen(image)); |
144 st.remaining_len = GetFirmwareHeaderLen(image); | 174 st.remaining_len = GetFirmwareHeaderLen(image); |
145 st.remaining_buf = header_blob; | 175 st.remaining_buf = header_blob; |
146 | 176 |
147 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len)); | 177 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len)); |
148 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, FIELD_LEN(header_len)); | 178 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, FIELD_LEN(header_len)); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 close(fd); | 285 close(fd); |
256 return 1; | 286 return 1; |
257 } | 287 } |
258 | 288 |
259 void PrintFirmwareImage(const FirmwareImage* image) { | 289 void PrintFirmwareImage(const FirmwareImage* image) { |
260 if (!image) | 290 if (!image) |
261 return; | 291 return; |
262 | 292 |
263 /* Print header. */ | 293 /* Print header. */ |
264 printf("Header Length = %d\n" | 294 printf("Header Length = %d\n" |
265 "Algorithm Id = %d\n" | 295 "Firmware Signature Algorithm = %s\n" |
266 "Signature Algorithm = %s\n" | 296 "Firmware Key Version = %d\n\n", |
267 "Key Version = %d\n\n", | |
268 image->header_len, | 297 image->header_len, |
269 image->firmware_sign_algorithm, | |
270 algo_strings[image->firmware_sign_algorithm], | 298 algo_strings[image->firmware_sign_algorithm], |
271 image->firmware_key_version); | 299 image->firmware_key_version); |
272 /* TODO(gauravsh): Output hash and key signature here? */ | 300 /* TODO(gauravsh): Output hash and key signature here? */ |
273 /* Print preamble. */ | 301 /* Print preamble. */ |
274 printf("Firmware Version = %d\n" | 302 printf("Firmware Version = %d\n" |
275 "Firmware Length = %" PRIu64 "\n\n", | 303 "Firmware Length = %" PRIu64 "\n\n", |
276 image->firmware_version, | 304 image->firmware_version, |
277 image->firmware_len); | 305 image->firmware_len); |
278 /* Output key signature here? */ | 306 /* Output key signature here? */ |
279 } | 307 } |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
578 if (!(firmware_signature = SignatureBuf(image->firmware_data, | 606 if (!(firmware_signature = SignatureBuf(image->firmware_data, |
579 image->firmware_len, | 607 image->firmware_len, |
580 signing_key_file, | 608 signing_key_file, |
581 image->firmware_sign_algorithm))) | 609 image->firmware_sign_algorithm))) |
582 return 0; | 610 return 0; |
583 image->firmware_signature = (uint8_t*) Malloc(signature_len); | 611 image->firmware_signature = (uint8_t*) Malloc(signature_len); |
584 Memcpy(image->firmware_signature, firmware_signature, signature_len); | 612 Memcpy(image->firmware_signature, firmware_signature, signature_len); |
585 Free(firmware_signature); | 613 Free(firmware_signature); |
586 return 1; | 614 return 1; |
587 } | 615 } |
OLD | NEW |