diff --git a/subprojects/libcr51sign/src/libcr51sign.c b/subprojects/libcr51sign/src/libcr51sign.c
new file mode 100644
index 0000000..9bd86b9
--- /dev/null
+++ b/subprojects/libcr51sign/src/libcr51sign.c
@@ -0,0 +1,984 @@
+/*
+ * 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, format, args...) printf(format, ##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)
+        {
+            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 (!intf->prod_to_dev_downgrade_allowed)
+            {
+                return LIBCR51SIGN_SUCCESS;
+            }
+            else if (!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;
+        uint8_t d_region_num = 0;
+        int i, 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 + offsetof(struct image_descriptor, image_regions),
+            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,
+                    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)",
+                        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
