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