1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include <assert.h> 17 #include <libcr51sign/libcr51sign.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 22 #ifdef __cplusplus 23 extern "C" 24 { 25 #endif 26 27 #ifndef USER_PRINT 28 #define CPRINTS(ctx, ...) fprintf(stderr, __VA_ARGS__) 29 #endif 30 31 #define MEMBER_SIZE(type, field) sizeof(((type*)0)->field) 32 33 // True of x is a power of two 34 #define POWER_OF_TWO(x) ((x) && !((x) & ((x)-1))) 35 36 // Maximum version supported. Major revisions are not backwards compatible. 37 #define MAX_MAJOR_VERSION 1 38 39 // Descriptor alignment on the external EEPROM. 40 #define DESCRIPTOR_ALIGNMENT (64 * 1024) 41 42 // SPS EEPROM sector size is 4KiB, since this is the smallest erasable size. 43 #define IMAGE_REGION_ALIGNMENT 4096 44 45 #define MAX_READ_SIZE 1024 46 47 #ifndef ARRAY_SIZE 48 #define ARRAY_SIZE(t) (sizeof(t) / sizeof(t[0])) 49 #endif 50 51 // Values of SIGNATURE_OFFSET shuold be same for all sig types (2048,3072,4096) 52 #define SIGNATURE_OFFSET offsetof(struct signature_rsa3072_pkcs15, modulus) 53 54 #ifndef BUILD_ASSERT 55 #define BUILD_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)])) 56 #endif 57 58 typedef enum libcr51sign_validation_failure_reason failure_reason; 59 60 // Returns the bytes size of keys used in the given signature_scheme. 61 // Return error if signature_scheme is invalid. 62 // 63 static failure_reason get_key_size(enum signature_scheme signature_scheme, 64 uint16_t* key_size) 65 { 66 switch (signature_scheme) 67 { 68 case SIGNATURE_RSA2048_PKCS15: 69 *key_size = 256; 70 return LIBCR51SIGN_SUCCESS; 71 case SIGNATURE_RSA3072_PKCS15: 72 *key_size = 384; 73 return LIBCR51SIGN_SUCCESS; 74 case SIGNATURE_RSA4096_PKCS15: 75 case SIGNATURE_RSA4096_PKCS15_SHA512: 76 *key_size = 512; 77 return LIBCR51SIGN_SUCCESS; 78 default: 79 return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME; 80 } 81 } 82 83 // Returns the hash_type for a given signature scheme 84 // Returns error if scheme is invalid. 85 failure_reason get_hash_type_from_signature(enum signature_scheme scheme, 86 enum hash_type* type) 87 { 88 switch (scheme) 89 { 90 case SIGNATURE_RSA2048_PKCS15: 91 case SIGNATURE_RSA3072_PKCS15: 92 case SIGNATURE_RSA4096_PKCS15: 93 *type = HASH_SHA2_256; 94 return LIBCR51SIGN_SUCCESS; 95 case SIGNATURE_RSA4096_PKCS15_SHA512: 96 *type = HASH_SHA2_512; 97 return LIBCR51SIGN_SUCCESS; 98 default: 99 return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME; 100 } 101 } 102 103 // Check if the given hash_type is supported. 104 // Returns error if hash_type is not supported. 105 static failure_reason is_hash_type_supported(enum hash_type type) 106 { 107 switch (type) 108 { 109 case HASH_SHA2_256: 110 case HASH_SHA2_512: 111 return LIBCR51SIGN_SUCCESS; 112 default: 113 return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE; 114 } 115 } 116 117 // Determines digest size for a given hash_type. 118 // Returns error if hash_type is not supported. 119 static failure_reason get_hash_digest_size(enum hash_type type, 120 uint32_t* size) 121 { 122 switch (type) 123 { 124 case HASH_SHA2_256: 125 *size = LIBCR51SIGN_SHA256_DIGEST_SIZE; 126 return LIBCR51SIGN_SUCCESS; 127 case HASH_SHA2_512: 128 *size = LIBCR51SIGN_SHA512_DIGEST_SIZE; 129 return LIBCR51SIGN_SUCCESS; 130 default: 131 return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE; 132 } 133 } 134 135 // Determines hash struct size for a given hash_type. 136 // Returns error if hash_type is not supported. 137 static failure_reason get_hash_struct_size(enum hash_type type, 138 uint32_t* size) 139 { 140 switch (type) 141 { 142 case HASH_SHA2_256: 143 *size = sizeof(struct hash_sha256); 144 return LIBCR51SIGN_SUCCESS; 145 case HASH_SHA2_512: 146 *size = sizeof(struct hash_sha256); 147 return LIBCR51SIGN_SUCCESS; 148 default: 149 return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE; 150 } 151 } 152 153 // Checks that: 154 // - The signing key is trusted 155 // - The target version is not denylisted 156 // If validating a staged update, also checks that: 157 // - The target image family matches the current image family 158 // - The image type transition is legal (i.e. dev -> *|| prod -> prod) or 159 // alternatively that the hardware ID is allowlisted 160 // Assuming the caller has performed following: 161 // board_get_base_key_index(); 162 // board_get_key_array 163 // Possible return codes: 164 // LIBCR51SIGN_SUCCESS = 0, 165 // LIBCR51SIGN_ERROR_RUNTIME_FAILURE = 1, 166 // LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR = 3, 167 // LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY = 4, 168 // LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED = 5, 169 170 static failure_reason 171 validate_transition(const struct libcr51sign_ctx* ctx, 172 const struct libcr51sign_intf* intf, 173 uint32_t signature_struct_offset) 174 { 175 BUILD_ASSERT((offsetof(struct signature_rsa2048_pkcs15, modulus) == 176 SIGNATURE_OFFSET && 177 offsetof(struct signature_rsa3072_pkcs15, modulus) == 178 SIGNATURE_OFFSET && 179 offsetof(struct signature_rsa4096_pkcs15, modulus) == 180 SIGNATURE_OFFSET)); 181 182 // Read up to the modulus. 183 enum 184 { 185 read_len = SIGNATURE_OFFSET 186 }; 187 uint8_t buffer[read_len]; 188 // "modulus" & "signature" will not be indexed. 189 struct signature_rsa4096_pkcs15* sig_data = (void*)&buffer; 190 int rv; 191 rv = intf->read(ctx, signature_struct_offset, read_len, buffer); 192 if (rv != LIBCR51SIGN_SUCCESS) 193 { 194 CPRINTS(ctx, 195 "validate_transition: failed to read signature struct"); 196 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 197 } 198 if (sig_data->signature_magic != SIGNATURE_MAGIC) 199 { 200 CPRINTS(ctx, "validate_transition: bad signature magic"); 201 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 202 } 203 204 if (ctx->descriptor.image_family != ctx->current_image_family && 205 ctx->descriptor.image_family != IMAGE_FAMILY_ALL && 206 ctx->current_image_family != IMAGE_FAMILY_ALL) 207 { 208 CPRINTS(ctx, "validate_transition: invalid image family"); 209 return LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY; 210 } 211 212 if (intf->is_production_mode == NULL) 213 { 214 CPRINTS(ctx, "validate_transition: missing is_production_mode"); 215 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 216 } 217 if (intf->is_production_mode() && 218 (ctx->descriptor.image_type == IMAGE_DEV)) 219 { 220 CPRINTS(ctx, "validate_transition: checking exemption allowlist"); 221 222 // If function is NULL or if the function call return false, return 223 // error 224 if (intf->prod_to_dev_downgrade_allowed == NULL || 225 !intf->prod_to_dev_downgrade_allowed()) 226 { 227 CPRINTS(ctx, "validate_transition: illegal image type"); 228 return LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED; 229 } 230 } 231 return LIBCR51SIGN_SUCCESS; 232 } 233 234 // If caller had provided read_and_hash_update call that, otherwise call 235 // read and then update. 236 237 static failure_reason 238 read_and_hash_update(const struct libcr51sign_ctx* ctx, 239 const struct libcr51sign_intf* intf, 240 uint32_t offset, uint32_t size) 241 { 242 uint8_t read_buffer[MAX_READ_SIZE]; 243 int rv; 244 int read_size; 245 246 if (intf->read_and_hash_update) 247 { 248 rv = intf->read_and_hash_update((void*)ctx, offset, size); 249 } 250 else 251 { 252 if (!intf->hash_update) 253 { 254 CPRINTS(ctx, "read_and_hash_update: missing hash_update"); 255 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 256 } 257 do 258 { 259 read_size = size < MAX_READ_SIZE ? size : MAX_READ_SIZE; 260 rv = intf->read((void*)ctx, offset, read_size, read_buffer); 261 if (rv != LIBCR51SIGN_SUCCESS) 262 { 263 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 264 } 265 rv = intf->hash_update((void*)ctx, read_buffer, read_size); 266 if (rv != LIBCR51SIGN_SUCCESS) 267 { 268 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 269 } 270 offset += read_size; 271 size -= read_size; 272 } while (size > 0); 273 } 274 return rv; 275 } 276 277 // Validates the image_region array, namely that: 278 // - The regions are aligned, contiguous & exhaustive 279 // - That the image descriptor resides in a static region 280 // 281 // If the array is consistent, proceeds to hash the static regions and 282 // validates the hash. d_offset is the absolute image descriptor offset 283 284 static failure_reason validate_payload_regions( 285 const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf, 286 uint32_t d_offset, struct libcr51sign_validated_regions* image_regions) 287 { 288 // Allocate buffer to accomodate largest supported hash-type(SHA512) 289 uint8_t magic_and_digest[MEMBER_SIZE(struct hash_sha512, hash_magic) + 290 LIBCR51SIGN_SHA512_DIGEST_SIZE]; 291 uint8_t dcrypto_digest[LIBCR51SIGN_SHA512_DIGEST_SIZE]; 292 uint32_t byte_count, region_count, image_size, hash_offset, digest_size; 293 uint32_t i; 294 uint8_t d_region_num = 0; 295 int rv; 296 struct image_region const* region; 297 298 if (image_regions == NULL) 299 { 300 CPRINTS(ctx, "Missing image region input"); 301 return LIBCR51SIGN_ERROR_INVALID_REGION_INPUT; 302 } 303 304 BUILD_ASSERT((MEMBER_SIZE(struct hash_sha256, hash_magic) == 305 MEMBER_SIZE(struct hash_sha512, hash_magic))); 306 image_size = ctx->descriptor.image_size; 307 region_count = ctx->descriptor.region_count; 308 hash_offset = d_offset + sizeof(struct image_descriptor) + 309 region_count * sizeof(struct image_region); 310 // Read the image_region array. 311 312 if (region_count > ARRAY_SIZE(image_regions->image_regions)) 313 { 314 CPRINTS(ctx, "validate_payload_regions: " 315 "ctx->descriptor.region_count is greater " 316 "than LIBCR51SIGN_MAX_REGION_COUNT"); 317 return LIBCR51SIGN_ERROR_INVALID_REGION_SIZE; 318 } 319 320 rv = intf->read(ctx, d_offset + sizeof(struct image_descriptor), 321 region_count * sizeof(struct image_region), 322 (uint8_t*)&image_regions->image_regions); 323 324 image_regions->region_count = region_count; 325 326 if (rv != LIBCR51SIGN_SUCCESS) 327 { 328 CPRINTS(ctx, 329 "validate_payload_regions: failed to read region array"); 330 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 331 } 332 333 // Validate that the regions are contiguous & exhaustive. 334 for (i = 0, byte_count = 0; i < region_count; i++) 335 { 336 region = image_regions->image_regions + i; 337 338 CPRINTS(ctx, 339 "validate_payload_regions: region #%d \"%s\" (%x - %x)", i, 340 (const char*)region->region_name, region->region_offset, 341 region->region_offset + region->region_size); 342 if ((region->region_offset % IMAGE_REGION_ALIGNMENT) != 0 || 343 (region->region_size % IMAGE_REGION_ALIGNMENT) != 0) 344 { 345 CPRINTS( 346 ctx, 347 "validate_payload_regions: regions must be sector aligned"); 348 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 349 } 350 if (region->region_offset != byte_count || 351 region->region_size > image_size - byte_count) 352 { 353 CPRINTS(ctx, "validate_payload_regions: invalid region array"); 354 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 355 } 356 byte_count += region->region_size; 357 // The image descriptor must be part of a static region. 358 if (d_offset >= region->region_offset && d_offset < byte_count) 359 { 360 d_region_num = i; 361 CPRINTS( 362 ctx, 363 "validate_payload_regions: image descriptor in region %d", 364 i); 365 // The descriptor can't span regions. 366 if (ctx->descriptor.descriptor_area_size > byte_count || 367 !(region->region_attributes & IMAGE_REGION_STATIC)) 368 { 369 CPRINTS( 370 ctx, 371 "validate_payload_regions: descriptor must reside in " 372 "static region"); 373 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 374 } 375 } 376 } 377 if (byte_count != image_size) 378 { 379 CPRINTS(ctx, "validate_payload_regions: invalid image size"); 380 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 381 } 382 383 rv = get_hash_digest_size(ctx->descriptor.hash_type, &digest_size); 384 if (rv != LIBCR51SIGN_SUCCESS) 385 { 386 return rv; 387 } 388 389 rv = intf->read(ctx, hash_offset, 390 MEMBER_SIZE(struct hash_sha256, hash_magic) + 391 digest_size, 392 magic_and_digest); 393 if (rv != LIBCR51SIGN_SUCCESS) 394 { 395 CPRINTS(ctx, 396 "validate_payload_regions: failed to read hash from flash"); 397 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 398 } 399 if (*(uint32_t*)magic_and_digest != HASH_MAGIC) 400 { 401 CPRINTS(ctx, "validate_payload_regions: bad hash magic"); 402 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 403 } 404 rv = intf->hash_init(ctx, ctx->descriptor.hash_type); 405 if (rv != LIBCR51SIGN_SUCCESS) 406 { 407 CPRINTS(ctx, "validate_payload_regions: hash_init failed"); 408 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 409 } 410 for (i = 0; i < region_count; i++) 411 { 412 uint32_t hash_start, hash_size; 413 region = image_regions->image_regions + i; 414 415 if (!(region->region_attributes & IMAGE_REGION_STATIC)) 416 { 417 continue; 418 } 419 hash_start = region->region_offset; 420 hash_size = region->region_size; 421 422 // Skip the descriptor. 423 do 424 { 425 if (i == d_region_num) 426 { 427 hash_size = d_offset - hash_start; 428 } 429 430 if (!hash_size) 431 { 432 hash_start += ctx->descriptor.descriptor_area_size; 433 hash_size = (region->region_offset + region->region_size - 434 hash_start); 435 } 436 CPRINTS("validate_payload_regions: hashing %s (%x - %x)", 437 (const char*)region->region_name, hash_start, 438 hash_start + hash_size); 439 // Read the image_region array. 440 rv = read_and_hash_update(ctx, intf, hash_start, hash_size); 441 if (rv != LIBCR51SIGN_SUCCESS) 442 { 443 return rv; 444 } 445 hash_start += hash_size; 446 } while (hash_start != region->region_offset + region->region_size); 447 } 448 rv = intf->hash_final((void*)ctx, (uint8_t*)dcrypto_digest); 449 450 if (rv != LIBCR51SIGN_SUCCESS) 451 { 452 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 453 } 454 455 if (memcmp(magic_and_digest + 456 MEMBER_SIZE(struct hash_sha256, hash_magic), 457 dcrypto_digest, digest_size)) 458 { 459 CPRINTS(ctx, "validate_payload_regions: invalid hash"); 460 return LIBCR51SIGN_ERROR_INVALID_HASH; 461 } 462 // Image is valid. 463 return LIBCR51SIGN_SUCCESS; 464 } 465 466 // Create empty image_regions to pass to validate_payload_regions 467 // Support validate_payload_regions_helper to remove image_regions as a 468 // required input. 469 470 static failure_reason 471 allocate_and_validate_payload_regions(const struct libcr51sign_ctx* ctx, 472 struct libcr51sign_intf* intf, 473 uint32_t d_offset) 474 { 475 struct libcr51sign_validated_regions image_regions; 476 return validate_payload_regions(ctx, intf, d_offset, &image_regions); 477 } 478 479 // Wrapper around validate_payload_regions to allow nullptr for 480 // image_regions. Calls allocate_and_validate_payload_regions when 481 // image_regions is nullptr to create placer holder image_regions. 482 483 static failure_reason validate_payload_regions_helper( 484 const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf, 485 uint32_t d_offset, struct libcr51sign_validated_regions* image_regions) 486 { 487 if (image_regions) 488 { 489 return validate_payload_regions(ctx, intf, d_offset, image_regions); 490 } 491 492 return allocate_and_validate_payload_regions(ctx, intf, d_offset); 493 } 494 495 // Check if the given signature_scheme is supported. 496 // Returns nonzero on error, zero on success 497 498 static failure_reason 499 is_signature_scheme_supported(enum signature_scheme scheme) 500 { 501 switch (scheme) 502 { 503 case SIGNATURE_RSA2048_PKCS15: 504 case SIGNATURE_RSA3072_PKCS15: 505 case SIGNATURE_RSA4096_PKCS15: 506 case SIGNATURE_RSA4096_PKCS15_SHA512: 507 return LIBCR51SIGN_SUCCESS; 508 default: 509 return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME; 510 } 511 } 512 513 // Returns size of signature struct size in |size| 514 // Returns nonzero on error, zero on success 515 516 static failure_reason 517 get_signature_struct_size(enum signature_scheme scheme, uint32_t* size) 518 { 519 switch (scheme) 520 { 521 case SIGNATURE_RSA2048_PKCS15: 522 *size = sizeof(struct signature_rsa2048_pkcs15); 523 return LIBCR51SIGN_SUCCESS; 524 case SIGNATURE_RSA3072_PKCS15: 525 *size = sizeof(struct signature_rsa3072_pkcs15); 526 return LIBCR51SIGN_SUCCESS; 527 case SIGNATURE_RSA4096_PKCS15: 528 case SIGNATURE_RSA4096_PKCS15_SHA512: 529 *size = sizeof(struct signature_rsa4096_pkcs15); 530 return LIBCR51SIGN_SUCCESS; 531 default: 532 return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME; 533 } 534 } 535 536 static failure_reason 537 get_signature_field_offset(enum signature_scheme scheme, 538 uint32_t* offset) 539 { 540 switch (scheme) 541 { 542 case SIGNATURE_RSA2048_PKCS15: 543 *offset = offsetof(struct signature_rsa2048_pkcs15, signature); 544 return LIBCR51SIGN_SUCCESS; 545 case SIGNATURE_RSA3072_PKCS15: 546 *offset = offsetof(struct signature_rsa3072_pkcs15, signature); 547 return LIBCR51SIGN_SUCCESS; 548 case SIGNATURE_RSA4096_PKCS15: 549 case SIGNATURE_RSA4096_PKCS15_SHA512: 550 *offset = offsetof(struct signature_rsa4096_pkcs15, signature); 551 return LIBCR51SIGN_SUCCESS; 552 default: 553 return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME; 554 } 555 } 556 557 // Validates the signature (of type scheme) read from "device" at 558 //"raw_signature_offset" with "public_key" over a SHA256/SHA512 digest of 559 // EEPROM area "data_offset:data_size". 560 561 static failure_reason validate_signature( 562 const struct libcr51sign_ctx* ctx, const struct libcr51sign_intf* intf, 563 uint32_t data_offset, uint32_t data_size, enum signature_scheme scheme, 564 uint32_t raw_signature_offset) 565 { 566 uint8_t signature[LIBCR51SIGN_MAX_SIGNATURE_SIZE]; 567 uint16_t key_size; 568 uint32_t digest_size; 569 uint8_t dcrypto_digest[LIBCR51SIGN_SHA512_DIGEST_SIZE]; 570 int rv; 571 enum hash_type hash_type; 572 573 if (!intf->hash_init) 574 { 575 CPRINTS(ctx, "validate_signature: missing hash_init"); 576 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 577 } 578 rv = get_hash_type_from_signature(scheme, &hash_type); 579 if (rv != LIBCR51SIGN_SUCCESS) 580 { 581 CPRINTS( 582 ctx, 583 "validate_payload_regions: hash_type from signature failed"); 584 return rv; 585 } 586 rv = intf->hash_init(ctx, hash_type); 587 if (rv != LIBCR51SIGN_SUCCESS) 588 { 589 CPRINTS(ctx, "validate_payload_regions: hash_init failed"); 590 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 591 } 592 rv = read_and_hash_update(ctx, intf, data_offset, data_size); 593 if (rv != LIBCR51SIGN_SUCCESS) 594 { 595 CPRINTS(ctx, "validate_signature: hash_update failed"); 596 return rv; 597 } 598 if (!intf->hash_final) 599 { 600 CPRINTS(ctx, "validate_signature: missing hash_final"); 601 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 602 } 603 rv = intf->hash_final((void*)ctx, dcrypto_digest); 604 if (rv != LIBCR51SIGN_SUCCESS) 605 { 606 CPRINTS(ctx, "validate_signature: hash_final failed (status = %d)", 607 rv); 608 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 609 } 610 rv = get_key_size(scheme, &key_size); 611 if (rv != LIBCR51SIGN_SUCCESS) 612 { 613 return rv; 614 } 615 616 rv = intf->read(ctx, raw_signature_offset, key_size, signature); 617 if (rv != LIBCR51SIGN_SUCCESS) 618 { 619 CPRINTS( 620 ctx, 621 "validate_signature: failed to read signature (status = %d)", 622 rv); 623 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 624 } 625 if (!intf->verify_signature) 626 { 627 CPRINTS(ctx, "validate_signature: missing verify_signature"); 628 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 629 } 630 rv = get_hash_digest_size(hash_type, &digest_size); 631 if (rv != LIBCR51SIGN_SUCCESS) 632 { 633 return rv; 634 } 635 rv = intf->verify_signature(ctx, scheme, signature, key_size, 636 dcrypto_digest, digest_size); 637 if (rv != LIBCR51SIGN_SUCCESS) 638 { 639 CPRINTS(ctx, 640 "validate_signature: verification failed (status = %d)", 641 rv); 642 return LIBCR51SIGN_ERROR_INVALID_SIGNATURE; 643 } 644 CPRINTS(ctx, "validate_signature: verification succeeded"); 645 return LIBCR51SIGN_SUCCESS; 646 } 647 648 // Sanity checks the image descriptor & validates its signature. 649 // This function does not validate the image_region array or image hash. 650 // 651 //@param[in] ctx context which describes the image and holds opaque private 652 // data for the user of the library 653 //@param[in] intf function pointers which interface to the current system 654 // and environment 655 //@param offset Absolute image descriptor flash offset. 656 //@param relative_offset Image descriptor offset relative to image start. 657 //@param image_size Image size in bytes. 658 //@param descriptor Output pointer to an image_descriptor struct 659 660 static failure_reason validate_descriptor( 661 const struct libcr51sign_ctx* ctx, const struct libcr51sign_intf* intf, 662 uint32_t offset, uint32_t relative_offset, uint32_t image_size) 663 { 664 uint32_t max_descriptor_size, signed_size, signature_scheme, 665 signature_offset; 666 uint32_t signature_struct_offset, signature_struct_size, 667 hash_struct_size; 668 int rv; 669 670 max_descriptor_size = image_size - relative_offset; 671 if (image_size < relative_offset || 672 max_descriptor_size < sizeof(struct image_descriptor)) 673 { 674 CPRINTS(ctx, "validate_descriptor: invalid arguments"); 675 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 676 } 677 678 rv = intf->read(ctx, offset, sizeof(ctx->descriptor), 679 (uint8_t*)&ctx->descriptor); 680 if (rv != LIBCR51SIGN_SUCCESS) 681 { 682 CPRINTS(ctx, "validate_descriptor: failed to read descriptor"); 683 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 684 } 685 if (ctx->descriptor.descriptor_magic != DESCRIPTOR_MAGIC || 686 ctx->descriptor.descriptor_offset != relative_offset || 687 ctx->descriptor.region_count == 0 || 688 ctx->descriptor.descriptor_area_size > max_descriptor_size || 689 ctx->descriptor.image_size != image_size) 690 { 691 CPRINTS(ctx, "validate_descriptor: invalid descriptor"); 692 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 693 } 694 if (ctx->descriptor.image_type != IMAGE_DEV && 695 ctx->descriptor.image_type != IMAGE_PROD && 696 ctx->descriptor.image_type != IMAGE_BREAKOUT && 697 ctx->descriptor.image_type != IMAGE_TEST && 698 ctx->descriptor.image_type != IMAGE_UNSIGNED_INTEGRITY) 699 { 700 CPRINTS(ctx, "validate_descriptor: bad image type"); 701 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 702 } 703 // Although the image_descriptor struct supports unauthenticated 704 // images, Haven will not allow it. 705 // Haven only supports SHA256 + RSA2048/RSA3072_PKCS15 currently. 706 707 signature_scheme = ctx->descriptor.signature_scheme; 708 709 rv = is_signature_scheme_supported(signature_scheme); 710 if (rv != LIBCR51SIGN_SUCCESS) 711 { 712 return rv; 713 } 714 rv = is_hash_type_supported(ctx->descriptor.hash_type); 715 if (rv != LIBCR51SIGN_SUCCESS) 716 { 717 CPRINTS(ctx, "validate_payload_regions: invalid hash type"); 718 return rv; 719 } 720 if (ctx->descriptor.descriptor_major > MAX_MAJOR_VERSION || 721 ctx->descriptor.region_count > LIBCR51SIGN_MAX_REGION_COUNT) 722 { 723 CPRINTS(ctx, "validate_descriptor: unsupported descriptor"); 724 return LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR; 725 } 726 rv = 727 get_signature_struct_size(signature_scheme, &signature_struct_size); 728 if (rv != LIBCR51SIGN_SUCCESS) 729 { 730 return rv; 731 } 732 733 // Compute the size of the signed portion of the image descriptor. 734 signed_size = 735 sizeof(struct image_descriptor) + 736 ctx->descriptor.region_count * sizeof(struct image_region); 737 rv = get_hash_struct_size(ctx->descriptor.hash_type, &hash_struct_size); 738 if (rv != LIBCR51SIGN_SUCCESS) 739 { 740 return rv; 741 } 742 signed_size += hash_struct_size; 743 if (ctx->descriptor.denylist_size) 744 { 745 signed_size += sizeof(struct denylist); 746 signed_size += 747 ctx->descriptor.denylist_size * sizeof(struct denylist_record); 748 } 749 if (ctx->descriptor.blob_size) 750 { 751 signed_size += sizeof(struct blob); 752 // Previous additions are guaranteed not to overflow. 753 if (ctx->descriptor.blob_size > 754 ctx->descriptor.descriptor_area_size - signed_size) 755 { 756 CPRINTS(ctx, "validate_descriptor: invalid blob size (0x%x)", 757 ctx->descriptor.blob_size); 758 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 759 } 760 signed_size += ctx->descriptor.blob_size; 761 } 762 if (signature_struct_size > 763 ctx->descriptor.descriptor_area_size - signed_size) 764 { 765 CPRINTS(ctx, 766 "validate_descriptor: invalid descriptor area size " 767 "(expected = 0x%x, actual = 0x%x)", 768 ctx->descriptor.descriptor_area_size, 769 signed_size + signature_struct_size); 770 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 771 } 772 signature_struct_offset = signed_size; 773 // Omit the actual signature. 774 rv = get_signature_field_offset(signature_scheme, &signature_offset); 775 if (rv != LIBCR51SIGN_SUCCESS) 776 { 777 return rv; 778 } 779 signed_size += signature_offset; 780 781 // Lookup key & validate transition. 782 rv = validate_transition(ctx, intf, offset + signature_struct_offset); 783 784 if (rv != LIBCR51SIGN_SUCCESS) 785 { 786 return rv; 787 } 788 return validate_signature(ctx, intf, offset, signed_size, 789 signature_scheme, offset + signed_size); 790 } 791 792 // Scans the external EEPROM for a magic value at "alignment" boundaries. 793 // 794 //@param device Handle to the external EEPROM. 795 //@param magic 8-byte pattern to search for. 796 //@param start_offset Offset to begin searching at. 797 //@param limit Exclusive address (e.g. EEPROM size). 798 //@param alignment Alignment boundaries (POW2) to search on. 799 //@param header_offset Location to place the new header offset. 800 //@return LIBCR51SIGN_SUCCESS (or non-zero on error). 801 802 int scan_for_magic_8(const struct libcr51sign_ctx* ctx, 803 const struct libcr51sign_intf* intf, uint64_t magic, 804 uint32_t start_offset, uint32_t limit, 805 uint32_t alignment, uint32_t* header_offset) 806 { 807 uint64_t read_data; 808 uint32_t offset; 809 int rv; 810 811 if (limit <= start_offset || limit > ctx->end_offset || 812 limit < sizeof(magic) || !POWER_OF_TWO(alignment)) 813 { 814 return LIBCR51SIGN_ERROR_INVALID_ARGUMENT; 815 } 816 817 if (!intf->read) 818 { 819 CPRINTS(ctx, "scan_for_magic_8: missing intf->read"); 820 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 821 } 822 // Align start_offset to the next valid boundary. 823 start_offset = ((start_offset - 1) & ~(alignment - 1)) + alignment; 824 for (offset = start_offset; offset < limit - sizeof(magic); 825 offset += alignment) 826 { 827 rv = intf->read((void*)ctx, offset, sizeof(read_data), 828 (uint8_t*)&read_data); 829 if (rv != LIBCR51SIGN_SUCCESS) 830 { 831 return rv; 832 } 833 if (read_data == magic) 834 { 835 if (header_offset) 836 { 837 *header_offset = offset; 838 } 839 return LIBCR51SIGN_SUCCESS; 840 } 841 } 842 // Failed to locate magic. 843 return LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC; 844 } 845 846 // Check whether the signature on the image is valid. 847 // Validates the authenticity of an EEPROM image. Scans for & validates the 848 // signature on the image descriptor. If the descriptor validates, hashes 849 // the rest of the image to verify its integrity. 850 // 851 // @param[in] ctx - context which describes the image and holds opaque 852 // private 853 // data for the user of the library 854 // @param[in] intf - function pointers which interface to the current system 855 // and environment 856 // @param[out] image_regions - image_region pointer to an array for the 857 // output 858 // 859 // @return nonzero on error, zero on success 860 861 failure_reason libcr51sign_validate( 862 const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf, 863 struct libcr51sign_validated_regions* image_regions) 864 { 865 uint32_t image_limit = 0; 866 int rv, rv_first_desc = LIBCR51SIGN_SUCCESS; 867 uint32_t descriptor_offset; 868 869 if (!ctx) 870 { 871 CPRINTS(ctx, "MIssing context"); 872 return LIBCR51SIGN_ERROR_INVALID_CONTEXT; 873 } 874 else if (!intf) 875 { 876 CPRINTS(ctx, "Missing interface"); 877 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 878 } 879 880 rv = scan_for_magic_8(ctx, intf, DESCRIPTOR_MAGIC, ctx->start_offset, 881 ctx->end_offset, DESCRIPTOR_ALIGNMENT, 882 &descriptor_offset); 883 while (rv == LIBCR51SIGN_SUCCESS) 884 { 885 CPRINTS(ctx, "validate: potential image descriptor found @%x ", 886 descriptor_offset); 887 // Validation is split into 2 functions to minimize 888 // stack usage. 889 890 rv = validate_descriptor(ctx, intf, descriptor_offset, 891 descriptor_offset - ctx->start_offset, 892 ctx->end_offset - ctx->start_offset); 893 if (rv != LIBCR51SIGN_SUCCESS) 894 { 895 CPRINTS(ctx, "validate: validate_descriptor() failed ec%d ", 896 rv); 897 } 898 899 if (rv == LIBCR51SIGN_SUCCESS) 900 { 901 rv = validate_payload_regions_helper( 902 ctx, intf, descriptor_offset, image_regions); 903 if (rv == LIBCR51SIGN_SUCCESS) 904 { 905 CPRINTS(ctx, "validate: success!"); 906 return rv; 907 } 908 CPRINTS(ctx, 909 "validate: validate_payload_regions() failed ec%d ", 910 rv); 911 } 912 // Store the first desc fail reason if any 913 if (rv != LIBCR51SIGN_SUCCESS && 914 rv_first_desc == LIBCR51SIGN_SUCCESS) 915 rv_first_desc = rv; 916 917 // scan_for_magic_8() will round up to the next aligned boundary. 918 descriptor_offset++; 919 image_limit = ctx->end_offset - ctx->start_offset; 920 rv = scan_for_magic_8(ctx, intf, DESCRIPTOR_MAGIC, 921 descriptor_offset, image_limit, 922 DESCRIPTOR_ALIGNMENT, &descriptor_offset); 923 } 924 CPRINTS(ctx, "validate: failed to validate image ec%d ", rv); 925 // If desc validation failed for some reason then return that reason 926 if (rv_first_desc != LIBCR51SIGN_SUCCESS) 927 return rv_first_desc; 928 else 929 return rv; 930 } 931 932 // @func to returns the libcr51sign error code as a string 933 // @param[in] ec - Error code 934 // @return error code in string format 935 936 const char* libcr51sign_errorcode_to_string(failure_reason ec) 937 { 938 switch (ec) 939 { 940 case LIBCR51SIGN_SUCCESS: 941 return "Success"; 942 case LIBCR51SIGN_ERROR_RUNTIME_FAILURE: 943 return "Runtime Error Failure"; 944 case LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR: 945 return "Unsupported descriptor"; 946 case LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR: 947 return "Invalid descriptor"; 948 case LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY: 949 return "Invalid image family"; 950 case LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED: 951 return "Image type disallowed"; 952 case LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED: 953 return "Dev downgrade disallowed"; 954 case LIBCR51SIGN_ERROR_UNTRUSTED_KEY: 955 return "Untrusted key"; 956 case LIBCR51SIGN_ERROR_INVALID_SIGNATURE: 957 return "Invalid signature"; 958 case LIBCR51SIGN_ERROR_INVALID_HASH: 959 return "Invalid hash"; 960 case LIBCR51SIGN_ERROR_INVALID_HASH_TYPE: 961 return "Invalid hash type"; 962 case LIBCR51SIGN_ERROR_INVALID_ARGUMENT: 963 return "Invalid Argument"; 964 case LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC: 965 return "Failed to locate descriptor"; 966 case LIBCR51SIGN_ERROR_INVALID_CONTEXT: 967 return "Invalid context"; 968 case LIBCR51SIGN_ERROR_INVALID_INTERFACE: 969 return "Invalid interface"; 970 case LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME: 971 return "Invalid signature scheme"; 972 case LIBCR51SIGN_ERROR_INVALID_REGION_INPUT: 973 return "Invalid image region input"; 974 case LIBCR51SIGN_ERROR_INVALID_REGION_SIZE: 975 return "Invalid image region size"; 976 default: 977 return "Unknown error"; 978 } 979 } 980 981 #ifdef __cplusplus 982 } // extern "C" 983 #endif 984