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