/*
 * 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 <assert.h>
#include <libcr51sign/libcr51sign.h>
#include <stdio.h>
#include <stdlib.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];
        // "modulus" & "signature" will not be indexed.
        struct signature_rsa4096_pkcs15* sig_data = (void*)&buffer;
        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");
            return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
        }
        if (sig_data->signature_magic != SIGNATURE_MAGIC)
        {
            CPRINTS(ctx, "validate_transition: bad signature magic");
            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");
            return LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY;
        }

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

            // 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");
                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");
                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;
        struct image_region const* region;

        if (image_regions == NULL)
        {
            CPRINTS(ctx, "Missing image region input");
            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");
            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");
            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)", 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");
                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");
                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",
                    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");
                    return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
                }
            }
        }
        if (byte_count != image_size)
        {
            CPRINTS(ctx, "validate_payload_regions: invalid image size");
            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");
            return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
        }
        if (*(uint32_t*)magic_and_digest != HASH_MAGIC)
        {
            CPRINTS(ctx, "validate_payload_regions: bad hash magic");
            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");
            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)",
                        (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");
            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");
            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");
            return rv;
        }
        rv = intf->hash_init(ctx, hash_type);
        if (rv != LIBCR51SIGN_SUCCESS)
        {
            CPRINTS(ctx, "validate_payload_regions: hash_init failed");
            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");
            return rv;
        }
        if (!intf->hash_final)
        {
            CPRINTS(ctx, "validate_signature: missing hash_final");
            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)",
                    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)",
                rv);
            return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
        }
        if (!intf->verify_signature)
        {
            CPRINTS(ctx, "validate_signature: missing verify_signature");
            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)",
                    rv);
            return LIBCR51SIGN_ERROR_INVALID_SIGNATURE;
        }
        CPRINTS(ctx, "validate_signature: verification succeeded");
        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 image_size  Image size 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 image_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 = image_size - relative_offset;
        if (image_size < relative_offset ||
            max_descriptor_size < sizeof(struct image_descriptor))
        {
            CPRINTS(ctx, "validate_descriptor: invalid arguments");
            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");
            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 != image_size)
        {
            CPRINTS(ctx, "validate_descriptor: invalid descriptor");
            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");
            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");
            return rv;
        }
        if (ctx->descriptor.descriptor_major > MAX_MAJOR_VERSION ||
            ctx->descriptor.region_count > LIBCR51SIGN_MAX_REGION_COUNT)
        {
            CPRINTS(ctx, "validate_descriptor: unsupported descriptor");
            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)",
                        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)",
                    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");
            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");
            return LIBCR51SIGN_ERROR_INVALID_CONTEXT;
        }
        else if (!intf)
        {
            CPRINTS(ctx, "Missing interface");
            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 ",
                    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 ",
                        rv);
            }

            if (rv == LIBCR51SIGN_SUCCESS)
            {
                rv = validate_payload_regions_helper(
                    ctx, intf, descriptor_offset, image_regions);
                if (rv == LIBCR51SIGN_SUCCESS)
                {
                    CPRINTS(ctx, "validate: success!");
                    return rv;
                }
                CPRINTS(ctx,
                        "validate: validate_payload_regions() failed ec%d ",
                        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 ", 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
