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