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) 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 (!intf->prod_to_dev_downgrade_allowed) 223 { 224 return LIBCR51SIGN_SUCCESS; 225 } 226 else if (!intf->prod_to_dev_downgrade_allowed()) 227 { 228 CPRINTS(ctx, "validate_transition: illegal image type"); 229 return LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED; 230 } 231 } 232 return LIBCR51SIGN_SUCCESS; 233 } 234 235 // If caller had provided read_and_hash_update call that, otherwise call 236 // read and then update. 237 238 static failure_reason 239 read_and_hash_update(const struct libcr51sign_ctx* ctx, 240 const struct libcr51sign_intf* intf, 241 uint32_t offset, uint32_t size) 242 { 243 uint8_t read_buffer[MAX_READ_SIZE]; 244 int rv; 245 int read_size; 246 247 if (intf->read_and_hash_update) 248 { 249 rv = intf->read_and_hash_update((void*)ctx, offset, size); 250 } 251 else 252 { 253 if (!intf->hash_update) 254 { 255 CPRINTS(ctx, "read_and_hash_update: missing hash_update"); 256 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 257 } 258 do 259 { 260 read_size = size < MAX_READ_SIZE ? size : MAX_READ_SIZE; 261 rv = intf->read((void*)ctx, offset, read_size, read_buffer); 262 if (rv != LIBCR51SIGN_SUCCESS) 263 { 264 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 265 } 266 rv = intf->hash_update((void*)ctx, read_buffer, read_size); 267 if (rv != LIBCR51SIGN_SUCCESS) 268 { 269 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 270 } 271 offset += read_size; 272 size -= read_size; 273 } while (size > 0); 274 } 275 return rv; 276 } 277 278 // Validates the image_region array, namely that: 279 // - The regions are aligned, contiguous & exhaustive 280 // - That the image descriptor resides in a static region 281 // 282 // If the array is consistent, proceeds to hash the static regions and 283 // validates the hash. d_offset is the absolute image descriptor offset 284 285 static failure_reason validate_payload_regions( 286 const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf, 287 uint32_t d_offset, struct libcr51sign_validated_regions* image_regions) 288 { 289 // Allocate buffer to accomodate largest supported hash-type(SHA512) 290 uint8_t magic_and_digest[MEMBER_SIZE(struct hash_sha512, hash_magic) + 291 LIBCR51SIGN_SHA512_DIGEST_SIZE]; 292 uint8_t dcrypto_digest[LIBCR51SIGN_SHA512_DIGEST_SIZE]; 293 uint32_t byte_count, region_count, image_size, hash_offset, digest_size; 294 uint32_t i; 295 uint8_t d_region_num = 0; 296 int rv; 297 struct image_region const* region; 298 299 if (image_regions == NULL) 300 { 301 CPRINTS(ctx, "Missing image region input"); 302 return LIBCR51SIGN_ERROR_INVALID_REGION_INPUT; 303 } 304 305 BUILD_ASSERT((MEMBER_SIZE(struct hash_sha256, hash_magic) == 306 MEMBER_SIZE(struct hash_sha512, hash_magic))); 307 image_size = ctx->descriptor.image_size; 308 region_count = ctx->descriptor.region_count; 309 hash_offset = d_offset + sizeof(struct image_descriptor) + 310 region_count * sizeof(struct image_region); 311 // Read the image_region array. 312 313 if (region_count > ARRAY_SIZE(image_regions->image_regions)) 314 { 315 CPRINTS(ctx, "validate_payload_regions: " 316 "ctx->descriptor.region_count is greater " 317 "than LIBCR51SIGN_MAX_REGION_COUNT"); 318 return LIBCR51SIGN_ERROR_INVALID_REGION_SIZE; 319 } 320 321 rv = intf->read(ctx, d_offset + sizeof(struct image_descriptor), 322 region_count * sizeof(struct image_region), 323 (uint8_t*)&image_regions->image_regions); 324 325 image_regions->region_count = region_count; 326 327 if (rv != LIBCR51SIGN_SUCCESS) 328 { 329 CPRINTS(ctx, 330 "validate_payload_regions: failed to read region array"); 331 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 332 } 333 334 // Validate that the regions are contiguous & exhaustive. 335 for (i = 0, byte_count = 0; i < region_count; i++) 336 { 337 region = image_regions->image_regions + i; 338 339 CPRINTS(ctx, 340 "validate_payload_regions: region #%d \"%s\" (%x - %x)", i, 341 (const char*)region->region_name, region->region_offset, 342 region->region_offset + region->region_size); 343 if ((region->region_offset % IMAGE_REGION_ALIGNMENT) != 0 || 344 (region->region_size % IMAGE_REGION_ALIGNMENT) != 0) 345 { 346 CPRINTS( 347 ctx, 348 "validate_payload_regions: regions must be sector aligned"); 349 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 350 } 351 if (region->region_offset != byte_count || 352 region->region_size > image_size - byte_count) 353 { 354 CPRINTS(ctx, "validate_payload_regions: invalid region array"); 355 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 356 } 357 byte_count += region->region_size; 358 // The image descriptor must be part of a static region. 359 if (d_offset >= region->region_offset && d_offset < byte_count) 360 { 361 d_region_num = i; 362 CPRINTS( 363 ctx, 364 "validate_payload_regions: image descriptor in region %d", 365 i); 366 // The descriptor can't span regions. 367 if (ctx->descriptor.descriptor_area_size > byte_count || 368 !(region->region_attributes & IMAGE_REGION_STATIC)) 369 { 370 CPRINTS( 371 ctx, 372 "validate_payload_regions: descriptor must reside in " 373 "static region"); 374 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 375 } 376 } 377 } 378 if (byte_count != image_size) 379 { 380 CPRINTS(ctx, "validate_payload_regions: invalid image size"); 381 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 382 } 383 384 rv = get_hash_digest_size(ctx->descriptor.hash_type, &digest_size); 385 if (rv != LIBCR51SIGN_SUCCESS) 386 { 387 return rv; 388 } 389 390 rv = intf->read(ctx, hash_offset, 391 MEMBER_SIZE(struct hash_sha256, hash_magic) + 392 digest_size, 393 magic_and_digest); 394 if (rv != LIBCR51SIGN_SUCCESS) 395 { 396 CPRINTS(ctx, 397 "validate_payload_regions: failed to read hash from flash"); 398 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 399 } 400 if (*(uint32_t*)magic_and_digest != HASH_MAGIC) 401 { 402 CPRINTS(ctx, "validate_payload_regions: bad hash magic"); 403 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 404 } 405 rv = intf->hash_init(ctx, ctx->descriptor.hash_type); 406 if (rv != LIBCR51SIGN_SUCCESS) 407 { 408 CPRINTS(ctx, "validate_payload_regions: hash_init failed"); 409 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 410 } 411 for (i = 0; i < region_count; i++) 412 { 413 uint32_t hash_start, hash_size; 414 region = image_regions->image_regions + i; 415 416 if (!(region->region_attributes & IMAGE_REGION_STATIC)) 417 { 418 continue; 419 } 420 hash_start = region->region_offset; 421 hash_size = region->region_size; 422 423 // Skip the descriptor. 424 do 425 { 426 if (i == d_region_num) 427 { 428 hash_size = d_offset - hash_start; 429 } 430 431 if (!hash_size) 432 { 433 hash_start += ctx->descriptor.descriptor_area_size; 434 hash_size = (region->region_offset + region->region_size - 435 hash_start); 436 } 437 CPRINTS("validate_payload_regions: hashing %s (%x - %x)", 438 (const char*)region->region_name, hash_start, 439 hash_start + hash_size); 440 // Read the image_region array. 441 rv = read_and_hash_update(ctx, intf, hash_start, hash_size); 442 if (rv != LIBCR51SIGN_SUCCESS) 443 { 444 return rv; 445 } 446 hash_start += hash_size; 447 } while (hash_start != region->region_offset + region->region_size); 448 } 449 rv = intf->hash_final((void*)ctx, (uint8_t*)dcrypto_digest); 450 451 if (rv != LIBCR51SIGN_SUCCESS) 452 { 453 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 454 } 455 456 if (memcmp(magic_and_digest + 457 MEMBER_SIZE(struct hash_sha256, hash_magic), 458 dcrypto_digest, digest_size)) 459 { 460 CPRINTS(ctx, "validate_payload_regions: invalid hash"); 461 return LIBCR51SIGN_ERROR_INVALID_HASH; 462 } 463 // Image is valid. 464 return LIBCR51SIGN_SUCCESS; 465 } 466 467 // Create empty image_regions to pass to validate_payload_regions 468 // Support validate_payload_regions_helper to remove image_regions as a 469 // required input. 470 471 static failure_reason 472 allocate_and_validate_payload_regions(const struct libcr51sign_ctx* ctx, 473 struct libcr51sign_intf* intf, 474 uint32_t d_offset) 475 { 476 struct libcr51sign_validated_regions image_regions; 477 return validate_payload_regions(ctx, intf, d_offset, &image_regions); 478 } 479 480 // Wrapper around validate_payload_regions to allow nullptr for 481 // image_regions. Calls allocate_and_validate_payload_regions when 482 // image_regions is nullptr to create placer holder image_regions. 483 484 static failure_reason validate_payload_regions_helper( 485 const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf, 486 uint32_t d_offset, struct libcr51sign_validated_regions* image_regions) 487 { 488 if (image_regions) 489 { 490 return validate_payload_regions(ctx, intf, d_offset, image_regions); 491 } 492 493 return allocate_and_validate_payload_regions(ctx, intf, d_offset); 494 } 495 496 // Check if the given signature_scheme is supported. 497 // Returns nonzero on error, zero on success 498 499 static failure_reason 500 is_signature_scheme_supported(enum signature_scheme scheme) 501 { 502 switch (scheme) 503 { 504 case SIGNATURE_RSA2048_PKCS15: 505 case SIGNATURE_RSA3072_PKCS15: 506 case SIGNATURE_RSA4096_PKCS15: 507 case SIGNATURE_RSA4096_PKCS15_SHA512: 508 return LIBCR51SIGN_SUCCESS; 509 default: 510 return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME; 511 } 512 } 513 514 // Returns size of signature struct size in |size| 515 // Returns nonzero on error, zero on success 516 517 static failure_reason 518 get_signature_struct_size(enum signature_scheme scheme, uint32_t* size) 519 { 520 switch (scheme) 521 { 522 case SIGNATURE_RSA2048_PKCS15: 523 *size = sizeof(struct signature_rsa2048_pkcs15); 524 return LIBCR51SIGN_SUCCESS; 525 case SIGNATURE_RSA3072_PKCS15: 526 *size = sizeof(struct signature_rsa3072_pkcs15); 527 return LIBCR51SIGN_SUCCESS; 528 case SIGNATURE_RSA4096_PKCS15: 529 case SIGNATURE_RSA4096_PKCS15_SHA512: 530 *size = sizeof(struct signature_rsa4096_pkcs15); 531 return LIBCR51SIGN_SUCCESS; 532 default: 533 return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME; 534 } 535 } 536 537 static failure_reason 538 get_signature_field_offset(enum signature_scheme scheme, 539 uint32_t* offset) 540 { 541 switch (scheme) 542 { 543 case SIGNATURE_RSA2048_PKCS15: 544 *offset = offsetof(struct signature_rsa2048_pkcs15, signature); 545 return LIBCR51SIGN_SUCCESS; 546 case SIGNATURE_RSA3072_PKCS15: 547 *offset = offsetof(struct signature_rsa3072_pkcs15, signature); 548 return LIBCR51SIGN_SUCCESS; 549 case SIGNATURE_RSA4096_PKCS15: 550 case SIGNATURE_RSA4096_PKCS15_SHA512: 551 *offset = offsetof(struct signature_rsa4096_pkcs15, signature); 552 return LIBCR51SIGN_SUCCESS; 553 default: 554 return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME; 555 } 556 } 557 558 // Validates the signature (of type scheme) read from "device" at 559 //"raw_signature_offset" with "public_key" over a SHA256/SHA512 digest of 560 // EEPROM area "data_offset:data_size". 561 562 static failure_reason validate_signature( 563 const struct libcr51sign_ctx* ctx, const struct libcr51sign_intf* intf, 564 uint32_t data_offset, uint32_t data_size, enum signature_scheme scheme, 565 uint32_t raw_signature_offset) 566 { 567 uint8_t signature[LIBCR51SIGN_MAX_SIGNATURE_SIZE]; 568 uint16_t key_size; 569 uint32_t digest_size; 570 uint8_t dcrypto_digest[LIBCR51SIGN_SHA512_DIGEST_SIZE]; 571 int rv; 572 enum hash_type hash_type; 573 574 if (!intf->hash_init) 575 { 576 CPRINTS(ctx, "validate_signature: missing hash_init"); 577 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 578 } 579 rv = get_hash_type_from_signature(scheme, &hash_type); 580 if (rv != LIBCR51SIGN_SUCCESS) 581 { 582 CPRINTS( 583 ctx, 584 "validate_payload_regions: hash_type from signature failed"); 585 return rv; 586 } 587 rv = intf->hash_init(ctx, hash_type); 588 if (rv != LIBCR51SIGN_SUCCESS) 589 { 590 CPRINTS(ctx, "validate_payload_regions: hash_init failed"); 591 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 592 } 593 rv = read_and_hash_update(ctx, intf, data_offset, data_size); 594 if (rv != LIBCR51SIGN_SUCCESS) 595 { 596 CPRINTS(ctx, "validate_signature: hash_update failed"); 597 return rv; 598 } 599 if (!intf->hash_final) 600 { 601 CPRINTS(ctx, "validate_signature: missing hash_final"); 602 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 603 } 604 rv = intf->hash_final((void*)ctx, dcrypto_digest); 605 if (rv != LIBCR51SIGN_SUCCESS) 606 { 607 CPRINTS(ctx, "validate_signature: hash_final failed (status = %d)", 608 rv); 609 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 610 } 611 rv = get_key_size(scheme, &key_size); 612 if (rv != LIBCR51SIGN_SUCCESS) 613 { 614 return rv; 615 } 616 617 rv = intf->read(ctx, raw_signature_offset, key_size, signature); 618 if (rv != LIBCR51SIGN_SUCCESS) 619 { 620 CPRINTS( 621 ctx, 622 "validate_signature: failed to read signature (status = %d)", 623 rv); 624 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 625 } 626 if (!intf->verify_signature) 627 { 628 CPRINTS(ctx, "validate_signature: missing verify_signature"); 629 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 630 } 631 rv = get_hash_digest_size(hash_type, &digest_size); 632 if (rv != LIBCR51SIGN_SUCCESS) 633 { 634 return rv; 635 } 636 rv = intf->verify_signature(ctx, scheme, signature, key_size, 637 dcrypto_digest, digest_size); 638 if (rv != LIBCR51SIGN_SUCCESS) 639 { 640 CPRINTS(ctx, 641 "validate_signature: verification failed (status = %d)", 642 rv); 643 return LIBCR51SIGN_ERROR_INVALID_SIGNATURE; 644 } 645 CPRINTS(ctx, "validate_signature: verification succeeded"); 646 return LIBCR51SIGN_SUCCESS; 647 } 648 649 // Sanity checks the image descriptor & validates its signature. 650 // This function does not validate the image_region array or image hash. 651 // 652 //@param[in] ctx context which describes the image and holds opaque private 653 // data for the user of the library 654 //@param[in] intf function pointers which interface to the current system 655 // and environment 656 //@param offset Absolute image descriptor flash offset. 657 //@param relative_offset Image descriptor offset relative to image start. 658 //@param image_size Image size in bytes. 659 //@param descriptor Output pointer to an image_descriptor struct 660 661 static failure_reason validate_descriptor( 662 const struct libcr51sign_ctx* ctx, const struct libcr51sign_intf* intf, 663 uint32_t offset, uint32_t relative_offset, uint32_t image_size) 664 { 665 uint32_t max_descriptor_size, signed_size, signature_scheme, 666 signature_offset; 667 uint32_t signature_struct_offset, signature_struct_size, 668 hash_struct_size; 669 int rv; 670 671 max_descriptor_size = image_size - relative_offset; 672 if (image_size < relative_offset || 673 max_descriptor_size < sizeof(struct image_descriptor)) 674 { 675 CPRINTS(ctx, "validate_descriptor: invalid arguments"); 676 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 677 } 678 679 rv = intf->read(ctx, offset, sizeof(ctx->descriptor), 680 (uint8_t*)&ctx->descriptor); 681 if (rv != LIBCR51SIGN_SUCCESS) 682 { 683 CPRINTS(ctx, "validate_descriptor: failed to read descriptor"); 684 return LIBCR51SIGN_ERROR_RUNTIME_FAILURE; 685 } 686 if (ctx->descriptor.descriptor_magic != DESCRIPTOR_MAGIC || 687 ctx->descriptor.descriptor_offset != relative_offset || 688 ctx->descriptor.region_count == 0 || 689 ctx->descriptor.descriptor_area_size > max_descriptor_size || 690 ctx->descriptor.image_size != image_size) 691 { 692 CPRINTS(ctx, "validate_descriptor: invalid descriptor"); 693 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 694 } 695 if (ctx->descriptor.image_type != IMAGE_DEV && 696 ctx->descriptor.image_type != IMAGE_PROD && 697 ctx->descriptor.image_type != IMAGE_BREAKOUT && 698 ctx->descriptor.image_type != IMAGE_TEST && 699 ctx->descriptor.image_type != IMAGE_UNSIGNED_INTEGRITY) 700 { 701 CPRINTS(ctx, "validate_descriptor: bad image type"); 702 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 703 } 704 // Although the image_descriptor struct supports unauthenticated 705 // images, Haven will not allow it. 706 // Haven only supports SHA256 + RSA2048/RSA3072_PKCS15 currently. 707 708 signature_scheme = ctx->descriptor.signature_scheme; 709 710 rv = is_signature_scheme_supported(signature_scheme); 711 if (rv != LIBCR51SIGN_SUCCESS) 712 { 713 return rv; 714 } 715 rv = is_hash_type_supported(ctx->descriptor.hash_type); 716 if (rv != LIBCR51SIGN_SUCCESS) 717 { 718 CPRINTS(ctx, "validate_payload_regions: invalid hash type"); 719 return rv; 720 } 721 if (ctx->descriptor.descriptor_major > MAX_MAJOR_VERSION || 722 ctx->descriptor.region_count > LIBCR51SIGN_MAX_REGION_COUNT) 723 { 724 CPRINTS(ctx, "validate_descriptor: unsupported descriptor"); 725 return LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR; 726 } 727 rv = 728 get_signature_struct_size(signature_scheme, &signature_struct_size); 729 if (rv != LIBCR51SIGN_SUCCESS) 730 { 731 return rv; 732 } 733 734 // Compute the size of the signed portion of the image descriptor. 735 signed_size = 736 sizeof(struct image_descriptor) + 737 ctx->descriptor.region_count * sizeof(struct image_region); 738 rv = get_hash_struct_size(ctx->descriptor.hash_type, &hash_struct_size); 739 if (rv != LIBCR51SIGN_SUCCESS) 740 { 741 return rv; 742 } 743 signed_size += hash_struct_size; 744 if (ctx->descriptor.denylist_size) 745 { 746 signed_size += sizeof(struct denylist); 747 signed_size += 748 ctx->descriptor.denylist_size * sizeof(struct denylist_record); 749 } 750 if (ctx->descriptor.blob_size) 751 { 752 signed_size += sizeof(struct blob); 753 // Previous additions are guaranteed not to overflow. 754 if (ctx->descriptor.blob_size > 755 ctx->descriptor.descriptor_area_size - signed_size) 756 { 757 CPRINTS(ctx, "validate_descriptor: invalid blob size (0x%x)", 758 ctx->descriptor.blob_size); 759 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 760 } 761 signed_size += ctx->descriptor.blob_size; 762 } 763 if (signature_struct_size > 764 ctx->descriptor.descriptor_area_size - signed_size) 765 { 766 CPRINTS(ctx, 767 "validate_descriptor: invalid descriptor area size " 768 "(expected = 0x%x, actual = 0x%x)", 769 ctx->descriptor.descriptor_area_size, 770 signed_size + signature_struct_size); 771 return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR; 772 } 773 signature_struct_offset = signed_size; 774 // Omit the actual signature. 775 rv = get_signature_field_offset(signature_scheme, &signature_offset); 776 if (rv != LIBCR51SIGN_SUCCESS) 777 { 778 return rv; 779 } 780 signed_size += signature_offset; 781 782 // Lookup key & validate transition. 783 rv = validate_transition(ctx, intf, offset + signature_struct_offset); 784 785 if (rv != LIBCR51SIGN_SUCCESS) 786 { 787 return rv; 788 } 789 return validate_signature(ctx, intf, offset, signed_size, 790 signature_scheme, offset + signed_size); 791 } 792 793 // Scans the external EEPROM for a magic value at "alignment" boundaries. 794 // 795 //@param device Handle to the external EEPROM. 796 //@param magic 8-byte pattern to search for. 797 //@param start_offset Offset to begin searching at. 798 //@param limit Exclusive address (e.g. EEPROM size). 799 //@param alignment Alignment boundaries (POW2) to search on. 800 //@param header_offset Location to place the new header offset. 801 //@return LIBCR51SIGN_SUCCESS (or non-zero on error). 802 803 int scan_for_magic_8(const struct libcr51sign_ctx* ctx, 804 const struct libcr51sign_intf* intf, uint64_t magic, 805 uint32_t start_offset, uint32_t limit, 806 uint32_t alignment, uint32_t* header_offset) 807 { 808 uint64_t read_data; 809 uint32_t offset; 810 int rv; 811 812 if (limit <= start_offset || limit > ctx->end_offset || 813 limit < sizeof(magic) || !POWER_OF_TWO(alignment)) 814 { 815 return LIBCR51SIGN_ERROR_INVALID_ARGUMENT; 816 } 817 818 if (!intf->read) 819 { 820 CPRINTS(ctx, "scan_for_magic_8: missing intf->read"); 821 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 822 } 823 // Align start_offset to the next valid boundary. 824 start_offset = ((start_offset - 1) & ~(alignment - 1)) + alignment; 825 for (offset = start_offset; offset < limit - sizeof(magic); 826 offset += alignment) 827 { 828 rv = intf->read((void*)ctx, offset, sizeof(read_data), 829 (uint8_t*)&read_data); 830 if (rv != LIBCR51SIGN_SUCCESS) 831 { 832 return rv; 833 } 834 if (read_data == magic) 835 { 836 if (header_offset) 837 { 838 *header_offset = offset; 839 } 840 return LIBCR51SIGN_SUCCESS; 841 } 842 } 843 // Failed to locate magic. 844 return LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC; 845 } 846 847 // Check whether the signature on the image is valid. 848 // Validates the authenticity of an EEPROM image. Scans for & validates the 849 // signature on the image descriptor. If the descriptor validates, hashes 850 // the rest of the image to verify its integrity. 851 // 852 // @param[in] ctx - context which describes the image and holds opaque 853 // private 854 // data for the user of the library 855 // @param[in] intf - function pointers which interface to the current system 856 // and environment 857 // @param[out] image_regions - image_region pointer to an array for the 858 // output 859 // 860 // @return nonzero on error, zero on success 861 862 failure_reason libcr51sign_validate( 863 const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf, 864 struct libcr51sign_validated_regions* image_regions) 865 { 866 uint32_t image_limit = 0; 867 int rv, rv_first_desc = LIBCR51SIGN_SUCCESS; 868 uint32_t descriptor_offset; 869 870 if (!ctx) 871 { 872 CPRINTS(ctx, "MIssing context"); 873 return LIBCR51SIGN_ERROR_INVALID_CONTEXT; 874 } 875 else if (!intf) 876 { 877 CPRINTS(ctx, "Missing interface"); 878 return LIBCR51SIGN_ERROR_INVALID_INTERFACE; 879 } 880 881 rv = scan_for_magic_8(ctx, intf, DESCRIPTOR_MAGIC, ctx->start_offset, 882 ctx->end_offset, DESCRIPTOR_ALIGNMENT, 883 &descriptor_offset); 884 while (rv == LIBCR51SIGN_SUCCESS) 885 { 886 CPRINTS(ctx, "validate: potential image descriptor found @%x ", 887 descriptor_offset); 888 // Validation is split into 2 functions to minimize 889 // stack usage. 890 891 rv = validate_descriptor(ctx, intf, descriptor_offset, 892 descriptor_offset - ctx->start_offset, 893 ctx->end_offset - ctx->start_offset); 894 if (rv != LIBCR51SIGN_SUCCESS) 895 { 896 CPRINTS(ctx, "validate: validate_descriptor() failed ec%d ", 897 rv); 898 } 899 900 if (rv == LIBCR51SIGN_SUCCESS) 901 { 902 rv = validate_payload_regions_helper( 903 ctx, intf, descriptor_offset, image_regions); 904 if (rv == LIBCR51SIGN_SUCCESS) 905 { 906 CPRINTS(ctx, "validate: success!"); 907 return rv; 908 } 909 CPRINTS(ctx, 910 "validate: validate_payload_regions() failed ec%d ", 911 rv); 912 } 913 // Store the first desc fail reason if any 914 if (rv != LIBCR51SIGN_SUCCESS && 915 rv_first_desc == LIBCR51SIGN_SUCCESS) 916 rv_first_desc = rv; 917 918 // scan_for_magic_8() will round up to the next aligned boundary. 919 descriptor_offset++; 920 image_limit = ctx->end_offset - ctx->start_offset; 921 rv = scan_for_magic_8(ctx, intf, DESCRIPTOR_MAGIC, 922 descriptor_offset, image_limit, 923 DESCRIPTOR_ALIGNMENT, &descriptor_offset); 924 } 925 CPRINTS(ctx, "validate: failed to validate image ec%d ", rv); 926 // If desc validation failed for some reason then return that reason 927 if (rv_first_desc != LIBCR51SIGN_SUCCESS) 928 return rv_first_desc; 929 else 930 return rv; 931 } 932 933 // @func to returns the libcr51sign error code as a string 934 // @param[in] ec - Error code 935 // @return error code in string format 936 937 const char* libcr51sign_errorcode_to_string(failure_reason ec) 938 { 939 switch (ec) 940 { 941 case LIBCR51SIGN_SUCCESS: 942 return "Success"; 943 case LIBCR51SIGN_ERROR_RUNTIME_FAILURE: 944 return "Runtime Error Failure"; 945 case LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR: 946 return "Unsupported descriptor"; 947 case LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR: 948 return "Invalid descriptor"; 949 case LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY: 950 return "Invalid image family"; 951 case LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED: 952 return "Image type disallowed"; 953 case LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED: 954 return "Dev downgrade disallowed"; 955 case LIBCR51SIGN_ERROR_UNTRUSTED_KEY: 956 return "Untrusted key"; 957 case LIBCR51SIGN_ERROR_INVALID_SIGNATURE: 958 return "Invalid signature"; 959 case LIBCR51SIGN_ERROR_INVALID_HASH: 960 return "Invalid hash"; 961 case LIBCR51SIGN_ERROR_INVALID_HASH_TYPE: 962 return "Invalid hash type"; 963 case LIBCR51SIGN_ERROR_INVALID_ARGUMENT: 964 return "Invalid Argument"; 965 case LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC: 966 return "Failed to locate descriptor"; 967 case LIBCR51SIGN_ERROR_INVALID_CONTEXT: 968 return "Invalid context"; 969 case LIBCR51SIGN_ERROR_INVALID_INTERFACE: 970 return "Invalid interface"; 971 case LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME: 972 return "Invalid signature scheme"; 973 case LIBCR51SIGN_ERROR_INVALID_REGION_INPUT: 974 return "Invalid image region input"; 975 case LIBCR51SIGN_ERROR_INVALID_REGION_SIZE: 976 return "Invalid image region size"; 977 default: 978 return "Unknown error"; 979 } 980 } 981 982 #ifdef __cplusplus 983 } // extern "C" 984 #endif 985