/*
 * 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 "stddef.h"

#include <assert.h>
#include <libcr51sign/cr51_image_descriptor.h>
#include <libcr51sign/libcr51sign.h>
#include <libcr51sign/libcr51sign_internal.h>
#include <libcr51sign/libcr51sign_mauv.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __cplusplus
extern "C"
{
#endif

// 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

// 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_sha512);
            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, "%s: failed to read signature struct\n", __FUNCTION__);
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    if (*(uint32_t*)buffer != SIGNATURE_MAGIC)
    {
        CPRINTS(ctx, "%s: bad signature magic\n", __FUNCTION__);
        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, "%s: invalid image family\n", __FUNCTION__);
        return LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY;
    }

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

        // 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, "%s: illegal image type\n", __FUNCTION__);
            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, "%s: missing hash_update\n", __FUNCTION__);
            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, "%s: Missing image region input\n", __FUNCTION__);
        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,
                "%s: ctx->descriptor.region_count is greater "
                "than LIBCR51SIGN_MAX_REGION_COUNT\n",
                __FUNCTION__);
        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, "%s: failed to read region array\n", __FUNCTION__);
        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, "%s: region #%d \"%s\" (%x - %x)\n", __FUNCTION__, 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, "%s: regions must be sector aligned\n", __FUNCTION__);
            return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
        }
        if (region->region_offset != byte_count ||
            region->region_size > image_size - byte_count)
        {
            CPRINTS(ctx, "%s: invalid region array\n", __FUNCTION__);
            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, "%s: image descriptor in region %d\n", __FUNCTION__,
                    i);
            // The descriptor can't span regions.
            if ((ctx->descriptor.descriptor_area_size >
                 (byte_count - d_offset)) ||
                !(region->region_attributes & IMAGE_REGION_STATIC))
            {
                CPRINTS(ctx,
                        "%s: descriptor must reside in "
                        "static region\n",
                        __FUNCTION__);
                return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
            }
        }
    }
    if (byte_count != image_size)
    {
        CPRINTS(ctx, "%s: invalid image size\n", __FUNCTION__);
        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, "%s: failed to read hash from flash\n", __FUNCTION__);
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    if (*(uint32_t*)magic_and_digest != HASH_MAGIC)
    {
        CPRINTS(ctx, "%s: bad hash magic\n", __FUNCTION__);
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }
    rv = intf->hash_init(ctx, ctx->descriptor.hash_type);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "%s: hash_init failed\n", __FUNCTION__);
        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(ctx, "%s: hashing %s (%x - %x)\n", __FUNCTION__,
                    (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, "%s: invalid hash\n", __FUNCTION__);
        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, "%s: missing hash_init\n", __FUNCTION__);
        return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
    }
    rv = get_hash_type_from_signature(scheme, &hash_type);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "%s: hash_type from signature failed\n", __FUNCTION__);
        return rv;
    }
    rv = intf->hash_init(ctx, hash_type);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "%s: hash_init failed\n", __FUNCTION__);
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    rv = read_and_hash_update(ctx, intf, data_offset, data_size);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "%s: hash_update failed\n", __FUNCTION__);
        return rv;
    }
    if (!intf->hash_final)
    {
        CPRINTS(ctx, "%s: missing hash_final\n", __FUNCTION__);
        return LIBCR51SIGN_ERROR_INVALID_INTERFACE;
    }
    rv = intf->hash_final((void*)ctx, dcrypto_digest);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "%s: hash_final failed (status = %d)\n", __FUNCTION__, 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, "%s: failed to read signature (status = %d)\n",
                __FUNCTION__, rv);
        return LIBCR51SIGN_ERROR_RUNTIME_FAILURE;
    }
    if (!intf->verify_signature)
    {
        CPRINTS(ctx, "%s: missing verify_signature\n", __FUNCTION__);
        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, "%s: verification failed (status = %d)\n", __FUNCTION__,
                rv);
        return LIBCR51SIGN_ERROR_INVALID_SIGNATURE;
    }
    CPRINTS(ctx, "%s: verification succeeded\n", __FUNCTION__);
    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[out] payload_blob_offset  Absolute offset of BLOB data in image
//                                 descriptor (if BLOB data is present)
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* const restrict payload_blob_offset)
{
    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, "%s: invalid arguments\n", __FUNCTION__);
        return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
    }

    rv = intf->read(ctx, offset, sizeof(ctx->descriptor),
                    (uint8_t*)&ctx->descriptor);
    if (rv != LIBCR51SIGN_SUCCESS)
    {
        CPRINTS(ctx, "%s: failed to read descriptor\n", __FUNCTION__);
        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, "%s: invalid descriptor\n", __FUNCTION__);
        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, "%s: invalid image size\n", __FUNCTION__);
            return LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR;
        }
    }
    else if (!intf->image_size_valid(ctx->descriptor.image_size))
    {
        CPRINTS(ctx, "%s: invalid image size\n", __FUNCTION__);
        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, "%s: bad image type\n", __FUNCTION__);
        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, "%s: invalid hash type\n", __FUNCTION__);
        return rv;
    }
    if (ctx->descriptor.descriptor_major > MAX_MAJOR_VERSION ||
        ctx->descriptor.region_count > LIBCR51SIGN_MAX_REGION_COUNT)
    {
        CPRINTS(ctx, "%s: unsupported descriptor\n", __FUNCTION__);
        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)
    {
        *payload_blob_offset = offset + signed_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) ||
            // Sanity check blob size
            (ctx->descriptor.blob_size < sizeof(struct blob_data)))
        {
            CPRINTS(ctx, "%s: invalid blob size (0x%x)\n", __FUNCTION__,
                    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,
                "%s: invalid descriptor area size "
                "(expected = 0x%x, actual = 0x%x)\n",
                __FUNCTION__, 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, "%s: missing intf->read\n", __FUNCTION__);
        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
//
// TODO(aranika) return valid key
//
// @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)
{
    int rv, rv_first_desc = LIBCR51SIGN_SUCCESS;
    uint32_t descriptor_offset;
    uint32_t payload_blob_offset = 0;

    if (!ctx)
    {
        CPRINTS(ctx, "%s: Missing context\n", __FUNCTION__);
        return LIBCR51SIGN_ERROR_INVALID_CONTEXT;
    }
    else if (!intf)
    {
        CPRINTS(ctx, "%s: Missing interface\n", __FUNCTION__);
        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, "%s: potential image descriptor found @%x\n", __FUNCTION__,
                descriptor_offset);
        // Validation is split into 3 functions to minimize stack usage.

        rv = validate_descriptor(
            ctx, intf, descriptor_offset, descriptor_offset - ctx->start_offset,
            ctx->end_offset - ctx->start_offset, &payload_blob_offset);
        if (rv != LIBCR51SIGN_SUCCESS)
        {
            CPRINTS(ctx, "%s: validate_descriptor() failed ec%d\n",
                    __FUNCTION__, rv);
        }
        else
        {
            rv = validate_payload_regions_helper(ctx, intf, descriptor_offset,
                                                 image_regions);
            if (rv != LIBCR51SIGN_SUCCESS)
            {
                CPRINTS(ctx, "%s: validate_payload_regions() failed ec%d\n",
                        __FUNCTION__, rv);
            }
            else if (ctx->descriptor.image_type == IMAGE_PROD)
            {
                // Lookup and validate payload Image MAUV against Image MAUV
                // stored in the system after checking signature to ensure
                // offsets and sizes are not tampered with. Also, do this after
                // hash calculation for payload regions to ensure that stored
                // Image MAUV is updated (if necessary) as close to the end of
                // payload validation as possible
                rv = validate_payload_image_mauv(ctx, intf, payload_blob_offset,
                                                 ctx->descriptor.blob_size);
                if (rv == LIBCR51SIGN_SUCCESS)
                {
                    CPRINTS(ctx,
                            "%s: Payload Image MAUV validation successful\n",
                            __FUNCTION__);
                    return rv;
                }
                if (rv == LIBCR51SIGN_ERROR_STORING_NEW_IMAGE_MAUV_DATA)
                {
                    CPRINTS(
                        ctx,
                        "%s: Payload validation succeeded, but Image MAUV validation "
                        "failed\n",
                        __FUNCTION__);
                    return LIBCR51SIGN_ERROR_VALID_IMAGE_BUT_NEW_IMAGE_MAUV_DATA_NOT_STORED;
                }
                CPRINTS(ctx, "%s: Payload Image MAUV validation failed\n",
                        __FUNCTION__);
                // In practice, we expect only 1 valid image descriptor in
                // payload. If Image MAUV check fails for the payload after
                // validating the image descriptor, do not try validating other
                // image descriptors
                return rv;
            }
            else
            {
                return 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++;
        rv = scan_for_magic_8(ctx, intf, DESCRIPTOR_MAGIC, descriptor_offset,
                              ctx->end_offset, DESCRIPTOR_ALIGNMENT,
                              &descriptor_offset);
    }
    CPRINTS(ctx, "%s: failed to validate image ec%d\n", __FUNCTION__, 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";
        case LIBCR51SIGN_ERROR_INVALID_IMAGE_MAUV_DATA:
            return "Invalid Image MAUV data";
        case LIBCR51SIGN_ERROR_RETRIEVING_STORED_IMAGE_MAUV_DATA:
            return "Failed to retrieve Image MAUV data stored in system";
        case LIBCR51SIGN_ERROR_STORING_NEW_IMAGE_MAUV_DATA:
            return "Failed to store Image MAUV data from payload image into system";
        case LIBCR51SIGN_ERROR_STORED_IMAGE_MAUV_DOES_NOT_ALLOW_UPDATE_TO_PAYLOAD:
            return "Image MAUV stored in system does not allow payload "
                   "update";
        case LIBCR51SIGN_ERROR_VALID_IMAGE_BUT_NEW_IMAGE_MAUV_DATA_NOT_STORED:
            return "Payload image is valid for update but failed to store new Image "
                   "MAUV in system";
        case LIBCR51SIGN_ERROR_STORED_IMAGE_MAUV_EXPECTS_PAYLOAD_IMAGE_MAUV:
            return "Image MAUV is expected to be present in payload when stored "
                   "Image MAUV is present in the system";
        case LIBCR51SIGN_NO_STORED_MAUV_FOUND:
            return "Client did not find any MAUV data stored in the system";
        default:
            return "Unknown error";
    }
}

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