/*
 * Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <libcr51sign/libcr51sign.h>
#include <stdio.h>
#include <string.h>

#ifdef __cplusplus
extern "C"
{
#endif

#ifndef USER_PRINT
#define CPRINTS(ctx, ...) fprintf(stderr, __VA_ARGS__)
#endif

#define MEMBER_SIZE(type, field) sizeof(((type*)0)->field)

// True of x is a power of two
#define POWER_OF_TWO(x) ((x) && !((x) & ((x)-1)))

// Maximum version supported. Major revisions are not backwards compatible.
#define MAX_MAJOR_VERSION 1

// Descriptor alignment on the external EEPROM.
#define DESCRIPTOR_ALIGNMENT (64 * 1024)

// SPS EEPROM sector size is 4KiB, since this is the smallest erasable size.
#define IMAGE_REGION_ALIGNMENT 4096

#define MAX_READ_SIZE 1024

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(t) (sizeof(t) / sizeof(t[0]))
#endif

// Values of SIGNATURE_OFFSET shuold be same for all sig types (2048,3072,4096)
#define SIGNATURE_OFFSET offsetof(struct signature_rsa3072_pkcs15, modulus)

#ifndef BUILD_ASSERT
#define BUILD_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)]))
#endif

typedef enum libcr51sign_validation_failure_reason failure_reason;

// Returns the bytes size of keys used in the given signature_scheme.
// Return error if signature_scheme is invalid.
//
static failure_reason get_key_size(enum signature_scheme signature_scheme,
                                   uint16_t* key_size)
{
    switch (signature_scheme)
    {
        case SIGNATURE_RSA2048_PKCS15:
            *key_size = 256;
            return LIBCR51SIGN_SUCCESS;
        case SIGNATURE_RSA3072_PKCS15:
            *key_size = 384;
            return LIBCR51SIGN_SUCCESS;
        case SIGNATURE_RSA4096_PKCS15:
        case SIGNATURE_RSA4096_PKCS15_SHA512:
            *key_size = 512;
            return LIBCR51SIGN_SUCCESS;
        default:
            return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
    }
}

// Returns the hash_type for a given signature scheme
// Returns error if scheme is invalid.
failure_reason get_hash_type_from_signature(enum signature_scheme scheme,
                                            enum hash_type* type)
{
    switch (scheme)
    {
        case SIGNATURE_RSA2048_PKCS15:
        case SIGNATURE_RSA3072_PKCS15:
        case SIGNATURE_RSA4096_PKCS15:
            *type = HASH_SHA2_256;
            return LIBCR51SIGN_SUCCESS;
        case SIGNATURE_RSA4096_PKCS15_SHA512:
            *type = HASH_SHA2_512;
            return LIBCR51SIGN_SUCCESS;
        default:
            return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
    }
}

// Check if the given hash_type is supported.
// Returns error if hash_type is not supported.
static failure_reason is_hash_type_supported(enum hash_type type)
{
    switch (type)
    {
        case HASH_SHA2_256:
        case HASH_SHA2_512:
            return LIBCR51SIGN_SUCCESS;
        default:
            return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE;
    }
}

// Determines digest size for a given hash_type.
// Returns error if hash_type is not supported.
static failure_reason get_hash_digest_size(enum hash_type type, uint32_t* size)
{
    switch (type)
    {
        case HASH_SHA2_256:
            *size = LIBCR51SIGN_SHA256_DIGEST_SIZE;
            return LIBCR51SIGN_SUCCESS;
        case HASH_SHA2_512:
            *size = LIBCR51SIGN_SHA512_DIGEST_SIZE;
            return LIBCR51SIGN_SUCCESS;
        default:
            return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE;
    }
}

// Determines hash struct size for a given hash_type.
// Returns error if hash_type is not supported.
static failure_reason get_hash_struct_size(enum hash_type type, uint32_t* size)
{
    switch (type)
    {
        case HASH_SHA2_256:
            *size = sizeof(struct hash_sha256);
            return LIBCR51SIGN_SUCCESS;
        case HASH_SHA2_512:
            *size = sizeof(struct hash_sha256);
            return LIBCR51SIGN_SUCCESS;
        default:
            return LIBCR51SIGN_ERROR_INVALID_HASH_TYPE;
    }
}

// Checks that:
//  - The signing key is trusted
//  - The target version is not denylisted
// If validating a staged update, also checks that:
//  - The target image family matches the current image family
//  - The image type transition is legal (i.e. dev -> *|| prod -> prod) or
//    alternatively that the hardware ID is allowlisted
// Assuming the caller has performed following:
// board_get_base_key_index();
// board_get_key_array
// Possible return codes:
// LIBCR51SIGN_SUCCESS = 0,
// LIBCR51SIGN_ERROR_RUNTIME_FAILURE = 1,
// LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR = 3,
// LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY = 4,
// LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED = 5,

static failure_reason validate_transition(const struct libcr51sign_ctx* ctx,
                                          const struct libcr51sign_intf* intf,
                                          uint32_t signature_struct_offset)
{
    BUILD_ASSERT((offsetof(struct signature_rsa2048_pkcs15, modulus) ==
                      SIGNATURE_OFFSET &&
                  offsetof(struct signature_rsa3072_pkcs15, modulus) ==
                      SIGNATURE_OFFSET &&
                  offsetof(struct signature_rsa4096_pkcs15, modulus) ==
                      SIGNATURE_OFFSET));

    // Read up to the modulus.
    enum
    {
        read_len = SIGNATURE_OFFSET
    };
    uint8_t buffer[read_len];
    int rv;
    rv = intf->read(ctx, signature_struct_offset, read_len, buffer);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate_transition: failed to read signature struct\n");
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    if (*(uint32_t*)buffer != SIGNATURE_MAGIC)
    {
        CPRINTS(ctx, "validate_transition: bad signature magic\n");
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }

    if (ctx->descriptor.image_family != ctx->current_image_family &&
        ctx->descriptor.image_family != IMAGE_FAMILY_ALL &&
        ctx->current_image_family != IMAGE_FAMILY_ALL)
    {
        CPRINTS(ctx, "validate_transition: invalid image family\n");
        return LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY;
    }

    if (intf->is_production_mode == NULL)
    {
        CPRINTS(ctx, "validate_transition: missing is_production_mode\n");
        return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
    }
    if (intf->is_production_mode() && (ctx->descriptor.image_type == IMAGE_DEV))
    {
        CPRINTS(ctx, "validate_transition: checking exemption allowlist\n");

        // If function is NULL or if the function call return false, return
        // error
        if (intf->prod_to_dev_downgrade_allowed == NULL ||
            !intf->prod_to_dev_downgrade_allowed())
        {
            CPRINTS(ctx, "validate_transition: illegal image type\n");
            return LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED;
        }
    }
    return LIBCR51SIGN_SUCCESS;
}

// If caller had provided read_and_hash_update call that, otherwise call
// read and then update.

static failure_reason read_and_hash_update(const struct libcr51sign_ctx* ctx,
                                           const struct libcr51sign_intf* intf,
                                           uint32_t offset, uint32_t size)
{
    uint8_t read_buffer[MAX_READ_SIZE];
    int rv;
    int read_size;

    if (intf->read_and_hash_update)
    {
        rv = intf->read_and_hash_update((void*)ctx, offset, size);
    }
    else
    {
        if (!intf->hash_update)
        {
            CPRINTS(ctx, "read_and_hash_update: missing hash_update\n");
            return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
        }
        do
        {
            read_size = size < MAX_READ_SIZE ? size : MAX_READ_SIZE;
            rv = intf->read((void*)ctx, offset, read_size, read_buffer);
            if (rv != LIBCR51SIGN_SUCCESS)
            {
                return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
            }
            rv = intf->hash_update((void*)ctx, read_buffer, read_size);
            if (rv != LIBCR51SIGN_SUCCESS)
            {
                return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
            }
            offset += read_size;
            size -= read_size;
        } while (size > 0);
    }
    return rv;
}

// Validates the image_region array, namely that:
//  - The regions are aligned, contiguous & exhaustive
//  - That the image descriptor resides in a static region
//
// If the array is consistent, proceeds to hash the static regions and
// validates the hash. d_offset is the absolute image descriptor offset

static failure_reason validate_payload_regions(
    const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf,
    uint32_t d_offset, struct libcr51sign_validated_regions* image_regions)
{
    // Allocate buffer to accomodate largest supported hash-type(SHA512)
    uint8_t magic_and_digest[MEMBER_SIZE(struct hash_sha512, hash_magic) +
                             LIBCR51SIGN_SHA512_DIGEST_SIZE];
    uint8_t dcrypto_digest[LIBCR51SIGN_SHA512_DIGEST_SIZE];
    uint32_t byte_count, region_count, image_size, hash_offset, digest_size;
    uint32_t i;
    uint8_t d_region_num = 0;
    int rv;
    const struct image_region* region;

    if (image_regions == NULL)
    {
        CPRINTS(ctx, "Missing image region input\n");
        return LIBCR51SIGN_ERROR_INVALID_REGION_INPUT;
    }

    BUILD_ASSERT((MEMBER_SIZE(struct hash_sha256, hash_magic) ==
                  MEMBER_SIZE(struct hash_sha512, hash_magic)));
    image_size = ctx->descriptor.image_size;
    region_count = ctx->descriptor.region_count;
    hash_offset = d_offset + sizeof(struct image_descriptor) +
                  region_count * sizeof(struct image_region);
    // Read the image_region array.

    if (region_count > ARRAY_SIZE(image_regions->image_regions))
    {
        CPRINTS(ctx, "validate_payload_regions: "
                     "ctx->descriptor.region_count is greater "
                     "than LIBCR51SIGN_MAX_REGION_COUNT\n");
        return LIBCR51SIGN_ERROR_INVALID_REGION_SIZE;
    }

    rv = intf->read(ctx, d_offset + sizeof(struct image_descriptor),
                    region_count * sizeof(struct image_region),
                    (uint8_t*)&image_regions->image_regions);

    image_regions->region_count = region_count;

    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate_payload_regions: failed to read region array\n");
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }

    // Validate that the regions are contiguous & exhaustive.
    for (i = 0, byte_count = 0; i < region_count; i++)
    {
        region = image_regions->image_regions + i;

        CPRINTS(ctx, "validate_payload_regions: region #%d \"%s\" (%x - %x)\n",
                i, (const char*)region->region_name, region->region_offset,
                region->region_offset + region->region_size);
        if ((region->region_offset % IMAGE_REGION_ALIGNMENT) != 0 ||
            (region->region_size % IMAGE_REGION_ALIGNMENT) != 0)
        {
            CPRINTS(ctx, "validate_payload_regions: regions must be sector "
                         "aligned\n");
            return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
        }
        if (region->region_offset != byte_count ||
            region->region_size > image_size - byte_count)
        {
            CPRINTS(ctx, "validate_payload_regions: invalid region array\n");
            return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
        }
        byte_count += region->region_size;
        // The image descriptor must be part of a static region.
        if (d_offset >= region->region_offset && d_offset < byte_count)
        {
            d_region_num = i;
            CPRINTS(ctx,
                    "validate_payload_regions: image descriptor in region %d\n",
                    i);
            // The descriptor can't span regions.
            if (ctx->descriptor.descriptor_area_size > byte_count ||
                !(region->region_attributes & IMAGE_REGION_STATIC))
            {
                CPRINTS(ctx,
                        "validate_payload_regions: descriptor must reside in "
                        "static region\n");
                return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
            }
        }
    }
    if (byte_count != image_size)
    {
        CPRINTS(ctx, "validate_payload_regions: invalid image size\n");
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }

    rv = get_hash_digest_size(ctx->descriptor.hash_type, &digest_size);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        return rv;
    }

    rv = intf->read(ctx, hash_offset,
                    MEMBER_SIZE(struct hash_sha256, hash_magic) + digest_size,
                    magic_and_digest);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx,
                "validate_payload_regions: failed to read hash from flash\n");
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    if (*(uint32_t*)magic_and_digest != HASH_MAGIC)
    {
        CPRINTS(ctx, "validate_payload_regions: bad hash magic\n");
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }
    rv = intf->hash_init(ctx, ctx->descriptor.hash_type);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate_payload_regions: hash_init failed\n");
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    for (i = 0; i < region_count; i++)
    {
        uint32_t hash_start, hash_size;
        region = image_regions->image_regions + i;

        if (!(region->region_attributes & IMAGE_REGION_STATIC))
        {
            continue;
        }
        hash_start = region->region_offset;
        hash_size = region->region_size;

        // Skip the descriptor.
        do
        {
            if (i == d_region_num)
            {
                hash_size = d_offset - hash_start;
            }

            if (!hash_size)
            {
                hash_start += ctx->descriptor.descriptor_area_size;
                hash_size =
                    (region->region_offset + region->region_size - hash_start);
            }
            CPRINTS("validate_payload_regions: hashing %s (%x - %x)\n",
                    (const char*)region->region_name, hash_start,
                    hash_start + hash_size);
            // Read the image_region array.
            rv = read_and_hash_update(ctx, intf, hash_start, hash_size);
            if (rv != LIBCR51SIGN_SUCCESS)
            {
                return rv;
            }
            hash_start += hash_size;
        } while (hash_start != region->region_offset + region->region_size);
    }
    rv = intf->hash_final((void*)ctx, (uint8_t*)dcrypto_digest);

    if (rv != LIBCR51SIGN_SUCCESS)
    {
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }

    if (memcmp(magic_and_digest + MEMBER_SIZE(struct hash_sha256, hash_magic),
               dcrypto_digest, digest_size))
    {
        CPRINTS(ctx, "validate_payload_regions: invalid hash\n");
        return LIBCR51SIGN_ERROR_INVALID_HASH;
    }
    // Image is valid.
    return LIBCR51SIGN_SUCCESS;
}

// Create empty image_regions to pass to validate_payload_regions
// Support validate_payload_regions_helper to remove image_regions as a
// required input.

static failure_reason
    allocate_and_validate_payload_regions(const struct libcr51sign_ctx* ctx,
                                          struct libcr51sign_intf* intf,
                                          uint32_t d_offset)
{
    struct libcr51sign_validated_regions image_regions;
    return validate_payload_regions(ctx, intf, d_offset, &image_regions);
}

// Wrapper around validate_payload_regions to allow nullptr for
// image_regions. Calls allocate_and_validate_payload_regions when
// image_regions is nullptr to create placer holder image_regions.

static failure_reason validate_payload_regions_helper(
    const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf,
    uint32_t d_offset, struct libcr51sign_validated_regions* image_regions)
{
    if (image_regions)
    {
        return validate_payload_regions(ctx, intf, d_offset, image_regions);
    }

    return allocate_and_validate_payload_regions(ctx, intf, d_offset);
}

// Check if the given signature_scheme is supported.
// Returns nonzero on error, zero on success

static failure_reason
    is_signature_scheme_supported(enum signature_scheme scheme)
{
    switch (scheme)
    {
        case SIGNATURE_RSA2048_PKCS15:
        case SIGNATURE_RSA3072_PKCS15:
        case SIGNATURE_RSA4096_PKCS15:
        case SIGNATURE_RSA4096_PKCS15_SHA512:
            return LIBCR51SIGN_SUCCESS;
        default:
            return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
    }
}

// Returns size of signature struct size in |size|
// Returns nonzero on error, zero on success

static failure_reason get_signature_struct_size(enum signature_scheme scheme,
                                                uint32_t* size)
{
    switch (scheme)
    {
        case SIGNATURE_RSA2048_PKCS15:
            *size = sizeof(struct signature_rsa2048_pkcs15);
            return LIBCR51SIGN_SUCCESS;
        case SIGNATURE_RSA3072_PKCS15:
            *size = sizeof(struct signature_rsa3072_pkcs15);
            return LIBCR51SIGN_SUCCESS;
        case SIGNATURE_RSA4096_PKCS15:
        case SIGNATURE_RSA4096_PKCS15_SHA512:
            *size = sizeof(struct signature_rsa4096_pkcs15);
            return LIBCR51SIGN_SUCCESS;
        default:
            return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
    }
}

static failure_reason get_signature_field_offset(enum signature_scheme scheme,
                                                 uint32_t* offset)
{
    switch (scheme)
    {
        case SIGNATURE_RSA2048_PKCS15:
            *offset = offsetof(struct signature_rsa2048_pkcs15, signature);
            return LIBCR51SIGN_SUCCESS;
        case SIGNATURE_RSA3072_PKCS15:
            *offset = offsetof(struct signature_rsa3072_pkcs15, signature);
            return LIBCR51SIGN_SUCCESS;
        case SIGNATURE_RSA4096_PKCS15:
        case SIGNATURE_RSA4096_PKCS15_SHA512:
            *offset = offsetof(struct signature_rsa4096_pkcs15, signature);
            return LIBCR51SIGN_SUCCESS;
        default:
            return LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME;
    }
}

// Validates the signature (of type scheme) read from "device" at
//"raw_signature_offset" with "public_key" over a SHA256/SHA512 digest of
// EEPROM area "data_offset:data_size".

static failure_reason validate_signature(const struct libcr51sign_ctx* ctx,
                                         const struct libcr51sign_intf* intf,
                                         uint32_t data_offset,
                                         uint32_t data_size,
                                         enum signature_scheme scheme,
                                         uint32_t raw_signature_offset)
{
    uint8_t signature[LIBCR51SIGN_MAX_SIGNATURE_SIZE];
    uint16_t key_size;
    uint32_t digest_size;
    uint8_t dcrypto_digest[LIBCR51SIGN_SHA512_DIGEST_SIZE];
    int rv;
    enum hash_type hash_type;

    if (!intf->hash_init)
    {
        CPRINTS(ctx, "validate_signature: missing hash_init\n");
        return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
    }
    rv = get_hash_type_from_signature(scheme, &hash_type);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx,
                "validate_payload_regions: hash_type from signature failed\n");
        return rv;
    }
    rv = intf->hash_init(ctx, hash_type);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate_payload_regions: hash_init failed\n");
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    rv = read_and_hash_update(ctx, intf, data_offset, data_size);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate_signature: hash_update failed\n");
        return rv;
    }
    if (!intf->hash_final)
    {
        CPRINTS(ctx, "validate_signature: missing hash_final\n");
        return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
    }
    rv = intf->hash_final((void*)ctx, dcrypto_digest);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate_signature: hash_final failed (status = %d)\n",
                rv);
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    rv = get_key_size(scheme, &key_size);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        return rv;
    }

    rv = intf->read(ctx, raw_signature_offset, key_size, signature);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx,
                "validate_signature: failed to read signature (status = %d)\n",
                rv);
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    if (!intf->verify_signature)
    {
        CPRINTS(ctx, "validate_signature: missing verify_signature\n");
        return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
    }
    rv = get_hash_digest_size(hash_type, &digest_size);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        return rv;
    }
    rv = intf->verify_signature(ctx, scheme, signature, key_size,
                                dcrypto_digest, digest_size);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate_signature: verification failed (status = %d)\n",
                rv);
        return LIBCR51SIGN_ERROR_INVALID_SIGNATURE;
    }
    CPRINTS(ctx, "validate_signature: verification succeeded\n");
    return LIBCR51SIGN_SUCCESS;
}

// Sanity checks the image descriptor & validates its signature.
// This function does not validate the image_region array or image hash.
//
//@param[in] ctx  context which describes the image and holds opaque private
//                 data for the user of the library
//@param[in] intf  function pointers which interface to the current system
// and environment
//@param offset  Absolute image descriptor flash offset.
//@param relative_offset  Image descriptor offset relative to image start.
//@param max_size Maximum size of the flash space in bytes.
//@param descriptor  Output pointer to an image_descriptor struct

static failure_reason validate_descriptor(const struct libcr51sign_ctx* ctx,
                                          const struct libcr51sign_intf* intf,
                                          uint32_t offset,
                                          uint32_t relative_offset,
                                          uint32_t max_size)
{
    uint32_t max_descriptor_size, signed_size, signature_scheme,
        signature_offset;
    uint32_t signature_struct_offset, signature_struct_size, hash_struct_size;
    int rv;

    max_descriptor_size = max_size - relative_offset;
    if (max_size < relative_offset ||
        max_descriptor_size < sizeof(struct image_descriptor))
    {
        CPRINTS(ctx, "validate_descriptor: invalid arguments\n");
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }

    rv = intf->read(ctx, offset, sizeof(ctx->descriptor),
                    (uint8_t*)&ctx->descriptor);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate_descriptor: failed to read descriptor\n");
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    if (ctx->descriptor.descriptor_magic != DESCRIPTOR_MAGIC ||
        ctx->descriptor.descriptor_offset != relative_offset ||
        ctx->descriptor.region_count == 0 ||
        ctx->descriptor.descriptor_area_size > max_descriptor_size ||
        ctx->descriptor.image_size > max_size)
    {
        CPRINTS(ctx, "validate_descriptor: invalid descriptor\n");
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }
    if (intf->image_size_valid == NULL)
    {
        // Preserve original behavior of requiring exact image_size match if
        // no operator is provided.
        if (ctx->descriptor.image_size != max_size)
        {
            CPRINTS(ctx, "validate_descriptor: invalid image size\n");
            return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
        }
    }
    else if (!intf->image_size_valid(ctx->descriptor.image_size))
    {
        CPRINTS(ctx, "validate_descriptor: invalid image size\n");
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }
    if (ctx->descriptor.image_type != IMAGE_DEV &&
        ctx->descriptor.image_type != IMAGE_PROD &&
        ctx->descriptor.image_type != IMAGE_BREAKOUT &&
        ctx->descriptor.image_type != IMAGE_TEST &&
        ctx->descriptor.image_type != IMAGE_UNSIGNED_INTEGRITY)
    {
        CPRINTS(ctx, "validate_descriptor: bad image type\n");
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }
    // Although the image_descriptor struct supports unauthenticated
    // images, Haven will not allow it.
    // Haven only supports SHA256 + RSA2048/RSA3072_PKCS15 currently.

    signature_scheme = ctx->descriptor.signature_scheme;

    rv = is_signature_scheme_supported(signature_scheme);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        return rv;
    }
    rv = is_hash_type_supported(ctx->descriptor.hash_type);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate_payload_regions: invalid hash type\n");
        return rv;
    }
    if (ctx->descriptor.descriptor_major > MAX_MAJOR_VERSION ||
        ctx->descriptor.region_count > LIBCR51SIGN_MAX_REGION_COUNT)
    {
        CPRINTS(ctx, "validate_descriptor: unsupported descriptor\n");
        return LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR;
    }
    rv = get_signature_struct_size(signature_scheme, &signature_struct_size);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        return rv;
    }

    // Compute the size of the signed portion of the image descriptor.
    signed_size = sizeof(struct image_descriptor) +
                  ctx->descriptor.region_count * sizeof(struct image_region);
    rv = get_hash_struct_size(ctx->descriptor.hash_type, &hash_struct_size);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        return rv;
    }
    signed_size += hash_struct_size;
    if (ctx->descriptor.denylist_size)
    {
        signed_size += sizeof(struct denylist);
        signed_size += ctx->descriptor.denylist_size *
                       sizeof(struct denylist_record);
    }
    if (ctx->descriptor.blob_size)
    {
        signed_size += sizeof(struct blob);
        // Previous additions are guaranteed not to overflow.
        if (ctx->descriptor.blob_size >
            ctx->descriptor.descriptor_area_size - signed_size)
        {
            CPRINTS(ctx, "validate_descriptor: invalid blob size (0x%x)\n",
                    ctx->descriptor.blob_size);
            return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
        }
        signed_size += ctx->descriptor.blob_size;
    }
    if (signature_struct_size >
        ctx->descriptor.descriptor_area_size - signed_size)
    {
        CPRINTS(ctx,
                "validate_descriptor: invalid descriptor area size "
                "(expected = 0x%x, actual = 0x%x)\n",
                ctx->descriptor.descriptor_area_size,
                signed_size + signature_struct_size);
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }
    signature_struct_offset = signed_size;
    // Omit the actual signature.
    rv = get_signature_field_offset(signature_scheme, &signature_offset);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        return rv;
    }
    signed_size += signature_offset;

    // Lookup key & validate transition.
    rv = validate_transition(ctx, intf, offset + signature_struct_offset);

    if (rv != LIBCR51SIGN_SUCCESS)
    {
        return rv;
    }
    return validate_signature(ctx, intf, offset, signed_size, signature_scheme,
                              offset + signed_size);
}

// Scans the external EEPROM for a magic value at "alignment" boundaries.
//
//@param device  Handle to the external EEPROM.
//@param magic   8-byte pattern to search for.
//@param start_offset  Offset to begin searching at.
//@param limit   Exclusive address (e.g. EEPROM size).
//@param alignment   Alignment boundaries (POW2) to search on.
//@param header_offset   Location to place the new header offset.
//@return LIBCR51SIGN_SUCCESS (or non-zero on error).

int scan_for_magic_8(const struct libcr51sign_ctx* ctx,
                     const struct libcr51sign_intf* intf, uint64_t magic,
                     uint32_t start_offset, uint32_t limit, uint32_t alignment,
                     uint32_t* header_offset)
{
    uint64_t read_data;
    uint32_t offset;
    int rv;

    if (limit <= start_offset || limit > ctx->end_offset ||
        limit < sizeof(magic) || !POWER_OF_TWO(alignment))
    {
        return LIBCR51SIGN_ERROR_INVALID_ARGUMENT;
    }

    if (!intf->read)
    {
        CPRINTS(ctx, "scan_for_magic_8: missing intf->read\n");
        return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
    }
    // Align start_offset to the next valid boundary.
    start_offset = ((start_offset - 1) & ~(alignment - 1)) + alignment;
    for (offset = start_offset; offset < limit - sizeof(magic);
         offset += alignment)
    {
        rv = intf->read((void*)ctx, offset, sizeof(read_data),
                        (uint8_t*)&read_data);
        if (rv != LIBCR51SIGN_SUCCESS)
        {
            return rv;
        }
        if (read_data == magic)
        {
            if (header_offset)
            {
                *header_offset = offset;
            }
            return LIBCR51SIGN_SUCCESS;
        }
    }
    // Failed to locate magic.
    return LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC;
}

// Check whether the signature on the image is valid.
// Validates the authenticity of an EEPROM image. Scans for & validates the
// signature on the image descriptor. If the descriptor validates, hashes
// the rest of the image to verify its integrity.
//
// @param[in] ctx - context which describes the image and holds opaque
// private
//                 data for the user of the library
// @param[in] intf - function pointers which interface to the current system
//                  and environment
// @param[out] image_regions - image_region pointer to an array for the
// output
//
// @return nonzero on error, zero on success

failure_reason
    libcr51sign_validate(const struct libcr51sign_ctx* ctx,
                         struct libcr51sign_intf* intf,
                         struct libcr51sign_validated_regions* image_regions)
{
    uint32_t image_limit = 0;
    int rv, rv_first_desc = LIBCR51SIGN_SUCCESS;
    uint32_t descriptor_offset;

    if (!ctx)
    {
        CPRINTS(ctx, "Missing context\n");
        return LIBCR51SIGN_ERROR_INVALID_CONTEXT;
    }
    else if (!intf)
    {
        CPRINTS(ctx, "Missing interface\n");
        return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
    }

    rv = scan_for_magic_8(ctx, intf, DESCRIPTOR_MAGIC, ctx->start_offset,
                          ctx->end_offset, DESCRIPTOR_ALIGNMENT,
                          &descriptor_offset);
    while (rv == LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "validate: potential image descriptor found @%x\n",
                descriptor_offset);
        // Validation is split into 2 functions to minimize
        // stack usage.

        rv = validate_descriptor(ctx, intf, descriptor_offset,
                                 descriptor_offset - ctx->start_offset,
                                 ctx->end_offset - ctx->start_offset);
        if (rv != LIBCR51SIGN_SUCCESS)
        {
            CPRINTS(ctx, "validate: validate_descriptor() failed ec%d\n", rv);
        }

        if (rv == LIBCR51SIGN_SUCCESS)
        {
            rv = validate_payload_regions_helper(ctx, intf, descriptor_offset,
                                                 image_regions);
            if (rv == LIBCR51SIGN_SUCCESS)
            {
                CPRINTS(ctx, "validate: success!\n");
                return rv;
            }
            CPRINTS(ctx, "validate: validate_payload_regions() failed ec%d\n",
                    rv);
        }
        // Store the first desc fail reason if any
        if (rv != LIBCR51SIGN_SUCCESS && rv_first_desc == LIBCR51SIGN_SUCCESS)
            rv_first_desc = rv;

        // scan_for_magic_8() will round up to the next aligned boundary.
        descriptor_offset++;
        image_limit = ctx->end_offset - ctx->start_offset;
        rv = scan_for_magic_8(ctx, intf, DESCRIPTOR_MAGIC, descriptor_offset,
                              image_limit, DESCRIPTOR_ALIGNMENT,
                              &descriptor_offset);
    }
    CPRINTS(ctx, "validate: failed to validate image ec%d\n", rv);
    // If desc validation failed for some reason then return that reason
    if (rv_first_desc != LIBCR51SIGN_SUCCESS)
        return rv_first_desc;
    else
        return rv;
}

// @func to returns the libcr51sign error code as a string
// @param[in] ec - Error code
// @return error code in string format

const char* libcr51sign_errorcode_to_string(failure_reason ec)
{
    switch (ec)
    {
        case LIBCR51SIGN_SUCCESS:
            return "Success";
        case LIBCR51SIGN_ERROR_RUNTIME_FAILURE:
            return "Runtime Error Failure";
        case LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR:
            return "Unsupported descriptor";
        case LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR:
            return "Invalid descriptor";
        case LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY:
            return "Invalid image family";
        case LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED:
            return "Image type disallowed";
        case LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED:
            return "Dev downgrade disallowed";
        case LIBCR51SIGN_ERROR_UNTRUSTED_KEY:
            return "Untrusted key";
        case LIBCR51SIGN_ERROR_INVALID_SIGNATURE:
            return "Invalid signature";
        case LIBCR51SIGN_ERROR_INVALID_HASH:
            return "Invalid hash";
        case LIBCR51SIGN_ERROR_INVALID_HASH_TYPE:
            return "Invalid hash type";
        case LIBCR51SIGN_ERROR_INVALID_ARGUMENT:
            return "Invalid Argument";
        case LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC:
            return "Failed to locate descriptor";
        case LIBCR51SIGN_ERROR_INVALID_CONTEXT:
            return "Invalid context";
        case LIBCR51SIGN_ERROR_INVALID_INTERFACE:
            return "Invalid interface";
        case LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME:
            return "Invalid signature scheme";
        case LIBCR51SIGN_ERROR_INVALID_REGION_INPUT:
            return "Invalid image region input";
        case LIBCR51SIGN_ERROR_INVALID_REGION_SIZE:
            return "Invalid image region size";
        default:
            return "Unknown error";
    }
}

#ifdef __cplusplus
} //  extern "C"
#endif
