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)