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