blob: 4c0cbc2b5181612f425799d758e42bb1199aa7a9 [file] [log] [blame]
/*
* Copyright 2024 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 __PRIVATE_CR51_INCLUDE_CR51_HOST_COMMANDS_H
#define __PRIVATE_CR51_INCLUDE_CR51_HOST_COMMANDS_H
/* Adding endianness */
#include <stdint.h>
#include <boost/endian/arithmetic.hpp>
/* Adding endianness */
using boost::endian::little_int32_t;
using boost::endian::little_uint16_t;
using boost::endian::little_uint32_t;
using boost::endian::little_uint64_t;
using boost::endian::little_uint8_t;
/* Get version number */
#define EC_CMD_GET_VERSION 0x0002
#define EC_CMD_CONSOLE_REQUEST 0x0097
#define EC_CMD_CONSOLE_READ 0x0098
#define EC_CMD_BOARD_SPECIFIC_BASE 0x3E00
#define EC_PRV_CMD_HOTH_CHANNEL_STATUS 0x0037
#define EC_CMD_HOTH_CHANNEL_READ 0x0036
enum ec_console_read_subcmd {
CONSOLE_READ_NEXT = 0,
CONSOLE_READ_RECENT = 1,
};
enum ec_current_image { EC_IMAGE_UNKNOWN = 0, EC_IMAGE_RO, EC_IMAGE_RW };
/**
* struct ec_response_get_version - Response to the get version command.
* @version_string_ro: Null-terminated RO firmware version string.
* @version_string_rw: Null-terminated RW firmware version string.
* @reserved: Unused bytes; was previously RW-B firmware version string.
* @current_image: One of ec_current_image.
*/
struct ec_response_get_version {
char version_string_ro[32];
char version_string_rw[32];
char reserved[32];
little_uint32_t current_image;
};
#define EC_PRV_CMD_HOTH_CRYPTA 0x0003
/* Hardware Category */
typedef enum crypta_hardware_category {
CRYPTA_HW_CAT_HOTH_B1 = 0,
CRYPTA_HW_CAT_HOTH_B2 = 1,
CRYPTA_HW_CAT_HOTH_D2 = 4
} CryptaHardwareCategory;
/* An identifier for a hoth chip */
typedef struct _crypta_command_info_hoth_id {
little_uint64_t hardware_id;
little_uint16_t hardware_category;
uint8_t reserved_0[2];
} crypta_command_info_hoth_id;
/* An identifier for a hoth chip running a specific major version of Crypta
* firmware.
*/
typedef struct _crypta_command_info_crypta_id {
crypta_command_info_hoth_id hoth_id;
little_uint32_t bootloader_tag;
little_uint32_t fw_epoch;
little_uint16_t fw_major_version;
uint8_t reserved_0[2];
} crypta_command_info_crypta_id;
/* Complete versioning information about the Crypta execution environment. Note
* that the values in this message are expected to continue representing the
* Crypta environment as long as the version of firmware currently running on
* the chip does not change.
*/
typedef struct _crypta_command_info {
crypta_command_info_crypta_id crypta_id;
// Crypta ensures that newer versions of firmware can access secrets wrapped
// by older versions, but not vice versa.
little_uint16_t fw_minor_version;
// This is the version number that the firmware will place in
// `signature_version` fields for signed headers. It corresponds to constants
// found in //security/crypta/firmware/crypta_constants.h.
uint8_t signature_version;
// This is the version number that the firmware will place in
// `wrapper_version` fields for wrapped keys. It corresponds to constants
// found in //security/crypta/firmware/crypta_constants.h.
uint8_t wrapper_version;
// These fields represent the size in bytes of the chip's SPI mailbox.
// |inbound_mailbox_size| represents the amount of bytes reserved for messages
// delivered to Crypta, while |outbound_mailbox_size| represents the amount of
// bytes reserved for the "staging area" where replies are assembled and
// dispatched from. Commands that exchange variable-length request/response
// parameters with Crypta should abide by these limits.
little_uint16_t inbound_mailbox_size;
little_uint16_t outbound_mailbox_size;
} crypta_command_info;
/* The header to be used for serialized Crypta command requests. The header
* should be followed by a number of crypta_parameter structures specified
* by `param_count`.
*/
struct ec_request_crypta_info {
// The major Crypta command for this request. Must be a value from the
// crypta_major_command enum.
uint8_t major_command;
// The minor command for this request. The meaning of this field is
// command specific and its value will depend on the value of
// `major_command`.
uint8_t minor_command;
// The number of parameters that follow the header in this request.
little_uint16_t param_count;
};
struct ec_response_crypta_info {
little_uint32_t crypta_response_header;
little_uint32_t crypta_parameter;
crypta_command_info crypta_info;
};
#define EC_PRV_CMD_HOTH_PAYLOAD_UPDATE 0x0005
/* PAYLOAD_UPDATE_INITIATE initiates erasure of the staging area. This enables
* clients to skip over erased regions of an image when writing payload data to
* the staging area. offset/len are ignored.
* An update can sometimes be completed without first initiating a reset if the
* EEPROM delta is known to be in an erased state.
*
* PAYLOAD_UPDATE_CONTINUE packets are allowed to be out-of-order.
*
* PAYLOAD_UPDATE_FINALIZE initiates verification.
*
* PAYLOAD_UPDATE_AUX_DATA is intended to stream auxiliary authentication data
* that might be required by some board-specific payload authentication schemes.
*
* PAYLOAD_UPDATE_VERIFY will return the verification status without activating
* the staging area.
*
* PAYLOAD_UPDATE_ACTIVATE, half must be authenticated to succeed. If one-time
* activation is requested, will revert on a subsequent Hoth reset unless a
* persistent activate request is initiated and/or the staging area is modified.
* Hoth must reset for the activation to take effect.
*
* PAYLOAD_UPDATE_READ will return data from the staging area. Read requests
* must be smaller than the mailbox size.
*
* PAYLOAD_UPDATE_GET_STATUS returns the active, "next" (to be exposed on the
* next Hoth reset) & persistent (half that would get exposed were Hoth
* to reset twice in a row) halves & their verification state.
*
* PAYLOAD_UPDATE_ERASE is intended to provide the flexibility to break up
* the PAYLOAD_UPDATE_INITIATE step to avoid blocking the SPI bus for too
* long if need be (relevant for use cases that leverage the watchdog offload).
*/
#define PAYLOAD_UPDATE_INITIATE 0
#define PAYLOAD_UPDATE_CONTINUE 1
#define PAYLOAD_UPDATE_FINALIZE 2
#define PAYLOAD_UPDATE_AUX_DATA 3
#define PAYLOAD_UPDATE_VERIFY 4
#define PAYLOAD_UPDATE_ACTIVATE 5
#define PAYLOAD_UPDATE_READ 6
#define PAYLOAD_UPDATE_GET_STATUS 7
#define PAYLOAD_UPDATE_ERASE 8
#define PAYLOAD_UPDATE_VERIFY_CHUNK 9
#define PAYLOAD_UPDATE_CONFIRM 10
#define PAYLOAD_UPDATE_VERIFY_DESCRIPTOR 11
/* Adding endianness */
struct payload_update_packet {
little_uint32_t offset; /* image offset */
little_uint32_t len; /* packet length excluding this header */
little_uint8_t type; /* One of PAYLOAD_UPDATE_* */
/* payload data immediately follows */
};
/* PAYLOAD_UPDATE_ACTIVATE request. */
struct payload_update_activate {
uint8_t half; /* 0, 1 */
uint8_t make_persistent; /* 0, 1 */
} __attribute__((packed));
/* PAYLOAD_UPDATE_GET_STATUS response. */
struct payload_update_status {
uint8_t a_valid; /* 0 = no, 1 = unknown, 2 = yes */
uint8_t b_valid; /* 0 = no, 1 = unknown, 2 = yes */
uint8_t active_half; /* 0, 1 */
uint8_t next_half; /* 0, 1 */
uint8_t persistent_half; /* 0, 1 */
} __attribute__((packed));
enum class payload_update_confirm_option : uint8_t {
Enable = 0, // Enable confirmed update for the updated payload
Enable_with_timeout = 1, // Enable and set a timeout value
Disable = 2, // Disable any timeout value that has been set
Confirm = 3, // Confirm that the updated payload is working fine
Get_timeout_values = 4, // Except for CONFIRM, all the other options will
}; // return timeout values as well.
struct payload_update_confirm {
payload_update_confirm_option option;
uint8_t padding[3];
// The desired timeout value in second only when option is ENABLE_WITH_TIMEOUT
little_uint32_t timeout_value;
// This value has no meaning to hoth. It will be stored in hoth as the
// confirmation value and re-exported via the GET_STATISTICS command.
// Recommended to use the host's current time so monitoring can determine
// when a payload was last confirmed. Only when option is CONFIRM
little_uint64_t confirmation_cookie;
};
// Return timeout values. Note that except for CONFIRM, all the other command
// options will receive these values from the response, so that the caller knows
// exactly what values are set in Hoth firmware and what timeout will be used
// after reboot
struct payload_update_confirm_timeout_values {
little_uint32_t min; // MIN timeout allowed
little_uint32_t max; // MAX timeout allowed
little_uint32_t default_val; // The default value to use when option = ENABLE
little_uint32_t current; // What value has been set. If 0, no value is set
};
struct payload_update_confirm_response {
struct payload_update_confirm_timeout_values timeout_values;
};
struct boot_timing_data {
little_uint32_t start_us;
little_uint32_t end_us;
};
#define EC_PRV_CMD_HOTH_PAYLOAD_STATUS 0x0006
#define PAYLOAD_STATUS_RESPONSE_VERSION 1
enum payload_validation_state {
PAYLOAD_IMAGE_INVALID = 0,
PAYLOAD_IMAGE_UNVERIFIED = 1,
PAYLOAD_IMAGE_VALID = 2,
PAYLOAD_DESCRIPTOR_VALID = 3,
};
struct payload_region_state {
uint8_t validation_state; /* enum payload_validation_state */
uint8_t failure_reason; /* enum payload_validation_failure_reason */
uint8_t reserved_0;
uint8_t image_type; /* enum image_type (dev, prod, breakout) */
little_uint16_t key_index;
little_uint16_t reserved_1;
little_uint32_t image_family; /* handy to disambiguate during enumeration */
little_uint32_t version_major;
little_uint32_t version_minor;
little_uint32_t version_point;
little_uint32_t version_subpoint;
little_uint32_t
descriptor_offset; /* can be used to pull the image hash/signature */
};
struct payload_status_response_header {
uint8_t version; /* command version = 1 */
uint8_t lockdown_state;
uint8_t active_half; /* 0 or 1 (A or B) */
uint8_t region_count; /* payload_region_state array size */
};
/* Hoth only supports 1 or 2 regions. */
#define PAYLOAD_STATUS_MAX_REGION_STATES 2
struct payload_status_response {
struct payload_status_response_header header;
struct payload_region_state
states[PAYLOAD_STATUS_MAX_REGION_STATES]; /* A or (A then B) */
};
/* Get various statistics from the Hoth */
#define EC_PRV_CMD_HOTH_GET_STATISTICS 0x000F
struct ec_response_statistics {
/*
* The offsets in this structure are fixed, and documented.
* Do not change the order of these fields, only add new
* fields in the reserved area.
*/
/*
* Number of 32 bit words returned from this command.
* That's not including the reserved fields.
* Offset: 0
*/
little_uint32_t valid_words;
/*
* The set of flags which describe the Hoth's most recent reset.
* Offset: 1 (32 bit words)
*/
little_uint32_t hoth_reset_flags;
/*
* Number of microseconds since the last Hoth boot.
* Offset: 2
*/
little_uint64_t time_since_hoth_boot_us;
/*
* The current temperature of the Hoth chip. This is just the value
* in the SUM8 register, no conversion to celsius or fahrenheit is applied.
* The value returned is a 9.3 bit fixed point binary number. Anything
* greater than the max value of a 9.3 bit fixed point binary number is
* considered invalid. Default invalid return value is 0xFFFFFFFF.
* Offset: 4
*/
little_uint32_t hoth_temperature;
/*
* The current INFO strike count in the RO region.
* Offset: 5
*/
little_uint32_t ro_info_strikes;
/*
* The current INFO strike count in the RW region.
* Offset: 6
*/
little_uint32_t rw_info_strikes;
/*
* For testing, a scratch value to say something
* Debug only, should be zero in release builds
* Offset: 7
*/
little_uint32_t scratch_value;
/*
* Reason code for last payload update failure.
*/
little_uint16_t payload_update_failure_reason;
/*
* Reason for last firmware update failure.
*/
little_uint16_t firmware_update_failure_reason;
/*
* Minor version of the last firmware update that failed.
*/
little_uint32_t failed_firmware_minor_version;
/*
* Time in microseconds of various things we want to measure during
* bootup. All times are in microseconds.
* total - Time from reset to HVNGOOD.
* update - Time spent in the self update routine. Since a proper self update
* involves a reset, this time is always expected to be low.
* mirroring - Time spent mirroing the self-update. This time is a reasonable
* proxy for the total self update time.
* payload_validation - Time spent validating the payload, copying mutable
* regions and/or dealing with failsafe fallback.
*/
struct boot_timing_data boot_timing_total;
struct boot_timing_data boot_timing_firmware_update;
struct boot_timing_data boot_timing_firmware_mirroring;
struct boot_timing_data boot_timing_payload_validation;
/*
* Confirmation cookie for Payload Update
*/
little_uint32_t payload_update_confirmation_cookie_failure_reason;
little_uint64_t payload_update_confirmation_cookie;
/*
* Error code returned by a bootloader update failure.
*/
little_uint32_t bootloader_update_error;
/*
* Future expansion.
*/
little_uint32_t reserved[42];
};
/* Get the hardware information from Hoth chip. */
#define EC_PRV_CMD_HOTH_CHIP_INFO 0x0010
struct ec_response_chip_info {
little_uint64_t hardware_identity;
little_uint16_t hardware_category;
little_uint16_t reserved0;
little_uint32_t info_variant;
};
/* Get the panic record persisted to gNVRAM
*/
#define EC_PRV_CMD_HOTH_PERSISTENT_PANIC_INFO 0x0014
#define HOTH_PERSISTENT_PANIC_INFO_CHUNK_SIZE 512
enum persistent_panic_op {
PERSISTENT_PANIC_INFO_GET = 0,
PERSISTENT_PANIC_INFO_ERASE = 1,
};
struct ec_request_persistent_panic_info {
/* The operation is one of persistent_panic_op. */
little_uint32_t operation;
/* When the operation is PERSISTENT_PANIC_INFO_GET, the index
* is which 512-byte chunk of the response to retrieve.
*/
little_uint32_t index;
};
struct persistent_panic_rw_version {
little_uint32_t epoch;
little_uint32_t major;
little_uint32_t minor;
};
struct ec_response_persistent_panic_info {
uint8_t panic_record[144];
/* The uart_head is the next location in the buffer that console output
* would write to.
*/
little_uint32_t uart_head;
/* The uart_tail is the next location the uart dma transmitter
* would had read from (had the firmware not crashed).
*/
little_uint32_t uart_tail;
/* The uart_buf contains the last 4096 characters written to the uart
* output. The oldest character written is pointed to by head and the
* newest character written is pointed to by head-1.
*/
char uart_buf[4096];
/* The reserved field pads this structure out to 6KiB. 6KiB is chosen
* because the erase granularity of the internal flash storage is 2KiB
*/
uint8_t reserved0[1880];
/* The rw_version of the firmware which created this record */
struct persistent_panic_rw_version rw_version;
/* The version number of the persistent panic record struct.
* -1: Doesn't include rw_version field.
* 0: Includes rw_version field.
*/
little_int32_t persistent_panic_record_version;
};
// Set of commands for regions in the image descriptor
#define EC_PRV_CMD_HOTH_GET_REGION_FROM_IMG_DESC 0x001B
/* GET_REGION_HOTH_UPDATE:Hoth looks for the image_descriptor and
* finds the “hoth_update” region, ensures it is mutable and returns its start
* offset and size.
*/
#define GET_REGION_HOTH_UPDATE 0
struct get_region_request {
uint8_t type; /* One of GET_REGION_* */
};
#define HOTH_UPDATE_REGION_FLAG_VALID 1
// A EC_PRV_CMD_HOTH_SPI_OPERATION request consists of one or more SPI
// transactions. Each SPI transaction consists of a ec_spi_operation_request
// header followed by the MOSI bytes (starting with the opcode), and each
// transaction is laid-out back-to-back with no padding or alignment.
//
// The response consists of the first ec_spi_operation_request::miso_len
// MISO bytes of each SPI transaction, including the dummy MISO bytes sent while
// the opcode/addr/dummy MOSI bytes are being transmitted. All the MISO bytes
// are laid-out back-to-back with no header, padding, or alignment.
#define EC_PRV_CMD_HOTH_SPI_OPERATION 0x0020
/* Options and request struct for EC_PRV_CMD_HOTH_RESET_TARGET */
enum ec_target_reset_option {
EC_TARGET_RESET_OPTION_RELEASE = 0, // Release target from reset
EC_TARGET_RESET_OPTION_SET = 1, // Put target in reset
EC_TARGET_RESET_OPTION_PULSE = 2, // Put target in reset then release
};
#define RESET_TARGET_ID_RSTCTRL0 0
struct ec_request_reset_target {
little_uint32_t target_id;
uint8_t reset_option; // "reset_option" must be one of ec_target_reset_option
little_uint32_t padding[3];
};
/* Reports on whether a command is allowed to run given the current host command
* filtering that the firmware is using. In order for this command to return
* true, the command must exist and must have is_command_allowed() return true.
*/
#define EC_PRV_CMD_HOTH_IS_HOST_COMMAND_SUPPORTED 0x0011
struct ec_request_is_host_command_supported {
little_uint16_t command;
};
struct ec_response_is_host_command_supported {
uint8_t is_allowed;
};
/* Reset the target device. */
#define EC_PRV_CMD_HOTH_RESET_TARGET 0x0012
// After sending this command, any future synchronous SPI reads from the RoT's
// SPI-slave interface will return all zeroes, but out-of-band methods (such as
// EC_SPI_OPERATION via USB) will be able to interact with the SPI flash.
#define EC_PRV_CMD_HOTH_SPS_PASSTHROUGH_DISABLE 0x003b
// Re-enables SPS passthrough. Future out-of-band access to the SPI flash will
// fail.
#define EC_PRV_CMD_HOTH_SPS_PASSTHROUGH_ENABLE 0x003c
#define EC_PRV_CMD_HOTH_GET_SPS_PASSTHROUGH_STATUS 0x0042
struct ec_response_sps_passthrough_status {
/* sps_passthrough_enabled = 0 = passthrough is disabled: synchronous SPI
reads from the RoT's SPI-slave interface will return all zeroes, but
out-of-band methods (such as EC_SPI_OPERATION via USB) will be able to interact
with the SPI flash sps_passthrough_enabled = 1 = passthrough is enabled: Future
out-of-band access to the SPI flash will
* fail.
*/
uint8_t sps_passthrough_enabled;
} __attribute__((packed, aligned(4)));
struct ec_params_console_read_v1 {
uint8_t subcmd;
} __attribute__((packed));
struct ec_channel_status_request {
little_uint32_t channel_id;
} __attribute__((aligned(4)));
struct ec_channel_status_response {
// The offset where the next data received in the channel will be written
little_uint32_t write_offset;
} __attribute__((aligned(4)));
struct ec_channel_read_request {
little_uint32_t channel_id;
// The 32-bit offset from the start of the stream to retrieve data from. If
// no data is available at this offset, it will be incremented to the first
// available data. The caller can detect discontinuities by observing the
// returned offset.
//
// This value will wrap around once the channel has delivered 4GiB of data.
little_uint32_t offset;
// the amount of data to return
little_uint32_t size;
// Maximum time to wait for new data to show up. If timeout is hit, command
// will succeed but will return 0 bytes.
little_uint32_t timeout_us;
} __attribute__((aligned(4)));
struct ec_channel_read_response {
// The actual offset where the returned data was found.
// This won't match the offset in the read request if the requested data
// wasn't available. Instead, it will be the offset of the first available
// data.
little_uint32_t offset;
// followed by the requested bytes.
} __attribute__((aligned(4)));
#define EC_PRV_CMD_HOTH_GET_AUTHZ_RECORD 0x0018
struct ec_authz_record_get_request {
// Authorization record index to get. Currently only index=0 is
// supported.
uint8_t index;
uint8_t reserved[3];
} __attribute__((packed));
#define AUTHORIZATION_RECORD_MAGIC_SIZE 8
#define AUTHORIZATION_RECORD_SIGNATURE_SIZE (96 * 4)
#define AUTHORIZATION_RECORD_FAUX_FUSES_SIZE 4
#define AUTHORIZATION_RECORD_NONCE_SIZE 32
// All multi-byte fields are little endian.
struct authorization_record {
uint8_t magic[AUTHORIZATION_RECORD_MAGIC_SIZE];
little_uint32_t
signature[AUTHORIZATION_RECORD_SIGNATURE_SIZE / sizeof(uint32_t)];
little_uint32_t version;
little_uint32_t reserved_0;
little_uint32_t size;
little_uint32_t key_id;
little_uint32_t flags;
uint8_t faux_fuses[AUTHORIZATION_RECORD_FAUX_FUSES_SIZE];
little_uint64_t capabilities;
little_uint32_t dev_id_0;
little_uint32_t dev_id_1;
little_uint32_t
authorization_nonce[AUTHORIZATION_RECORD_NONCE_SIZE / sizeof(uint32_t)];
} __attribute__((aligned(4)));
struct ec_authz_record_get_response {
// Index of authorization record in the response. This value matches the
// `index` in the corresponding host command request.
uint8_t index;
// When `valid` is non-zero value, the `record` at `index` in this
// response is valid.
uint8_t valid;
uint8_t reserved[2];
struct authorization_record record;
} __attribute__((aligned(4)));
#define EC_PRV_CMD_HOTH_KEY_ROTATION_OP 0x004d
struct ec_request_key_rotation_record {
uint16_t operation; // enum key_rotation_record_op
uint16_t
packet_offset; // Read/write offset. For
// KEY_ROTATION_RECORD_READ_CHUNK_TYPE operation,
// this is the offset within the specified chunk to read.
uint16_t packet_size; // Read/write size excluding this header. For
// KEY_ROTATION_RECORD_READ_CHUNK_TYPE operation, this
// is the size of the chunk to read starting at the
// specified offset.
uint16_t reserved;
} __attribute__((packed, aligned(4)));
enum key_rotation_record_op {
KEY_ROTATION_RECORD_INITIATE = 0, // Erases staging half
KEY_ROTATION_RECORD_WRITE = 1, // Write to staging half
KEY_ROTATION_RECORD_COMMIT = 2, // Commits staging half to active half
KEY_ROTATION_RECORD_GET_VERSION = 3, // Get current version of key
// rotation record
KEY_ROTATION_RECORD_READ = 4, // Read from key rotation record from flash
// (offset, size, A/B/Active/Staging)
KEY_ROTATION_RECORD_GET_STATUS = 5, // Read key rotation record version,
// image family, variant,
// validation method, key data,
// hash data
KEY_ROTATION_RECORD_READ_CHUNK_TYPE =
6, // Gets the ith chunk of given chunk_typecode and returns the
// chunk_size starting from the chunk_offset (chunk_index,
// chunk_offset, chunk_typecode, chunk_size)
KEY_ROTATION_RECORD_PAYLOAD_STATUS = 7, // Get validation method and data
KEY_ROTATION_RECORD_CHUNK_TYPE_COUNT = 8, // Get the number of chunks of a
// given chunk_typecode
};
// Validation method used to validate the payload.
enum key_rotation_validation_method {
KEY_ROTATION_VALIDATION_METHOD_UNKNOWN =
0, // Payload has not been validated.
KEY_ROTATION_VALIDATION_METHOD_EMBEDDED_KEY =
1, // Key embedded in the firmware.
KEY_ROTATION_VALIDATION_METHOD_PAYLOAD_KEY =
2, // Key present in the key rotation record.
KEY_ROTATION_VALIDATION_METHOD_HASH =
3, // Hash of the payload present in the key rotation record.
KEY_ROTATION_VALIDATION_METHOD_PAYLOAD_NOT_VALID = 4,
KEY_ROTATION_VALIDATION_METHOD_GET_ERROR =
0xFFFFFFFF, // Magic value used by hothd to indicate that key rotation
// query failed (either unsupported or communication error).
};
struct ec_response_key_rotation_status {
uint32_t version; // Config package version, used for anti-rollback
uint16_t image_family; // Image family of the payload keys this record is for
uint16_t image_family_variant; // Variant of the image family if any.
uint32_t validation_method; // enum key_rotation_validation_method
uint32_t validation_key_data; // If validation method is embedded key or
// payload key, first 32 bits of modulus of the
// key used to validate the payload
uint32_t validation_hash_data; // If validation method is hash, first 32 bits
// of cr51 hash
} __attribute__((packed, aligned(4)));
#endif /* __PRIVATE_CR51_INCLUDE_CR51_HOST_COMMANDS_H */