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> |
11 #include <limits.h> | 11 #include <limits.h> |
12 #include <stdio.h> | 12 #include <stdio.h> |
13 #include <sys/types.h> | 13 #include <sys/types.h> |
14 #include <sys/stat.h> | 14 #include <sys/stat.h> |
15 #include <unistd.h> | 15 #include <unistd.h> |
16 | 16 |
| 17 #include "file_keys.h" |
17 #include "padding.h" | 18 #include "padding.h" |
18 #include "rsa_utility.h" | 19 #include "rsa_utility.h" |
19 #include "sha_utility.h" | 20 #include "sha_utility.h" |
20 #include "utility.h" | 21 #include "utility.h" |
21 | 22 |
| 23 /* Macro to determine the size of a field structure in the FirmwareImage |
| 24 * structure. */ |
| 25 #define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field)) |
22 | 26 |
23 FirmwareImage* FirmwareImageNew(void) { | 27 FirmwareImage* FirmwareImageNew(void) { |
24 FirmwareImage* fw = (FirmwareImage*) Malloc(sizeof(FirmwareImage)); | 28 FirmwareImage* fw = (FirmwareImage*) Malloc(sizeof(FirmwareImage)); |
25 return fw; | 29 return fw; |
26 } | 30 } |
27 | 31 |
28 void FirmwareImageFree(FirmwareImage* image) { | 32 void FirmwareImageFree(FirmwareImage* image) { |
29 Free(image->sign_key); | 33 Free(image->sign_key); |
30 Free(image->key_signature); | 34 Free(image->key_signature); |
31 Free(image->preamble_signature); | 35 Free(image->preamble_signature); |
32 Free(image->firmware_signature); | 36 Free(image->firmware_signature); |
33 Free(image->firmware_data); | 37 Free(image->firmware_data); |
34 } | 38 } |
35 | 39 |
36 | 40 FirmwareImage* ReadFirmwareImage(const char* input_file, |
37 FirmwareImage* ReadFirmware(const char* input_file, | 41 FirmwareImage* image) { |
38 FirmwareImage* image) { | |
39 int fd; | 42 int fd; |
40 struct stat fd_stat; | 43 struct stat fd_stat; |
41 | 44 |
42 int image_len = 0; /* Total size of the firmware image. */ | 45 int image_len = 0; /* Total size of the firmware image. */ |
43 int header_len = 0; | 46 int header_len = 0; |
44 int sign_key_len; | 47 int sign_key_len; |
45 int signature_len; | 48 int signature_len; |
46 uint8_t* firmware_buf; | 49 uint8_t* firmware_buf; |
47 MemcpyState st; | 50 MemcpyState st; |
48 | 51 |
(...skipping 22 matching lines...) Expand all Loading... |
71 } | 74 } |
72 close(fd); | 75 close(fd); |
73 | 76 |
74 st.remaining_len = image_len; | 77 st.remaining_len = image_len; |
75 st.remaining_buf = firmware_buf; | 78 st.remaining_buf = firmware_buf; |
76 | 79 |
77 /* Read and compare magic bytes. */ | 80 /* Read and compare magic bytes. */ |
78 if (!StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE)) | 81 if (!StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE)) |
79 goto parse_failure; | 82 goto parse_failure; |
80 | 83 |
81 if (!SafeMemcmp(image->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) { | 84 if (SafeMemcmp(image->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) { |
82 fprintf(stderr, "Wrong Firmware Magic.\n"); | 85 fprintf(stderr, "Wrong Firmware Magic.\n"); |
83 goto parse_failure; | 86 goto parse_failure; |
84 } | 87 } |
85 | 88 |
86 StatefulMemcpy(&st, &image->header_len, sizeof(image->header_len)); | 89 StatefulMemcpy(&st, &image->header_len, sizeof(image->header_len)); |
87 StatefulMemcpy(&st, &image->sign_algorithm, sizeof(image->sign_algorithm)); | 90 StatefulMemcpy(&st, &image->sign_algorithm, sizeof(image->sign_algorithm)); |
88 | 91 |
89 /* Valid Algorithm? */ | 92 /* Valid Algorithm? */ |
90 if (image->sign_algorithm > kNumAlgorithms) | 93 if (image->sign_algorithm > kNumAlgorithms) |
91 goto parse_failure; | 94 goto parse_failure; |
92 | 95 |
93 /* Compute size of pre-processed RSA public key and signature. */ | 96 /* Compute size of pre-processed RSA public key and signature. */ |
94 sign_key_len = (2*siglen_map[image->sign_algorithm]*sizeof(uint32_t) | 97 sign_key_len = (2*siglen_map[image->sign_algorithm]*sizeof(uint32_t) |
95 + sizeof(uint32_t) + sizeof(int)); | 98 + sizeof(uint32_t) + sizeof(int)); |
96 signature_len = siglen_map[image->sign_algorithm] * sizeof(uint32_t); | 99 signature_len = siglen_map[image->sign_algorithm] * sizeof(uint32_t); |
97 | 100 |
98 | 101 |
99 /* Check whether the header length is correct. */ | 102 /* Check whether the header length is correct. */ |
100 header_len = (sizeof(image->header_len) + sizeof(image->sign_algorithm) + | 103 header_len = (sizeof(image->header_len) + sizeof(image->sign_algorithm) + |
101 sizeof(image->key_version) + | 104 sizeof(image->key_version) + |
102 sizeof(image->header_hash)); | 105 sizeof(image->header_checksum)); |
103 if (header_len != image->header_len) { | 106 if (header_len != image->header_len) { |
104 fprintf(stderr, "Header length mismatch."); | 107 fprintf(stderr, "Header length mismatch."); |
105 goto parse_failure; | 108 goto parse_failure; |
106 } | 109 } |
107 | 110 |
108 /* Read pre-processed public half of the sign key. */ | 111 /* Read pre-processed public half of the sign key. */ |
109 image->sign_key = (uint8_t*) Malloc(sign_key_len); | 112 image->sign_key = (uint8_t*) Malloc(sign_key_len); |
110 StatefulMemcpy(&st, image->sign_key, sign_key_len); | 113 StatefulMemcpy(&st, image->sign_key, sign_key_len); |
111 StatefulMemcpy(&st, &image->key_version, sizeof(image->key_version)); | 114 StatefulMemcpy(&st, &image->key_version, sizeof(image->key_version)); |
112 StatefulMemcpy(&st, image->header_hash, sizeof(image->header_hash)); | 115 StatefulMemcpy(&st, image->header_checksum, sizeof(image->header_checksum)); |
113 | 116 |
114 /* Read key signature. */ | 117 /* Read key signature. */ |
115 StatefulMemcpy(&st, image->key_signature, sizeof(image->key_signature)); | 118 StatefulMemcpy(&st, image->key_signature, sizeof(image->key_signature)); |
116 | 119 |
117 /* Read the firmware preamble. */ | 120 /* Read the firmware preamble. */ |
118 StatefulMemcpy(&st,&image->firmware_version, sizeof(image->firmware_version)); | 121 StatefulMemcpy(&st,&image->firmware_version, sizeof(image->firmware_version)); |
119 StatefulMemcpy(&st, &image->firmware_len, sizeof(image->firmware_len)); | 122 StatefulMemcpy(&st, &image->firmware_len, sizeof(image->firmware_len)); |
120 StatefulMemcpy(&st, image->preamble, sizeof(image->preamble)); | 123 StatefulMemcpy(&st, image->preamble, sizeof(image->preamble)); |
121 | 124 |
122 /* Read firmware preamble signature. */ | 125 /* Read firmware preamble signature. */ |
(...skipping 17 matching lines...) Expand all Loading... |
140 return NULL; | 143 return NULL; |
141 } | 144 } |
142 | 145 |
143 void WriteFirmwareHeader(int fd, FirmwareImage* image) { | 146 void WriteFirmwareHeader(int fd, FirmwareImage* image) { |
144 int sign_key_len; | 147 int sign_key_len; |
145 write(fd, &image->header_len, sizeof(image->header_len)); | 148 write(fd, &image->header_len, sizeof(image->header_len)); |
146 write(fd, &image->sign_algorithm, sizeof(image->header_len)); | 149 write(fd, &image->sign_algorithm, sizeof(image->header_len)); |
147 sign_key_len = (image->header_len - sizeof(image->header_len) - | 150 sign_key_len = (image->header_len - sizeof(image->header_len) - |
148 sizeof(image->sign_algorithm) - | 151 sizeof(image->sign_algorithm) - |
149 sizeof(image->key_version) - | 152 sizeof(image->key_version) - |
150 sizeof(image->header_hash)); | 153 sizeof(image->header_checksum)); |
151 write(fd, image->sign_key, sign_key_len); | 154 write(fd, image->sign_key, sign_key_len); |
152 write(fd, &image->key_version, sizeof(image->key_version)); | 155 write(fd, &image->key_version, sizeof(image->key_version)); |
153 write(fd, &image->header_hash, sizeof(image->header_hash)); | 156 write(fd, &image->header_checksum, sizeof(image->header_checksum)); |
154 } | 157 } |
155 | 158 |
156 void WriteFirmwarePreamble(int fd, FirmwareImage* image) { | 159 void WriteFirmwarePreamble(int fd, FirmwareImage* image) { |
157 write(fd, &image->firmware_version, | 160 write(fd, &image->firmware_version, |
158 sizeof(image->firmware_version)); | 161 sizeof(image->firmware_version)); |
159 write(fd, &image->firmware_len, sizeof(image->firmware_len)); | 162 write(fd, &image->firmware_len, sizeof(image->firmware_len)); |
160 write(fd, image->preamble, sizeof(image->preamble)); | 163 write(fd, image->preamble, sizeof(image->preamble)); |
161 } | 164 } |
162 | 165 |
| 166 FirmwareImage* WriteFirmwareImage(const char* input_file, |
| 167 FirmwareImage* image) { |
| 168 int fd; |
| 169 int signature_len; |
163 | 170 |
164 FirmwareImage* WriteFirmware(const char* input_file, | 171 if (!image) |
165 FirmwareImage* image) { | 172 return NULL; |
166 int fd; | 173 if (-1 == (fd = creat(input_file, S_IRWXU))) { |
167 int signature_len; | 174 fprintf(stderr, "Couldn't open file for writing.\n"); |
| 175 return NULL; |
| 176 } |
168 | 177 |
169 if (!image) | 178 write(fd, image->magic, sizeof(image->magic)); |
170 return NULL; | 179 WriteFirmwareHeader(fd, image); |
| 180 write(fd, image->key_signature, sizeof(image->key_signature)); |
| 181 signature_len = siglen_map[image->sign_algorithm] * sizeof(uint32_t); |
| 182 WriteFirmwarePreamble(fd, image); |
| 183 write(fd, image->preamble_signature, signature_len); |
| 184 write(fd, image->firmware_signature, signature_len); |
| 185 write(fd, image->firmware_data, image->firmware_len); |
171 | 186 |
172 if (-1 == (fd = open(input_file, O_WRONLY))) { | 187 close(fd); |
173 fprintf(stderr, "Couldn't open file for writing.\n"); | 188 return image; |
174 return NULL; | |
175 } | |
176 | |
177 write(fd, &image->magic, sizeof(image->magic)); | |
178 WriteFirmwareHeader(fd, image); | |
179 write(fd, image->key_signature, sizeof(image->key_signature)); | |
180 signature_len = siglen_map[image->sign_algorithm] * sizeof(uint32_t); | |
181 WriteFirmwarePreamble(fd, image); | |
182 write(fd, image->preamble_signature, signature_len); | |
183 write(fd, image->firmware_signature, signature_len); | |
184 write(fd, image->firmware_data, image->firmware_len); | |
185 | |
186 close(fd); | |
187 return image; | |
188 } | 189 } |
189 | 190 |
190 void PrintFirmware(const FirmwareImage* image) { | 191 void PrintFirmware(const FirmwareImage* image) { |
191 if (!image) | 192 if (!image) |
192 return; | 193 return; |
193 | 194 |
194 /* Print header. */ | 195 /* Print header. */ |
195 printf("Header Length = %d\n" | 196 printf("Header Length = %d\n" |
196 "Algorithm Id = %d\n" | 197 "Algorithm Id = %d\n" |
197 "Signature Algorithm = %s\n" | 198 "Signature Algorithm = %s\n" |
198 "Key Version = %d\n\n", | 199 "Key Version = %d\n\n", |
199 image->header_len, | 200 image->header_len, |
200 image->sign_algorithm, | 201 image->sign_algorithm, |
201 algo_strings[image->sign_algorithm], | 202 algo_strings[image->sign_algorithm], |
202 image->key_version); | 203 image->key_version); |
203 /* TODO(gauravsh): Output hash and key signature here? */ | 204 /* TODO(gauravsh): Output hash and key signature here? */ |
204 /* Print preamble. */ | 205 /* Print preamble. */ |
205 printf("Firmware Version = %d\n" | 206 printf("Firmware Version = %d\n" |
206 "Firmware Length = %d\n\n", | 207 "Firmware Length = %d\n\n", |
207 image->firmware_version, | 208 image->firmware_version, |
208 image->firmware_len); | 209 image->firmware_len); |
209 /* Output key signature here? */ | 210 /* Output key signature here? */ |
210 } | 211 } |
211 | 212 |
212 int VerifyFirmware(const RSAPublicKey* root_key, | 213 char* kVerifyFirmwareErrors[VERIFY_FIRMWARE_MAX] = { |
213 const FirmwareImage* image, | 214 "Success.", |
| 215 "Invalid Image.", |
| 216 "Root Key Signature Failed.", |
| 217 "Invalid Verification Algorithm.", |
| 218 "Preamble Signature Failed.", |
| 219 "Firmware Signature Failed.", |
| 220 "Wrong Firmware Magic.", |
| 221 }; |
| 222 |
| 223 int VerifyFirmwareHeader(const uint8_t* root_key_blob, |
| 224 const uint8_t* header_blob, |
| 225 const int dev_mode, |
| 226 int* algorithm, |
| 227 int* header_len) { |
| 228 int sign_key_len; |
| 229 int root_key_len; |
| 230 uint16_t hlen, algo; |
| 231 uint8_t* header_checksum = NULL; |
| 232 |
| 233 /* Base Offset for the header_checksum field. Actual offset is |
| 234 * this + sign_key_len. */ |
| 235 int base_header_checksum_offset = (FIELD_LEN(header_len) + |
| 236 FIELD_LEN(sign_algorithm) + |
| 237 FIELD_LEN(key_version)); |
| 238 |
| 239 |
| 240 root_key_len = RSAProcessedKeySize(ROOT_SIGNATURE_ALGORITHM); |
| 241 Memcpy(&hlen, header_blob, sizeof(hlen)); |
| 242 Memcpy(&algo, |
| 243 header_blob + FIELD_LEN(sign_algorithm), |
| 244 sizeof(algo)); |
| 245 if (algo >= kNumAlgorithms) |
| 246 return VERIFY_FIRMWARE_INVALID_ALGORITHM; |
| 247 *algorithm = (int) algo; |
| 248 sign_key_len = RSAProcessedKeySize(*algorithm); |
| 249 |
| 250 /* Verify if header len is correct? */ |
| 251 if (hlen != (base_header_checksum_offset + |
| 252 sign_key_len + |
| 253 FIELD_LEN(header_checksum))) |
| 254 return VERIFY_FIRMWARE_INVALID_IMAGE; |
| 255 |
| 256 *header_len = (int) hlen; |
| 257 |
| 258 /* Verify if the hash of the header is correct. */ |
| 259 header_checksum = DigestBuf(header_blob, |
| 260 *header_len - FIELD_LEN(header_checksum), |
| 261 SHA512_DIGEST_ALGORITHM); |
| 262 if (SafeMemcmp(header_checksum, |
| 263 header_blob + (base_header_checksum_offset + sign_key_len), |
| 264 FIELD_LEN(header_checksum))) { |
| 265 Free(header_checksum); |
| 266 return VERIFY_FIRMWARE_INVALID_IMAGE; |
| 267 } |
| 268 Free(header_checksum); |
| 269 |
| 270 /* Verify root key signature unless we are in dev mode. */ |
| 271 if (!dev_mode) { |
| 272 if (!RSAVerifyBinary_f(root_key_blob, NULL, /* Key to use */ |
| 273 header_blob, /* Data to verify */ |
| 274 *header_len, /* Length of data */ |
| 275 header_blob + *header_len, /* Expected Signature */ |
| 276 ROOT_SIGNATURE_ALGORITHM)) |
| 277 return VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; |
| 278 } |
| 279 return 0; |
| 280 } |
| 281 |
| 282 int VerifyFirmwarePreamble(RSAPublicKey* sign_key, |
| 283 const uint8_t* preamble_blob, |
| 284 int algorithm, |
| 285 int* firmware_len) { |
| 286 uint32_t len; |
| 287 int preamble_len; |
| 288 preamble_len = (FIELD_LEN(firmware_version) + |
| 289 FIELD_LEN(firmware_len) + |
| 290 FIELD_LEN(preamble)); |
| 291 if (!RSAVerifyBinary_f(NULL, sign_key, /* Key to use */ |
| 292 preamble_blob, /* Data to verify */ |
| 293 preamble_len, /* Length of data */ |
| 294 preamble_blob + preamble_len, /* Expected Signature */ |
| 295 algorithm)) |
| 296 return VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; |
| 297 |
| 298 Memcpy(&len, preamble_blob + FIELD_LEN(firmware_version), |
| 299 sizeof(len)); |
| 300 *firmware_len = (int) len; |
| 301 return 0; |
| 302 } |
| 303 |
| 304 int VerifyFirmwareData(RSAPublicKey* sign_key, |
| 305 const uint8_t* firmware_data_start, |
| 306 int firmware_len, |
| 307 int algorithm) { |
| 308 int signature_len = siglen_map[algorithm] * sizeof(uint32_t); |
| 309 if (!RSAVerifyBinary_f(NULL, sign_key, /* Key to use. */ |
| 310 firmware_data_start + signature_len, /* Data to |
| 311 * verify */ |
| 312 firmware_len, /* Length of data. */ |
| 313 firmware_data_start, /* Expected Signature */ |
| 314 algorithm)) |
| 315 return VERIFY_FIRMWARE_SIGNATURE_FAILED; |
| 316 return 0; |
| 317 } |
| 318 |
| 319 int VerifyFirmware(const uint8_t* root_key_blob, |
| 320 const uint8_t* firmware_blob, |
214 const int dev_mode) { | 321 const int dev_mode) { |
| 322 int error_code; |
| 323 int algorithm; /* Signing key algorithm. */ |
| 324 RSAPublicKey* sign_key; |
| 325 int sign_key_len, signature_len, header_len, firmware_len; |
| 326 const uint8_t* header_ptr; /* Pointer to header. */ |
| 327 const uint8_t* sign_key_ptr; /* Pointer to signing key. */ |
| 328 const uint8_t* preamble_ptr; /* Pointer to preamble block. */ |
| 329 const uint8_t* firmware_ptr; /* Pointer to firmware signature/data. */ |
| 330 |
| 331 /* Note: All the offset calculations are based on struct FirmwareImage which |
| 332 * is defined in include/firmware_image.h. */ |
| 333 |
| 334 /* Compare magic bytes. */ |
| 335 if (SafeMemcmp(firmware_blob, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) |
| 336 return VERIFY_FIRMWARE_WRONG_MAGIC; |
| 337 header_ptr = firmware_blob + FIRMWARE_MAGIC_SIZE; |
| 338 |
| 339 /* Only continue if header verification succeeds. */ |
| 340 if ((error_code = VerifyFirmwareHeader(root_key_blob, header_ptr, dev_mode, |
| 341 &algorithm, &header_len))) |
| 342 return error_code; /* AKA jump to revovery. */ |
| 343 |
| 344 /* Parse signing key into RSAPublicKey structure since it is required multiple |
| 345 * times. */ |
| 346 sign_key_len = RSAProcessedKeySize(algorithm); |
| 347 sign_key_ptr = header_ptr + (FIELD_LEN(header_len) + |
| 348 FIELD_LEN(sign_algorithm)); |
| 349 sign_key = RSAPublicKeyFromBuf(sign_key_ptr, sign_key_len); |
| 350 signature_len = siglen_map[algorithm] * sizeof(uint32_t); |
| 351 |
| 352 /* Only continue if preamble verification succeeds. */ |
| 353 preamble_ptr = (header_ptr + header_len + |
| 354 FIELD_LEN(key_signature)); |
| 355 if ((error_code = VerifyFirmwarePreamble(sign_key, preamble_ptr, algorithm, |
| 356 &firmware_len))) |
| 357 return error_code; /* AKA jump to recovery. */ |
| 358 |
| 359 /* Only continue if firmware data verification succeeds. */ |
| 360 firmware_ptr = (preamble_ptr + |
| 361 FIELD_LEN(firmware_version) + |
| 362 FIELD_LEN(firmware_len) + |
| 363 FIELD_LEN(preamble) + |
| 364 signature_len); |
| 365 |
| 366 if ((error_code = VerifyFirmwareData(sign_key, firmware_ptr, firmware_len, |
| 367 algorithm))) |
| 368 return error_code; /* AKA jump to recovery. */ |
| 369 |
| 370 return 0; /* Success! */ |
| 371 } |
| 372 |
| 373 int VerifyFirmwareImage(const RSAPublicKey* root_key, |
| 374 const FirmwareImage* image, |
| 375 const int dev_mode) { |
215 RSAPublicKey* sign_key; | 376 RSAPublicKey* sign_key; |
216 uint8_t* header_digest = NULL; | 377 uint8_t* header_digest = NULL; |
217 uint8_t* preamble_digest = NULL; | 378 uint8_t* preamble_digest = NULL; |
218 uint8_t* firmware_digest = NULL; | 379 uint8_t* firmware_digest = NULL; |
219 int sign_key_size; | 380 int sign_key_size; |
220 int signature_size; | 381 int signature_size; |
221 int error_code = 0; | 382 int error_code = 0; |
222 DigestContext ctx; | 383 DigestContext ctx; |
223 | 384 |
224 if (!image) | 385 if (!image) |
225 return VERIFY_INVALID_IMAGE; | 386 return VERIFY_FIRMWARE_INVALID_IMAGE; |
226 | 387 |
227 /* Verify root key signature on the sign key header if we | 388 /* Verify root key signature on the sign key header if we |
228 * are not in dev mode. */ | 389 * are not in dev mode. |
| 390 * |
| 391 * TODO(gauravsh): Add additional sanity checks here for: |
| 392 * 1) verifying the header length is correct. |
| 393 * 2) header_checksum is correct. |
| 394 */ |
229 if (!dev_mode) { | 395 if (!dev_mode) { |
230 DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM); | 396 DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM); |
231 DigestUpdate(&ctx, (uint8_t*) &image->header_len, | 397 DigestUpdate(&ctx, (uint8_t*) &image->header_len, |
232 sizeof(image->header_len)); | 398 sizeof(image->header_len)); |
233 DigestUpdate(&ctx, (uint8_t*) &image->sign_algorithm, | 399 DigestUpdate(&ctx, (uint8_t*) &image->sign_algorithm, |
234 sizeof(image->sign_algorithm)); | 400 sizeof(image->sign_algorithm)); |
235 DigestUpdate(&ctx, image->sign_key, | 401 DigestUpdate(&ctx, image->sign_key, |
236 RSAProcessedKeySize(image->sign_algorithm)); | 402 RSAProcessedKeySize(image->sign_algorithm)); |
237 DigestUpdate(&ctx, (uint8_t*) &image->key_version, | 403 DigestUpdate(&ctx, (uint8_t*) &image->key_version, |
238 sizeof(image->key_version)); | 404 sizeof(image->key_version)); |
239 DigestUpdate(&ctx, image->header_hash, | 405 DigestUpdate(&ctx, image->header_checksum, |
240 sizeof(image->header_hash)); | 406 sizeof(image->header_checksum)); |
241 header_digest = DigestFinal(&ctx); | 407 header_digest = DigestFinal(&ctx); |
242 if (!RSA_verify(root_key, image->key_signature, | 408 if (!RSA_verify(root_key, image->key_signature, |
243 sizeof(image->key_signature), | 409 sizeof(image->key_signature), |
244 ROOT_SIGNATURE_ALGORITHM, | 410 ROOT_SIGNATURE_ALGORITHM, |
245 header_digest)) { | 411 header_digest)) { |
246 error_code = VERIFY_ROOT_SIGNATURE_FAILED; | 412 error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; |
247 goto verify_failure; | 413 goto verify_failure; |
248 } | 414 } |
249 } | 415 } |
250 | 416 |
251 /* Get sign key to verify the rest of the firmware. */ | 417 /* Get sign key to verify the rest of the firmware. */ |
252 sign_key_size = RSAProcessedKeySize(image->sign_algorithm); | 418 sign_key_size = RSAProcessedKeySize(image->sign_algorithm); |
253 sign_key = RSAPublicKeyFromBuf(image->sign_key, | 419 sign_key = RSAPublicKeyFromBuf(image->sign_key, |
254 sign_key_size); | 420 sign_key_size); |
255 signature_size = siglen_map[image->sign_algorithm] * sizeof(uint32_t); | 421 signature_size = siglen_map[image->sign_algorithm] * sizeof(uint32_t); |
256 | 422 |
257 if (image->sign_algorithm >= kNumAlgorithms) | 423 if (image->sign_algorithm >= kNumAlgorithms) |
258 return VERIFY_INVALID_ALGORITHM; | 424 return VERIFY_FIRMWARE_INVALID_ALGORITHM; |
259 | 425 |
260 /* Verify firmware preamble signature. */ | 426 /* Verify firmware preamble signature. */ |
261 DigestInit(&ctx, image->sign_algorithm); | 427 DigestInit(&ctx, image->sign_algorithm); |
262 DigestUpdate(&ctx, (uint8_t*) &image->firmware_version, | 428 DigestUpdate(&ctx, (uint8_t*) &image->firmware_version, |
263 sizeof(image->firmware_version)); | 429 sizeof(image->firmware_version)); |
264 DigestUpdate(&ctx, (uint8_t*) &image->firmware_len, | 430 DigestUpdate(&ctx, (uint8_t*) &image->firmware_len, |
265 sizeof(image->firmware_len)); | 431 sizeof(image->firmware_len)); |
266 DigestUpdate(&ctx, (uint8_t*) &image->preamble, | 432 DigestUpdate(&ctx, (uint8_t*) &image->preamble, |
267 sizeof(image->preamble)); | 433 sizeof(image->preamble)); |
268 preamble_digest = DigestFinal(&ctx); | 434 preamble_digest = DigestFinal(&ctx); |
269 if (!RSA_verify(sign_key, image->preamble_signature, | 435 if (!RSA_verify(sign_key, image->preamble_signature, |
270 signature_size, image->sign_algorithm, | 436 signature_size, image->sign_algorithm, |
271 preamble_digest)) { | 437 preamble_digest)) { |
272 error_code = VERIFY_PREAMBLE_SIGNATURE_FAILED; | 438 error_code = VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; |
273 goto verify_failure; | 439 goto verify_failure; |
274 } | 440 } |
275 | 441 |
276 /* Verify firmware signature. */ | 442 /* Verify firmware signature. */ |
277 firmware_digest = DigestBuf(image->firmware_data, | 443 firmware_digest = DigestBuf(image->firmware_data, |
278 image->firmware_len, | 444 image->firmware_len, |
279 image->sign_algorithm); | 445 image->sign_algorithm); |
280 if(!RSA_verify(sign_key, image->firmware_signature, | 446 if(!RSA_verify(sign_key, image->firmware_signature, |
281 signature_size, image->sign_algorithm, | 447 signature_size, image->sign_algorithm, |
282 firmware_digest)) { | 448 firmware_digest)) { |
283 error_code = VERIFY_FIRMWARE_SIGNATURE_FAILED; | 449 error_code = VERIFY_FIRMWARE_SIGNATURE_FAILED; |
284 goto verify_failure; | 450 goto verify_failure; |
285 } | 451 } |
286 | 452 |
287 verify_failure: | 453 verify_failure: |
288 Free(firmware_digest); | 454 Free(firmware_digest); |
289 Free(preamble_digest); | 455 Free(preamble_digest); |
290 Free(header_digest); | 456 Free(header_digest); |
291 return error_code; | 457 return error_code; |
292 } | 458 } |
293 | 459 |
294 char* kVerifyFirmwareErrors[VERIFY_MAX] = { | |
295 "Success.", | |
296 "Invalid Image.", | |
297 "Root Key Signature Failed.", | |
298 "Invalid Verification Algorithm.", | |
299 "Preamble Signature Failed.", | |
300 "Firmware Signature Failed.", | |
301 }; | |
302 | |
303 uint8_t* SignatureFile(char* input_file, char* key_file, int algorithm) { | |
304 char* sign_utility = "./sign_data.sh"; | |
305 char* cmd; /* Command line to invoke. */ | |
306 int cmd_len; | |
307 FILE* cmd_out; /* File descriptor to command output. */ | |
308 uint8_t* signature = NULL; | |
309 int signature_size = siglen_map[algorithm] * sizeof(uint32_t); | |
310 | |
311 /* Build command line: | |
312 * sign_data.sh <algorithm> <key file> <input file> | |
313 */ | |
314 cmd_len = (strlen(sign_utility) + 1 + /* +1 for space. */ | |
315 2 + 1 + /* For [algorithm]. */ | |
316 strlen(key_file) + 1 + /* +1 for space. */ | |
317 strlen(input_file) + | |
318 1); /* For the trailing '\0'. */ | |
319 cmd = (char*) Malloc(cmd_len); | |
320 snprintf(cmd, cmd_len, "%s %d %s %s", sign_utility, algorithm, key_file, | |
321 input_file); | |
322 cmd_out = popen(cmd, "r"); | |
323 Free(cmd); | |
324 if (!cmd_out) { | |
325 fprintf(stderr, "Couldn't execute: %s\n", cmd); | |
326 return NULL; | |
327 } | |
328 | |
329 signature = (uint8_t*) Malloc(signature_size); | |
330 if (fread(signature, signature_size, 1, cmd_out) != 1) { | |
331 fprintf(stderr, "Couldn't read signature.\n"); | |
332 pclose(cmd_out); | |
333 Free(signature); | |
334 return NULL; | |
335 } | |
336 | |
337 pclose(cmd_out); | |
338 return signature; | |
339 } | |
340 | 460 |
341 int AddKeySignature(FirmwareImage* image, char* root_key_file) { | 461 int AddKeySignature(FirmwareImage* image, char* root_key_file) { |
342 int tmp_hdr_fd; | 462 int tmp_hdr_fd; |
343 char* tmp_hdr_file = ".tmpHdrFile"; | 463 char* tmp_hdr_file = ".tmpHdrFile"; |
344 uint8_t* signature; | 464 uint8_t* signature; |
345 | 465 |
346 if(-1 == (tmp_hdr_fd = creat(tmp_hdr_file, S_IRWXU))) { | 466 if(-1 == (tmp_hdr_fd = creat(tmp_hdr_file, S_IRWXU))) { |
347 fprintf(stderr, "Could not open temporary file for writing " | 467 fprintf(stderr, "Could not open temporary file for writing " |
348 "firmware header.\n"); | 468 "firmware header.\n"); |
349 return 0; | 469 return 0; |
(...skipping 14 matching lines...) Expand all Loading... |
364 char* tmp_preamble_file = ".tmpPreambleFile"; | 484 char* tmp_preamble_file = ".tmpPreambleFile"; |
365 int tmp_firmware_fd; | 485 int tmp_firmware_fd; |
366 char* tmp_firmware_file = ".tmpFirmwareFile"; | 486 char* tmp_firmware_file = ".tmpFirmwareFile"; |
367 uint8_t* preamble_signature; | 487 uint8_t* preamble_signature; |
368 uint8_t* firmware_signature; | 488 uint8_t* firmware_signature; |
369 int signature_len = siglen_map[algorithm] * sizeof(uint32_t); | 489 int signature_len = siglen_map[algorithm] * sizeof(uint32_t); |
370 | 490 |
371 /* Write preamble to a file. */ | 491 /* Write preamble to a file. */ |
372 if(-1 == (tmp_preamble_fd = creat(tmp_preamble_file, S_IRWXU))) { | 492 if(-1 == (tmp_preamble_fd = creat(tmp_preamble_file, S_IRWXU))) { |
373 fprintf(stderr, "Could not open temporary file for writing " | 493 fprintf(stderr, "Could not open temporary file for writing " |
374 "firmware praemble.\n"); | 494 "firmware preamble.\n"); |
375 return 0; | 495 return 0; |
376 } | 496 } |
377 WriteFirmwarePreamble(tmp_preamble_fd, image); | 497 WriteFirmwarePreamble(tmp_preamble_fd, image); |
378 close(tmp_preamble_fd); | 498 close(tmp_preamble_fd); |
379 if (!(preamble_signature = SignatureFile(tmp_preamble_file, signing_key_file, | 499 if (!(preamble_signature = SignatureFile(tmp_preamble_file, signing_key_file, |
380 algorithm))) | 500 algorithm))) |
381 return 0; | 501 return 0; |
382 image->preamble_signature = (uint8_t*) Malloc(signature_len); | 502 image->preamble_signature = (uint8_t*) Malloc(signature_len); |
383 Memcpy(image->preamble_signature, preamble_signature, signature_len); | 503 Memcpy(image->preamble_signature, preamble_signature, signature_len); |
384 Free(preamble_signature); | 504 Free(preamble_signature); |
(...skipping 10 matching lines...) Expand all Loading... |
395 algorithm))) { | 515 algorithm))) { |
396 fprintf(stderr, "Could not open temporary file for writing " | 516 fprintf(stderr, "Could not open temporary file for writing " |
397 "firmware.\n"); | 517 "firmware.\n"); |
398 return 0; | 518 return 0; |
399 } | 519 } |
400 image->firmware_signature = (uint8_t*) Malloc(signature_len); | 520 image->firmware_signature = (uint8_t*) Malloc(signature_len); |
401 Memcpy(image->firmware_signature, firmware_signature, signature_len); | 521 Memcpy(image->firmware_signature, firmware_signature, signature_len); |
402 Free(firmware_signature); | 522 Free(firmware_signature); |
403 return 1; | 523 return 1; |
404 } | 524 } |
OLD | NEW |