libcr51sign: build: Refactor for subproject use

This refactors the build to make it more suitable for use as a
subproject in other OpenBMC codebases.

Change-Id: I546c993d3f53c1cbe2161e5d8959373d5b12e57f
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/subprojects/libcr51sign/include/libcr51sign/cr51_image_descriptor.h b/subprojects/libcr51sign/include/libcr51sign/cr51_image_descriptor.h
new file mode 100644
index 0000000..0f4bf6f
--- /dev/null
+++ b/subprojects/libcr51sign/include/libcr51sign/cr51_image_descriptor.h
@@ -0,0 +1,420 @@
+/*
+ * 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.
+ */
+#ifndef PLATFORMS_SECURITY_TITAN_CR51_IMAGE_DESCRIPTOR_H_
+#define PLATFORMS_SECURITY_TITAN_CR51_IMAGE_DESCRIPTOR_H_
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+/* _Static_assert is usually not enabled in C++ mode by compilers. */
+#include <assert.h>
+#define _Static_assert static_assert
+#endif
+/* This structure encodes a superset of what we have historically encoded in:
+ *
+ *  Unless explicitly noted all fields are little-endian & offset/size fields
+ *  are in bytes. This struct must reside in a IMAGE_REGION_STATIC region and
+ *  must also reside on a 64K boundary. The size of the hashed/signed portion
+ *  of the descriptor region can be determined solely by parsing the (fixed)
+ *  image_descriptor struct.
+ *
+ *  --------------------------------Flash layout--------------------------------
+ *  |                     struct image_descriptor (signed)                     |
+ *  |                struct image_region[region_count] (signed)                |
+ *  ----------------------------------------------------------------------------
+ *  |               (optional: hash_type) struct hash_* (signed)               |
+ *  ----------------------------------------------------------------------------
+ *  |           (optional: denylist_size) struct denylist (signed)             |
+ *  |             struct denylist_record[denylist_size] (signed)               |
+ *  ----------------------------------------------------------------------------
+ *  |                (optional: blob_size) struct blob (signed)                |
+ *  |                     uint8_t blob[blob_size] (signed)                     |
+ *  ----------------------------------------------------------------------------
+ *  |    (optional: signature_scheme) struct signature_* (partially signed)    |
+ *  ----------------------------------------------------------------------------
+ *  |           (optional) struct key_rotation_records (not signed)            |
+ *  ----------------------------------------------------------------------------
+ */
+
+#define IMAGE_REGION_STATIC (1 << 0)
+#define IMAGE_REGION_COMPRESSED (1 << 1)
+#define IMAGE_REGION_WRITE_PROTECTED (1 << 2)
+#define IMAGE_REGION_READ_PROTECTED (1 << 3)
+#define IMAGE_REGION_PERSISTENT (1 << 4)
+#define IMAGE_REGION_PERSISTENT_RELOCATABLE (1 << 5)
+#define IMAGE_REGION_PERSISTENT_EXPANDABLE (1 << 6)
+#define IMAGE_REGION_OVERRIDE (1 << 7)
+#define IMAGE_REGION_OVERRIDE_ON_TRANSITION (1 << 8)
+#define IMAGE_REGION_MAILBOX (1 << 9)
+#define IMAGE_REGION_SKIP_BOOT_VALIDATION (1 << 10)
+
+/* Little endian on flash. */
+#define DESCRIPTOR_MAGIC 0x5f435344474d495f // "_IMGDSC_"
+#define HASH_MAGIC 0x48534148               // "HASH"
+#define DENYLIST_MAGIC 0x4b434c42           // "BLCK"
+#define BLOB_MAGIC 0x424f4c42               // "BLOB"
+#define SIGNATURE_MAGIC 0x4e474953          // "SIGN"
+#define ROTATION_MAGIC 0x5254524b           // "KRTR"
+
+/* Indicates the type of the image. The type of the image also indicates the
+ * family of key that was used to sign the image.
+ *
+ * Note: if the image type is IMAGE_UNSIGNED_INTEGRITY, the signature_scheme has
+ * to be of type
+ * *_NO_SIGNATURE. Also, all other image types cannot transition to an image of
+ * type IMAGE_UNSIGNED_INTEGRITY.
+ *
+ * The way to verify an image of type IMAGE_UNSIGNED_INTEGRITY differs from
+ * other types of images as it is not signed with an asymmetric key. Instead,
+ * one can verify the integrity by computing the shasum over the descriptor.
+ */
+enum image_type
+{
+    IMAGE_DEV = 0,
+    IMAGE_PROD = 1,
+    IMAGE_BREAKOUT = 2,
+    IMAGE_TEST = 3,
+    IMAGE_UNSIGNED_INTEGRITY = 4
+};
+
+enum hash_type
+{
+    HASH_NONE = 0,
+    HASH_SHA2_224 = 1,
+    HASH_SHA2_256 = 2,
+    HASH_SHA2_384 = 3,
+    HASH_SHA2_512 = 4,
+    HASH_SHA3_224 = 5,
+    HASH_SHA3_256 = 6,
+    HASH_SHA3_384 = 7,
+    HASH_SHA3_512 = 8
+};
+
+/* Note: If the image is of type IMAGE_UNSIGNED_INTEGRITY, the signature_scheme
+ * has to be of type *_ONLY_NO_SIGNATURE.
+ */
+enum signature_scheme
+{
+    SIGNATURE_NONE = 0,
+    SIGNATURE_RSA2048_PKCS15 = 1,
+    SIGNATURE_RSA3072_PKCS15 = 2,
+    SIGNATURE_RSA4096_PKCS15 = 3,
+    SIGNATURE_RSA4096_PKCS15_SHA512 = 4,
+    SHA256_ONLY_NO_SIGNATURE = 5
+};
+
+/* Payload image family. */
+enum image_family
+{
+    IMAGE_FAMILY_ALL = 0,
+    //  values < 256 are reserved for Google-internal use
+};
+
+#define IMAGE_REGION_PROTECTED_ALIGNMENT (4096)
+#define IMAGE_REGION_PROTECTED_PAGE_LENGTH (4096)
+
+struct image_region
+{
+    uint8_t region_name[32]; // null-terminated ASCII string
+    uint32_t region_offset;  // read- and write- protected regions must be
+                             // aligned to IMAGE_REGION_PROTECTED_ALIGNMENT.
+                             // Other regions are also aligned which
+                             // simplifies their implementation.
+    uint32_t region_size;    // read- and write- protected regions must be a
+                             // multiple of IMAGE_REGION_PROTECTED_PAGE_LENGTH.
+    /* Regions will not be persisted across different versions.
+     * This field is intended to flag potential incompatibilities in the
+     * context of data migration (e.g. the ELOG format changed between
+     * two BIOS releases).
+     */
+    uint16_t region_version;
+    /* See IMAGE_REGION_* defines above. */
+    uint16_t region_attributes;
+} __attribute__((__packed__));
+
+/* Main structure (major=1, minor=0). Verification process:
+ * - Hash(image_descriptor + region_count * struct image_region +
+ *        struct hash +
+ *        struct denylist + denylist_size * struct denylist_record +
+ *        struct blob + uint8_t blob[blob_size])
+ * - Verify the signature_* over the hash computed in the previous step
+ * - Compute the rolling hash of the regions marked IMAGE_REGION_STATIC
+ * - The image descriptor is excluded from the hash (descriptor_size bytes)
+ * - Compare the computed hash to the struct hash_*.hash
+ */
+struct image_descriptor
+{
+    uint64_t descriptor_magic; // #define DESCRIPTOR_MAGIC
+    /* Major revisions of this structure are not backwards compatible. */
+    uint8_t descriptor_major;
+    /* Minor revisions of this structure are backwards compatible. */
+    uint8_t descriptor_minor;
+    /* Padding. */
+    uint16_t reserved_0;
+
+    /* This field allows us to mitigate a DOS vector if we end up
+     * scanning the image to discover the image descriptor. The offset
+     * and size are hashed with the rest of the descriptor to prevent
+     * an attacker from copying a valid descriptor to a different
+     * location.
+     *
+     * The offset is relative to the start of the image data.
+     */
+    uint32_t descriptor_offset;
+    /* Includes this struct as well as the auxiliary structs (hash_*,
+     * signature_*, denylist, blob & key_rotation_records). This many bytes
+     * will be skipped when computing the hash of the region this struct
+     * resides in. Tail padding is allowed but must be all 0xff's.
+     */
+    uint32_t descriptor_area_size;
+
+    /*** Image information. ***/
+
+    /* Null-terminated ASCII string. For BIOS this would be the platform
+     * family-genus-version-date (e.g. ixion-hsw-2.8.0-2017.10.03).
+     * Intended for consumption by system software that generates human
+     * readable output (e.g. gsys).
+     */
+    uint8_t image_name[32];
+    /* Image transitions are enforced to be from/to the same family.
+     * 0 is treated as a wildcard (can upgrade to/from any image family).
+     * See image_family enum above.
+     */
+    uint32_t image_family;
+    uint32_t image_major;
+    uint32_t image_minor;
+    uint32_t image_point;
+    uint32_t image_subpoint;
+    /* Seconds since epoch. */
+    uint64_t build_timestamp;
+
+    /* image_type enum { DEV, PROD, BREAKOUT, UNSIGNED_INTEGRITY} */
+    uint8_t image_type;
+    /* 0: no denylist struct, 1: watermark only, >1: watermark + denylist */
+    uint8_t denylist_size;
+    /* hash_type enum { NONE, SHA2_224, SHA2_256, ...} */
+    uint8_t hash_type;
+    /* signature_scheme enum { NONE, RSA2048_PKCS15, ...}
+     * If set, hash_type must be set as well (cannot be NONE).
+     */
+    uint8_t signature_scheme;
+
+    /* struct image_region array size. */
+    uint8_t region_count;
+    uint8_t reserved_1;
+    uint16_t reserved_2;
+    /* The sum of the image_region.region_size fields must add up. */
+    uint32_t image_size;
+    /* Authenticated opaque data exposed to system software. Must be a multiple
+     * of 4 to maintain alignment. Does not include the blob struct magic.
+     */
+    uint32_t blob_size;
+    /* The list is strictly ordered by region_offset.
+     * Must exhaustively describe the image.
+     */
+#ifndef OMIT_VARIABLE_ARRAYS
+    struct image_region image_regions[];
+#endif
+} __attribute__((__packed__));
+
+/* Hash the static regions (IMAGE_REGION_STATIC) excluding this descriptor
+ * structure i.e. skipping image_descriptor.descriptor_size bytes (optional).
+ */
+struct hash_sha256
+{
+    uint32_t hash_magic; // #define HASH_MAGIC
+    uint8_t hash[32];
+} __attribute__((__packed__));
+
+struct hash_sha512
+{
+    uint32_t hash_magic; // #define HASH_MAGIC
+    uint8_t hash[64];
+} __attribute__((__packed__));
+
+struct denylist_record
+{
+    uint32_t image_major;
+    uint32_t image_minor;
+    uint32_t image_point;
+    uint32_t image_subpoint;
+} __attribute__((__packed__));
+
+struct denylist
+{
+    uint32_t denylist_magic; // #define DENYLIST_MAGIC
+    /* Deny list. The first entry is the watermark. All subsequent entries must
+     * be newer than the watermark.
+     */
+#ifndef OMIT_VARIABLE_ARRAYS
+    struct denylist_record denylist_record[];
+#endif
+} __attribute__((__packed__));
+
+struct blob
+{
+    uint32_t blob_magic; // #define BLOB_MAGIC
+#ifndef OMIT_VARIABLE_ARRAYS
+    /* Array of blob_data structures - see blob_data below for details. */
+    uint8_t blobs[];
+#endif
+} __attribute__((__packed__));
+
+/* If blobs[] is non-empty, it is expected to contain one more more instances
+ * of this struct. Each blob_data is followed by the minimum number of padding
+ * bytes (0-3) needed to maintain 4-byte alignment of blob_data structures.
+ * Padding bytes must be 0xFF and must be ignored by readers of blobs[].
+ *
+ * The ordering of the blob_data structures is undefined. Readers of blobs[]
+ * must locate expected blob_data by inspecting blob_type_magic of each
+ * blob_data. Readers are expected to ignore unknown blob_type_magic values,
+ * skipping over them to allow for future types.
+ *
+ * If blob_size is greater than zero but less than sizeof(struct blob_data), the
+ * blobs list is invalid. The blobs list is also invalid if there are multiple
+ * blob_data structures and the last one is truncated due to blob_size being too
+ * small to hold blob_payload_size. Readers must walk the entire length of the
+ * blob_data list to validate the list is well-formed. Any image with an
+ * invalid blobs list has an invalid descriptor and must be treated the same as
+ * an unsigned image.
+ */
+struct blob_data
+{
+    /* BLOB_TYPE_MAGIC_* */
+    uint32_t blob_type_magic;
+    /* Size of the data contained in blob_payload. Need not be a multiple of 4
+     * bytes. Must have sizeof(struct blob_data) + blob_payload_size <=
+     * blob_size.
+     */
+    uint32_t blob_payload_size;
+#ifndef OMIT_VARIABLE_ARRAYS
+    uint8_t blob_payload[];
+#endif
+} __attribute__((__packed__));
+
+/* Signature of the hash of the image_descriptor structure up to and including
+ * this struct but excluding the signature field (optional).
+ */
+struct signature_rsa2048_pkcs15
+{
+    uint32_t signature_magic; // #define SIGNATURE_MAGIC
+    /* Monotonic index of the key used to sign the image (starts at 1). */
+    uint16_t key_index;
+    /* Used to revoke keys, persisted by the enforcer. */
+    uint16_t min_key_index;
+    uint32_t exponent;      // little-endian
+    uint8_t modulus[256];   // big-endian
+    uint8_t signature[256]; // big-endian
+} __attribute__((__packed__));
+
+struct signature_rsa3072_pkcs15
+{
+    uint32_t signature_magic; // #define SIGNATURE_MAGIC
+    /* Monotonic index of the key used to sign the image (starts at 1). */
+    uint16_t key_index;
+    /* Used to revoke keys, persisted by the enforcer. */
+    uint16_t min_key_index;
+    uint32_t exponent;      // little-endian
+    uint8_t modulus[384];   // big-endian
+    uint8_t signature[384]; // big-endian
+} __attribute__((__packed__));
+
+struct signature_rsa4096_pkcs15
+{
+    uint32_t signature_magic; // #define SIGNATURE_MAGIC
+    /* Monotonic index of the key used to sign the image (starts at 1). */
+    uint16_t key_index;
+    /* Used to revoke keys, persisted by the enforcer. */
+    uint16_t min_key_index;
+    uint32_t exponent;      // little-endian
+    uint8_t modulus[512];   // big-endian
+    uint8_t signature[512]; // big-endian
+} __attribute__((__packed__));
+
+struct sha256_only_no_signature
+{
+    uint32_t signature_magic; // #define SIGNATURE_MAGIC
+    uint8_t digest[32];
+} __attribute__((__packed__));
+
+/* Key rotation record (optional).
+ * Enables enforcers to verify images signed with newer (rotated) keys.
+ * The hash function, signature & padding schemes are currently pinned
+ * by image family. This struct is likely to evolve.
+ */
+struct record_rsa2048_pkcs15
+{
+    uint16_t from_index;
+    uint16_t to_index;
+    uint32_t exponent;    // exponent of the new key, little-endian
+    uint8_t modulus[256]; // modulus of the new key, big-endian
+    /* SIGN[K<from_index>](HASH(to_index (LE) | exponent (LE) | modulus (BE)))
+     */
+    uint8_t signature[256]; // big-endian
+} __attribute__((__packed__));
+
+struct record_rsa3072_pkcs15
+{
+    uint16_t from_index;
+    uint16_t to_index;
+    uint32_t exponent;    // exponent of the new key, little-endian
+    uint8_t modulus[384]; // modulus of the new key, big-endian
+    /* SIGN[K<from_index>](HASH(to_index (LE) | exponent (LE) | modulus (BE)))
+     */
+    uint8_t signature[384]; // big-endian
+} __attribute__((__packed__));
+
+struct record_rsa4096_pkcs15
+{
+    uint16_t from_index;
+    uint16_t to_index;
+    uint32_t exponent;    // exponent of the new key, little-endian
+    uint8_t modulus[512]; // modulus of the new key, big-endian
+    /* SIGN[K<from_index>](HASH(to_index (LE) | exponent (LE) | modulus (BE)))
+     */
+    uint8_t signature[512]; // big-endian
+} __attribute__((__packed__));
+
+struct key_rotation_records_rsa2048_pkcs15
+{
+    uint32_t rotation_magic; // #define ROTATION_MAGIC
+    uint16_t record_count;
+    uint16_t reserved_0;
+#ifndef OMIT_VARIABLE_ARRAYS
+    struct record_rsa2048_pkcs15 records[];
+#endif
+} __attribute__((__packed__));
+
+struct key_rotation_records_rsa3072_pkcs15
+{
+    uint32_t rotation_magic; // #define ROTATION_MAGIC
+    uint16_t record_count;
+    uint16_t reserved_0;
+#ifndef OMIT_VARIABLE_ARRAYS
+    struct record_rsa3072_pkcs15 records[];
+#endif
+} __attribute__((__packed__));
+
+struct key_rotation_records_rsa4096_pkcs15
+{
+    uint32_t rotation_magic; // #define ROTATION_MAGIC
+    uint16_t record_count;
+    uint16_t reserved_0;
+#ifndef OMIT_VARIABLE_ARRAYS
+    struct record_rsa3072_pkcs15 records[];
+#endif
+} __attribute__((__packed__));
+#endif // PLATFORMS_SECURITY_TITAN_CR51_IMAGE_DESCRIPTOR_H_
diff --git a/subprojects/libcr51sign/include/libcr51sign/libcr51sign.h b/subprojects/libcr51sign/include/libcr51sign/libcr51sign.h
new file mode 100644
index 0000000..d56fc05
--- /dev/null
+++ b/subprojects/libcr51sign/include/libcr51sign/libcr51sign.h
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+#ifndef PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_H_
+#define PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_H_
+
+#include "cr51_image_descriptor.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define LIBCR51SIGN_SHA256_DIGEST_SIZE 32
+#define LIBCR51SIGN_SHA512_DIGEST_SIZE 64
+
+#define LIBCR51SIGN_MAX_REGION_COUNT 16
+
+// Currently RSA4096 (in bytes).
+#define LIBCR51SIGN_MAX_SIGNATURE_SIZE 512
+
+    // List of common error codes that can be returned
+    enum libcr51sign_validation_failure_reason
+    {
+        // All PayloadRegionState fields are valid & authenticated.
+        LIBCR51SIGN_SUCCESS = 0,
+
+        // Descriptor sanity check failed. None of the following
+        // PayloadRegionState fields are valid/populated.
+        LIBCR51SIGN_ERROR_RUNTIME_FAILURE = 1,
+        LIBCR51SIGN_ERROR_UNSUPPORTED_DESCRIPTOR = 2,
+        LIBCR51SIGN_ERROR_INVALID_DESCRIPTOR = 3,
+
+        // All fields are populated but may not be authentic.
+        LIBCR51SIGN_ERROR_INVALID_IMAGE_FAMILY = 4,
+        LIBCR51SIGN_ERROR_IMAGE_TYPE_DISALLOWED = 5,
+        LIBCR51SIGN_ERROR_DEV_DOWNGRADE_DISALLOWED = 6,
+        LIBCR51SIGN_ERROR_UNTRUSTED_KEY = 7,
+        LIBCR51SIGN_ERROR_INVALID_SIGNATURE = 8,
+        LIBCR51SIGN_ERROR_INVALID_HASH = 9,
+        LIBCR51SIGN_ERROR_INVALID_HASH_TYPE = 10,
+        // Invalid argument
+        LIBCR51SIGN_ERROR_INVALID_ARGUMENT = 11,
+        LIBCR51SIGN_ERROR_FAILED_TO_LOCATE_MAGIC = 12,
+        LIBCR51SIGN_ERROR_INVALID_CONTEXT = 13,
+        LIBCR51SIGN_ERROR_INVALID_INTERFACE = 14,
+        LIBCR51SIGN_ERROR_INVALID_SIG_SCHEME = 15,
+        LIBCR51SIGN_ERROR_MAX = 16,
+        // Invalid image region
+        LIBCR51SIGN_ERROR_INVALID_REGION_INPUT = 17,
+        LIBCR51SIGN_ERROR_INVALID_REGION_SIZE = 18,
+    };
+
+    struct libcr51sign_ctx
+    {
+        // Absolute image start offset
+        uint32_t start_offset;
+        // Absolute image end offset
+        uint32_t end_offset;
+        size_t block_size;
+        enum image_family current_image_family;
+        enum image_type current_image_type;
+        // keyring_len - number of keys in @a keyring
+        int keyring_len;
+        // valid_key - index of valid key on success
+        size_t* valid_key;
+        // keyring - array of pointers to public keys
+        const void* keyring;
+        void* priv;
+        struct image_descriptor descriptor;
+    };
+
+    struct libcr51sign_intf
+    {
+        // @func read read data from the image into a buffer
+        //
+        // @param[in] ctx - context struct
+        // @param[in] offset - bytes to seek into the image before reading
+        // @param[in] count - number of bytes to read
+        // @param[out] buf - pointer to buffer where result will be written
+        //
+        // @return nonzero on error, zero on success
+
+        int (*read)(const void*, uint32_t, uint32_t, uint8_t*);
+
+        // @func hash_init get ready to compute a hash
+        //
+        // @param[in] ctx - context struct
+        // @param[in] hash_type - type of hash function to use
+        //
+        // @return nonzero on error, zero on success
+
+        int (*hash_init)(const void*, enum hash_type);
+
+        // @func hash_update add data to the hash
+        //
+        // @param[in] ctx - context struct
+        // @param[in] buf - data to add to hash
+        // @param[in] count - number of bytes of data to add
+        // @param[in] hash_type - type of hash function to use
+        //
+        // @return nonzero on error, zero on success
+
+        int (*hash_update)(void*, const uint8_t*, size_t);
+
+        // Note this is a combination of an spi_nor_read() with
+        // spi_transaction() It is the responsibility of the caller to
+        // synchronize with other potential SPI clients / transactions.
+        // Collapsing the SPI stack results in a 2x throughput improvement (~20s
+        // -> ~10s to verify an Indus image with SHA256 HW acceleration).
+        //
+        // The caller is responsible for calling DCRYPTO_init()/HASH_final().
+
+        int (*read_and_hash_update)(void* ctx, uint32_t offset, uint32_t size);
+
+        // @func hash_final finish hash calculation
+        //
+        // @param[in] ctx - context struct
+        // @param[out] hash - buffer to write hash to
+        // @param[in] hash_type - type of hash function to use
+        //
+        // @return nonzero on error, zero on success
+
+        int (*hash_final)(void*, uint8_t*);
+
+        // @func verify check that the signature is valid for given hashed data
+        //
+        // @param[in] ctx - context struct
+        // @param[in] scheme - type of signature, hash, etc.
+        // @param[in] sig - signature blob
+        // @param[in] sig_len - length of signature in bytes
+        // @param[in] data - pre-hashed data to verify
+        // @param[in] data_len - length of hashed data in bytes
+        //
+        // @return nonzero on error, zero on success
+
+        int (*verify_signature)(const void*, enum signature_scheme,
+                                const uint8_t*, size_t, const uint8_t*, size_t);
+
+        // @func verify check that if the prod to dev downgrade/ hardware
+        // allowlist is allowed
+        // @return  true: if allowed
+        //          false: if not allowed
+        // BMC would return always false or pass a NULL pointer
+        // If NULL, treated as if the function always returns false.
+
+        bool (*prod_to_dev_downgrade_allowed)();
+
+        // @func returns true if the current firmware is running in production
+        // mode.
+        // @return true: if in production mode
+        //         false: if in any non-production mode
+
+        bool (*is_production_mode)();
+    };
+
+    struct libcr51sign_validated_regions
+    {
+        uint32_t region_count;
+        struct image_region image_regions[LIBCR51SIGN_MAX_REGION_COUNT];
+    };
+
+    // 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
+
+    enum libcr51sign_validation_failure_reason libcr51sign_validate(
+        const struct libcr51sign_ctx* ctx, struct libcr51sign_intf* intf,
+        struct libcr51sign_validated_regions* image_regions);
+
+    // Function to convert error code to string format
+    // @param[in] ec - error code
+    // @return error code in string format
+
+    const char* libcr51sign_errorcode_to_string(
+        enum libcr51sign_validation_failure_reason ec);
+
+    // Returns the hash_type for a given signature scheme
+    // @param[in] scheme - signature scheme
+    // @param[out] type - hash_type supported by given signature_scheme
+    //
+    // @return nonzero on error, zero on success
+
+    enum libcr51sign_validation_failure_reason
+        get_hash_type_from_signature(enum signature_scheme scheme,
+                                     enum hash_type* type);
+
+#ifdef __cplusplus
+} //  extern "C"
+#endif
+
+#endif // PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_H_
diff --git a/subprojects/libcr51sign/include/libcr51sign/libcr51sign_support.h b/subprojects/libcr51sign/include/libcr51sign/libcr51sign_support.h
new file mode 100644
index 0000000..87b4401
--- /dev/null
+++ b/subprojects/libcr51sign/include/libcr51sign/libcr51sign_support.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+#ifndef PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_SUPPORT_H_
+#define PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_SUPPORT_H_
+
+#include "libcr51sign.h"
+
+#include <openssl/sha.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    struct hash_ctx
+    {
+        enum hash_type hash_type;
+        union
+        {
+            SHA256_CTX sha256_ctx;
+            SHA512_CTX sha512_ctx;
+        };
+    };
+
+    // @func hash_init get ready to compute a hash
+    //
+    // @param[in] ctx - context struct
+    // @param[in] hash_type - type of hash function to use
+    //
+    // @return nonzero on error, zero on success
+
+    int hash_init(const void* ctx, enum hash_type type);
+
+    // @func hash_update add data to the hash
+    //
+    // @param[in] ctx - context struct
+    // @param[in] buf - data to add to hash
+    // @param[in] count - number of bytes of data to add
+    //
+    // @return nonzero on error, zero on success
+
+    int hash_update(void* ctx, const uint8_t* data, size_t size);
+
+    // @func hash_final finish hash calculation
+    //
+    // @param[in] ctx - context struct
+    // @param[out] hash - buffer to write hash to (guaranteed to be big enough)
+    //
+    // @return nonzero on error, zero on success
+
+    int hash_final(void* ctx, uint8_t* hash);
+
+    // @func verify check that the signature is valid for given hashed data
+    //
+    // @param[in] ctx - context struct
+    // @param[in] scheme - type of signature, hash, etc.
+    // @param[in] sig - signature blob
+    // @param[in] sig_len - length of signature in bytes
+    // @param[in] data - pre-hashed data to verify
+    // @param[in] data_len - length of hashed data in bytes
+    //
+    // @return nonzero on error, zero on success
+
+    int verify_signature(const void* ctx, enum signature_scheme sig_scheme,
+                         const uint8_t* sig, size_t sig_len,
+                         const uint8_t* data, size_t data_len);
+
+#ifdef __cplusplus
+} //  extern "C"
+#endif
+#endif // PLATFORMS_HAVEN_LIBCR51SIGN_LIBCR51SIGN_SUPPORT_H_
diff --git a/subprojects/libcr51sign/include/meson.build b/subprojects/libcr51sign/include/meson.build
new file mode 100644
index 0000000..fc9ec3a
--- /dev/null
+++ b/subprojects/libcr51sign/include/meson.build
@@ -0,0 +1,20 @@
+# 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.
+
+libcr51sign_includes = include_directories('.')
+
+install_subdir(
+  'libcr51sign',
+  install_dir: get_option('includedir'),
+  strip_directory: false)