| OLD | NEW |
| (Empty) |
| 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 | |
| 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 <sys/types.h> | |
| 11 #include <sys/stat.h> | |
| 12 #include <fcntl.h> | |
| 13 #include <unistd.h> | |
| 14 | |
| 15 #include "cryptolib.h" | |
| 16 #include "file_keys.h" | |
| 17 #include "signature_digest.h" | |
| 18 #include "stateful_util.h" | |
| 19 | |
| 20 /* Macro to determine the size of a field structure in the FirmwareImage | |
| 21 * structure. */ | |
| 22 #define FIELD_LEN(field) (sizeof(((FirmwareImage*)0)->field)) | |
| 23 | |
| 24 FirmwareImage* FirmwareImageNew(void) { | |
| 25 FirmwareImage* image = (FirmwareImage*) Malloc(sizeof(FirmwareImage)); | |
| 26 if (image) { | |
| 27 image->firmware_sign_key = NULL; | |
| 28 image->kernel_subkey_sign_key = NULL; | |
| 29 image->preamble_signature = NULL; | |
| 30 image->firmware_signature = NULL; | |
| 31 image->firmware_data = NULL; | |
| 32 } | |
| 33 return image; | |
| 34 } | |
| 35 | |
| 36 void FirmwareImageFree(FirmwareImage* image) { | |
| 37 if (image) { | |
| 38 Free(image->firmware_sign_key); | |
| 39 Free(image->kernel_subkey_sign_key); | |
| 40 Free(image->preamble_signature); | |
| 41 Free(image->firmware_signature); | |
| 42 Free(image->firmware_data); | |
| 43 Free(image); | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 FirmwareImage* ReadFirmwareImage(const char* input_file) { | |
| 48 uint64_t file_size; | |
| 49 int image_len = 0; /* Total size of the firmware image. */ | |
| 50 int header_len = 0; | |
| 51 int firmware_sign_key_len; | |
| 52 int signature_len; | |
| 53 uint8_t* firmware_buf; | |
| 54 uint8_t header_checksum[FIELD_LEN(header_checksum)]; | |
| 55 MemcpyState st; | |
| 56 FirmwareImage* image = FirmwareImageNew(); | |
| 57 | |
| 58 if (!image) | |
| 59 return NULL; | |
| 60 | |
| 61 firmware_buf = BufferFromFile(input_file, &file_size); | |
| 62 image_len = file_size; | |
| 63 | |
| 64 st.remaining_len = image_len; | |
| 65 st.remaining_buf = firmware_buf; | |
| 66 st.overrun = 0; | |
| 67 | |
| 68 /* Read and compare magic bytes. */ | |
| 69 StatefulMemcpy(&st, &image->magic, FIRMWARE_MAGIC_SIZE); | |
| 70 if (SafeMemcmp(image->magic, FIRMWARE_MAGIC, FIRMWARE_MAGIC_SIZE)) { | |
| 71 debug("Wrong Firmware Magic.\n"); | |
| 72 Free(firmware_buf); | |
| 73 return NULL; | |
| 74 } | |
| 75 StatefulMemcpy(&st, &image->header_len, FIELD_LEN(header_len)); | |
| 76 StatefulMemcpy(&st, &image->firmware_sign_algorithm, | |
| 77 FIELD_LEN(firmware_sign_algorithm)); | |
| 78 | |
| 79 /* Valid Algorithm? */ | |
| 80 if (image->firmware_sign_algorithm >= kNumAlgorithms) { | |
| 81 Free(firmware_buf); | |
| 82 return NULL; | |
| 83 } | |
| 84 | |
| 85 /* Compute size of pre-processed RSA public key and signature. */ | |
| 86 firmware_sign_key_len = RSAProcessedKeySize(image->firmware_sign_algorithm); | |
| 87 signature_len = siglen_map[image->firmware_sign_algorithm]; | |
| 88 | |
| 89 /* Check whether the header length is correct. */ | |
| 90 header_len = GetFirmwareHeaderLen(image); | |
| 91 if (header_len != image->header_len) { | |
| 92 debug("Header length mismatch. Got: %d Expected: %d\n", | |
| 93 image->header_len, header_len); | |
| 94 Free(firmware_buf); | |
| 95 return NULL; | |
| 96 } | |
| 97 | |
| 98 /* Read pre-processed public half of the sign key. */ | |
| 99 StatefulMemcpy(&st, &image->firmware_key_version, | |
| 100 FIELD_LEN(firmware_key_version)); | |
| 101 image->firmware_sign_key = (uint8_t*) Malloc(firmware_sign_key_len); | |
| 102 StatefulMemcpy(&st, image->firmware_sign_key, firmware_sign_key_len); | |
| 103 StatefulMemcpy(&st, image->header_checksum, FIELD_LEN(header_checksum)); | |
| 104 | |
| 105 /* Check whether the header checksum matches. */ | |
| 106 CalculateFirmwareHeaderChecksum(image, header_checksum); | |
| 107 if (SafeMemcmp(header_checksum, image->header_checksum, | |
| 108 FIELD_LEN(header_checksum))) { | |
| 109 debug("Invalid firmware header checksum!\n"); | |
| 110 Free(firmware_buf); | |
| 111 return NULL; | |
| 112 } | |
| 113 | |
| 114 /* Read key signature. */ | |
| 115 StatefulMemcpy(&st, image->firmware_key_signature, | |
| 116 FIELD_LEN(firmware_key_signature)); | |
| 117 | |
| 118 /* Read the firmware preamble. */ | |
| 119 StatefulMemcpy(&st,&image->firmware_version, FIELD_LEN(firmware_version)); | |
| 120 StatefulMemcpy(&st, &image->firmware_len, FIELD_LEN(firmware_len)); | |
| 121 StatefulMemcpy(&st, &image->kernel_subkey_sign_algorithm, | |
| 122 FIELD_LEN(kernel_subkey_sign_algorithm)); | |
| 123 StatefulMemcpy(&st, image->kernel_subkey_sign_key, | |
| 124 RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); | |
| 125 StatefulMemcpy(&st, image->preamble, FIELD_LEN(preamble)); | |
| 126 | |
| 127 /* Read firmware preamble signature. */ | |
| 128 image->preamble_signature = (uint8_t*) Malloc(signature_len); | |
| 129 StatefulMemcpy(&st, image->preamble_signature, signature_len); | |
| 130 | |
| 131 image->firmware_signature = (uint8_t*) Malloc(signature_len); | |
| 132 StatefulMemcpy(&st, image->firmware_signature, signature_len); | |
| 133 | |
| 134 image->firmware_data = (uint8_t*) Malloc(image->firmware_len); | |
| 135 StatefulMemcpy(&st, image->firmware_data, image->firmware_len); | |
| 136 | |
| 137 if(st.overrun || st.remaining_len != 0) { /* Overrun or underrun. */ | |
| 138 Free(firmware_buf); | |
| 139 return NULL; | |
| 140 } | |
| 141 | |
| 142 Free(firmware_buf); | |
| 143 return image; | |
| 144 } | |
| 145 | |
| 146 int GetFirmwareHeaderLen(const FirmwareImage* image) { | |
| 147 return (FIELD_LEN(header_len) + FIELD_LEN(firmware_sign_algorithm) + | |
| 148 RSAProcessedKeySize(image->firmware_sign_algorithm) + | |
| 149 FIELD_LEN(firmware_key_version) + FIELD_LEN(header_checksum)); | |
| 150 } | |
| 151 | |
| 152 void CalculateFirmwareHeaderChecksum(const FirmwareImage* image, | |
| 153 uint8_t* header_checksum) { | |
| 154 uint8_t* checksum; | |
| 155 DigestContext ctx; | |
| 156 DigestInit(&ctx, SHA512_DIGEST_ALGORITHM); | |
| 157 DigestUpdate(&ctx, (uint8_t*) &image->header_len, | |
| 158 sizeof(image->header_len)); | |
| 159 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, | |
| 160 sizeof(image->firmware_sign_algorithm)); | |
| 161 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version, | |
| 162 sizeof(image->firmware_key_version)); | |
| 163 DigestUpdate(&ctx, image->firmware_sign_key, | |
| 164 RSAProcessedKeySize(image->firmware_sign_algorithm)); | |
| 165 checksum = DigestFinal(&ctx); | |
| 166 Memcpy(header_checksum, checksum, FIELD_LEN(header_checksum)); | |
| 167 Free(checksum); | |
| 168 return; | |
| 169 } | |
| 170 | |
| 171 | |
| 172 uint8_t* GetFirmwareHeaderBlob(const FirmwareImage* image) { | |
| 173 uint8_t* header_blob = NULL; | |
| 174 MemcpyState st; | |
| 175 | |
| 176 header_blob = (uint8_t*) Malloc(GetFirmwareHeaderLen(image)); | |
| 177 st.remaining_len = GetFirmwareHeaderLen(image); | |
| 178 st.remaining_buf = header_blob; | |
| 179 st.overrun = 0; | |
| 180 | |
| 181 StatefulMemcpy_r(&st, &image->header_len, FIELD_LEN(header_len)); | |
| 182 StatefulMemcpy_r(&st, &image->firmware_sign_algorithm, FIELD_LEN(header_len)); | |
| 183 StatefulMemcpy_r(&st, &image->firmware_key_version, | |
| 184 FIELD_LEN(firmware_key_version)); | |
| 185 StatefulMemcpy_r(&st, image->firmware_sign_key, | |
| 186 RSAProcessedKeySize(image->firmware_sign_algorithm)); | |
| 187 StatefulMemcpy_r(&st, &image->header_checksum, FIELD_LEN(header_checksum)); | |
| 188 | |
| 189 if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */ | |
| 190 Free(header_blob); | |
| 191 return NULL; | |
| 192 } | |
| 193 return header_blob; | |
| 194 } | |
| 195 | |
| 196 | |
| 197 uint8_t* GetFirmwarePreambleBlob(const FirmwareImage* image) { | |
| 198 uint8_t* preamble_blob = NULL; | |
| 199 MemcpyState st; | |
| 200 uint64_t preamble_len = GetFirmwarePreambleLen( | |
| 201 image->kernel_subkey_sign_algorithm); | |
| 202 | |
| 203 preamble_blob = (uint8_t*) Malloc(preamble_len); | |
| 204 st.remaining_len = preamble_len; | |
| 205 st.remaining_buf = preamble_blob; | |
| 206 st.overrun = 0; | |
| 207 | |
| 208 StatefulMemcpy_r(&st, &image->firmware_version, FIELD_LEN(firmware_version)); | |
| 209 StatefulMemcpy_r(&st, &image->firmware_len, FIELD_LEN(firmware_len)); | |
| 210 StatefulMemcpy_r(&st, &image->kernel_subkey_sign_algorithm, | |
| 211 FIELD_LEN(kernel_subkey_sign_algorithm)); | |
| 212 StatefulMemcpy_r(&st, image->kernel_subkey_sign_key, | |
| 213 RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); | |
| 214 StatefulMemcpy_r(&st, image->preamble, FIELD_LEN(preamble)); | |
| 215 | |
| 216 if (st.overrun || st.remaining_len != 0 ) { /* Underrun or Overrun. */ | |
| 217 Free(preamble_blob); | |
| 218 return NULL; | |
| 219 } | |
| 220 return preamble_blob; | |
| 221 } | |
| 222 | |
| 223 | |
| 224 uint8_t* GetFirmwareBlob(const FirmwareImage* image, uint64_t* blob_len) { | |
| 225 int firmware_signature_len; | |
| 226 uint8_t* firmware_blob = NULL; | |
| 227 uint8_t* header_blob = NULL; | |
| 228 uint8_t* preamble_blob = NULL; | |
| 229 MemcpyState st; | |
| 230 | |
| 231 if (!image) | |
| 232 return NULL; | |
| 233 | |
| 234 firmware_signature_len = siglen_map[image->firmware_sign_algorithm]; | |
| 235 *blob_len = (FIELD_LEN(magic) + | |
| 236 GetFirmwareHeaderLen(image) + | |
| 237 FIELD_LEN(firmware_key_signature) + | |
| 238 GetFirmwarePreambleLen(image->kernel_subkey_sign_algorithm) + | |
| 239 2 * firmware_signature_len + | |
| 240 image->firmware_len); | |
| 241 firmware_blob = (uint8_t*) Malloc(*blob_len); | |
| 242 st.remaining_len = *blob_len; | |
| 243 st.remaining_buf = firmware_blob; | |
| 244 st.overrun = 0; | |
| 245 | |
| 246 header_blob = GetFirmwareHeaderBlob(image); | |
| 247 preamble_blob = GetFirmwarePreambleBlob(image); | |
| 248 | |
| 249 StatefulMemcpy_r(&st, image->magic, FIELD_LEN(magic)); | |
| 250 StatefulMemcpy_r(&st, header_blob, GetFirmwareHeaderLen(image)); | |
| 251 StatefulMemcpy_r(&st, image->firmware_key_signature, | |
| 252 FIELD_LEN(firmware_key_signature)); | |
| 253 StatefulMemcpy_r(&st, preamble_blob, | |
| 254 GetFirmwarePreambleLen(image->kernel_subkey_sign_algorithm)); | |
| 255 StatefulMemcpy_r(&st, image->preamble_signature, firmware_signature_len); | |
| 256 StatefulMemcpy_r(&st, image->firmware_signature, firmware_signature_len); | |
| 257 StatefulMemcpy_r(&st, image->firmware_data, image->firmware_len); | |
| 258 | |
| 259 Free(preamble_blob); | |
| 260 Free(header_blob); | |
| 261 | |
| 262 if (st.overrun || st.remaining_len != 0) { /* Underrun or Overrun. */ | |
| 263 Free(firmware_blob); | |
| 264 return NULL; | |
| 265 } | |
| 266 return firmware_blob; | |
| 267 } | |
| 268 | |
| 269 int WriteFirmwareImage(const char* output_file, | |
| 270 const FirmwareImage* image, | |
| 271 int is_only_vblock, | |
| 272 int is_subkey_out) { | |
| 273 int fd; | |
| 274 int success = 1; | |
| 275 uint8_t* firmware_blob; | |
| 276 uint8_t* subkey_out_buf = NULL; | |
| 277 uint8_t* subkey_header = NULL; | |
| 278 uint64_t blob_len; | |
| 279 | |
| 280 if (!image) | |
| 281 return 0; | |
| 282 if (-1 == (fd = creat(output_file, 0666))) { | |
| 283 debug("Couldn't open file for writing.\n"); | |
| 284 return 0; | |
| 285 } | |
| 286 if (is_subkey_out) { | |
| 287 blob_len = GetFirmwareHeaderLen(image) + | |
| 288 siglen_map[ROOT_SIGNATURE_ALGORITHM]; | |
| 289 subkey_out_buf = (uint8_t*) Malloc(blob_len); | |
| 290 subkey_header = GetFirmwareHeaderBlob(image); | |
| 291 Memcpy(subkey_out_buf, subkey_header, GetFirmwareHeaderLen(image)); | |
| 292 Memcpy(subkey_out_buf + GetFirmwareHeaderLen(image), | |
| 293 image->firmware_key_signature, | |
| 294 siglen_map[ROOT_SIGNATURE_ALGORITHM]); | |
| 295 if (blob_len != write(fd, subkey_out_buf, blob_len)) { | |
| 296 debug("Couldn't write kernel subkey header to file: %s\n", | |
| 297 output_file); | |
| 298 success = 0; | |
| 299 } | |
| 300 Free(subkey_header); | |
| 301 Free(subkey_out_buf); | |
| 302 close(fd); | |
| 303 return success; | |
| 304 } | |
| 305 | |
| 306 firmware_blob = GetFirmwareBlob(image, &blob_len); | |
| 307 if (!firmware_blob) { | |
| 308 debug("Couldn't create firmware blob from FirmwareImage.\n"); | |
| 309 return 0; | |
| 310 } | |
| 311 if (!is_only_vblock) { | |
| 312 if (blob_len != write(fd, firmware_blob, blob_len)) { | |
| 313 debug("Couldn't write Firmware Image to file: %s\n", output_file); | |
| 314 success = 0; | |
| 315 } | |
| 316 } else { | |
| 317 /* Exclude the firmware_data. */ | |
| 318 int vblock_len = blob_len - image->firmware_len; | |
| 319 if (vblock_len != write(fd, firmware_blob, vblock_len)) { | |
| 320 debug("Couldn't write Firmware Image verifcation block to file: %s\n", | |
| 321 output_file); | |
| 322 success = 0; | |
| 323 } | |
| 324 } | |
| 325 Free(firmware_blob); | |
| 326 close(fd); | |
| 327 return success; | |
| 328 } | |
| 329 | |
| 330 void PrintFirmwareImage(const FirmwareImage* image) { | |
| 331 if (!image) | |
| 332 return; | |
| 333 | |
| 334 /* Print header. */ | |
| 335 debug("Header Length = %d\n" | |
| 336 "Firmware Signature Algorithm = %s\n" | |
| 337 "Firmware Key Version = %d\n\n", | |
| 338 image->header_len, | |
| 339 algo_strings[image->firmware_sign_algorithm], | |
| 340 image->firmware_key_version); | |
| 341 /* TODO(gauravsh): Output hash and key signature here? */ | |
| 342 /* Print preamble. */ | |
| 343 debug("Firmware Version = %d\n" | |
| 344 "Firmware Length = %" PRIu64 "\n\n", | |
| 345 image->firmware_version, | |
| 346 image->firmware_len); | |
| 347 /* Output key signature here? */ | |
| 348 } | |
| 349 | |
| 350 int VerifyFirmwareImage(const RSAPublicKey* root_key, | |
| 351 const FirmwareImage* image) { | |
| 352 RSAPublicKey* firmware_sign_key = NULL; | |
| 353 uint8_t* header_digest = NULL; | |
| 354 uint8_t* preamble_digest = NULL; | |
| 355 uint8_t* firmware_digest = NULL; | |
| 356 int firmware_sign_key_size; | |
| 357 int signature_size; | |
| 358 int error_code = 0; | |
| 359 DigestContext ctx; | |
| 360 DigestContext firmware_ctx; | |
| 361 | |
| 362 if (!image) | |
| 363 return VERIFY_FIRMWARE_INVALID_IMAGE; | |
| 364 | |
| 365 /* Verify root key signature on the sign key header if we | |
| 366 * are not in dev mode. | |
| 367 * | |
| 368 * TODO(gauravsh): Add additional sanity checks here for: | |
| 369 * 1) verifying the header length is correct. | |
| 370 * 2) header_checksum is correct. | |
| 371 */ | |
| 372 | |
| 373 /* Check key signature. */ | |
| 374 DigestInit(&ctx, ROOT_SIGNATURE_ALGORITHM); | |
| 375 DigestUpdate(&ctx, (uint8_t*) &image->header_len, | |
| 376 FIELD_LEN(header_len)); | |
| 377 DigestUpdate(&ctx, (uint8_t*) &image->firmware_sign_algorithm, | |
| 378 FIELD_LEN(firmware_sign_algorithm)); | |
| 379 DigestUpdate(&ctx, (uint8_t*) &image->firmware_key_version, | |
| 380 FIELD_LEN(firmware_key_version)); | |
| 381 DigestUpdate(&ctx, image->firmware_sign_key, | |
| 382 RSAProcessedKeySize(image->firmware_sign_algorithm)); | |
| 383 DigestUpdate(&ctx, image->header_checksum, | |
| 384 FIELD_LEN(header_checksum)); | |
| 385 header_digest = DigestFinal(&ctx); | |
| 386 if (!RSAVerify(root_key, image->firmware_key_signature, | |
| 387 FIELD_LEN(firmware_key_signature), | |
| 388 ROOT_SIGNATURE_ALGORITHM, | |
| 389 header_digest)) { | |
| 390 error_code = VERIFY_FIRMWARE_ROOT_SIGNATURE_FAILED; | |
| 391 goto verify_failure; | |
| 392 } | |
| 393 | |
| 394 /* Get sign key to verify the rest of the firmware. */ | |
| 395 firmware_sign_key_size = RSAProcessedKeySize(image->firmware_sign_algorithm); | |
| 396 firmware_sign_key = RSAPublicKeyFromBuf(image->firmware_sign_key, | |
| 397 firmware_sign_key_size); | |
| 398 signature_size = siglen_map[image->firmware_sign_algorithm]; | |
| 399 | |
| 400 if (image->firmware_sign_algorithm >= kNumAlgorithms) | |
| 401 return VERIFY_FIRMWARE_INVALID_ALGORITHM; | |
| 402 | |
| 403 /* Verify firmware preamble signature. */ | |
| 404 DigestInit(&ctx, image->firmware_sign_algorithm); | |
| 405 DigestUpdate(&ctx, (uint8_t*) &image->firmware_version, | |
| 406 FIELD_LEN(firmware_version)); | |
| 407 DigestUpdate(&ctx, (uint8_t*) &image->firmware_len, | |
| 408 FIELD_LEN(firmware_len)); | |
| 409 DigestUpdate(&ctx, (uint8_t*) &image->kernel_subkey_sign_algorithm, | |
| 410 FIELD_LEN(kernel_subkey_sign_algorithm)); | |
| 411 DigestUpdate(&ctx, (uint8_t*) image->kernel_subkey_sign_key, | |
| 412 RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); | |
| 413 DigestUpdate(&ctx, (uint8_t*) &image->preamble, | |
| 414 FIELD_LEN(preamble)); | |
| 415 preamble_digest = DigestFinal(&ctx); | |
| 416 if (!RSAVerify(firmware_sign_key, image->preamble_signature, | |
| 417 signature_size, image->firmware_sign_algorithm, | |
| 418 preamble_digest)) { | |
| 419 error_code = VERIFY_FIRMWARE_PREAMBLE_SIGNATURE_FAILED; | |
| 420 goto verify_failure; | |
| 421 } | |
| 422 | |
| 423 /* Verify firmware signature - firmware signature is on the contents | |
| 424 of firmware preamble + firmware_data. */ | |
| 425 DigestInit(&firmware_ctx, image->firmware_sign_algorithm); | |
| 426 DigestUpdate(&firmware_ctx, (uint8_t*) &image->firmware_version, | |
| 427 FIELD_LEN(firmware_version)); | |
| 428 DigestUpdate(&firmware_ctx, (uint8_t*) &image->firmware_len, | |
| 429 FIELD_LEN(firmware_len)); | |
| 430 DigestUpdate(&firmware_ctx, (uint8_t*) &image->kernel_subkey_sign_algorithm, | |
| 431 FIELD_LEN(kernel_subkey_sign_algorithm)); | |
| 432 DigestUpdate(&firmware_ctx, (uint8_t*) image->kernel_subkey_sign_key, | |
| 433 RSAProcessedKeySize(image->kernel_subkey_sign_algorithm)); | |
| 434 DigestUpdate(&firmware_ctx, (uint8_t*) &image->preamble, | |
| 435 FIELD_LEN(preamble)); | |
| 436 DigestUpdate(&firmware_ctx, image->firmware_data, image->firmware_len); | |
| 437 firmware_digest = DigestFinal(&firmware_ctx); | |
| 438 if (!RSAVerify(firmware_sign_key, image->firmware_signature, | |
| 439 signature_size, image->firmware_sign_algorithm, | |
| 440 firmware_digest)) { | |
| 441 error_code = VERIFY_FIRMWARE_SIGNATURE_FAILED; | |
| 442 goto verify_failure; | |
| 443 } | |
| 444 | |
| 445 verify_failure: | |
| 446 RSAPublicKeyFree(firmware_sign_key); | |
| 447 Free(firmware_digest); | |
| 448 Free(preamble_digest); | |
| 449 Free(header_digest); | |
| 450 return error_code; | |
| 451 } | |
| 452 | |
| 453 const char* VerifyFirmwareErrorString(int error) { | |
| 454 return kVerifyFirmwareErrors[error]; | |
| 455 } | |
| 456 | |
| 457 int AddFirmwareKeySignature(FirmwareImage* image, const char* root_key_file) { | |
| 458 uint8_t* header_blob = NULL; | |
| 459 uint8_t* signature; | |
| 460 if (!image || !root_key_file) | |
| 461 return 0; | |
| 462 header_blob = GetFirmwareHeaderBlob(image); | |
| 463 if (!header_blob) | |
| 464 return 0; | |
| 465 if (!(signature = SignatureBuf(header_blob, | |
| 466 GetFirmwareHeaderLen(image), | |
| 467 root_key_file, | |
| 468 ROOT_SIGNATURE_ALGORITHM))) { | |
| 469 Free(header_blob); | |
| 470 return 0; | |
| 471 } | |
| 472 Memcpy(image->firmware_key_signature, signature, RSA8192NUMBYTES); | |
| 473 Free(header_blob); | |
| 474 Free(signature); | |
| 475 return 1; | |
| 476 } | |
| 477 | |
| 478 int AddFirmwareSignature(FirmwareImage* image, const char* signing_key_file) { | |
| 479 uint8_t* preamble_blob = NULL; | |
| 480 uint8_t* preamble_signature = NULL; | |
| 481 uint8_t* firmware_signature = NULL; | |
| 482 uint8_t* firmware_buf = NULL; | |
| 483 int signature_len = siglen_map[image->firmware_sign_algorithm]; | |
| 484 uint64_t preamble_len = GetFirmwarePreambleLen( | |
| 485 image->kernel_subkey_sign_algorithm); | |
| 486 | |
| 487 preamble_blob = GetFirmwarePreambleBlob(image); | |
| 488 if (!preamble_blob) | |
| 489 return 0; | |
| 490 if (!(preamble_signature = SignatureBuf(preamble_blob, | |
| 491 preamble_len, | |
| 492 signing_key_file, | |
| 493 image->firmware_sign_algorithm))) { | |
| 494 Free(preamble_blob); | |
| 495 return 0; | |
| 496 } | |
| 497 image->preamble_signature = (uint8_t*) Malloc(signature_len); | |
| 498 Memcpy(image->preamble_signature, preamble_signature, signature_len); | |
| 499 Free(preamble_signature); | |
| 500 /* Firmware signature must be calculated on preamble + firmware_data | |
| 501 * to avoid splicing attacks. */ | |
| 502 firmware_buf = (uint8_t*) Malloc(preamble_len + | |
| 503 image->firmware_len); | |
| 504 Memcpy(firmware_buf, preamble_blob, preamble_len); | |
| 505 Memcpy(firmware_buf + preamble_len, image->firmware_data, | |
| 506 image->firmware_len); | |
| 507 if (!(firmware_signature = SignatureBuf(firmware_buf, | |
| 508 preamble_len + | |
| 509 image->firmware_len, | |
| 510 signing_key_file, | |
| 511 image->firmware_sign_algorithm))) { | |
| 512 Free(preamble_blob); | |
| 513 Free(firmware_buf); | |
| 514 return 0; | |
| 515 } | |
| 516 image->firmware_signature = (uint8_t*) Malloc(signature_len); | |
| 517 Memcpy(image->firmware_signature, firmware_signature, signature_len); | |
| 518 Free(firmware_signature); | |
| 519 Free(firmware_buf); | |
| 520 Free(preamble_blob); | |
| 521 return 1; | |
| 522 } | |
| OLD | NEW |