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