core/cmd_interface/cerberus_protocol_optional_commands.h (462 lines of code) (raw):

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. #ifndef CERBERUS_PROTOCOL_OPTIONAL_COMMANDS_H_ #define CERBERUS_PROTOCOL_OPTIONAL_COMMANDS_H_ #include <stdbool.h> #include <stdint.h> #include "attestation/attestation.h" #include "attestation/pcr_store.h" #include "cmd_interface/cerberus_protocol.h" #include "cmd_interface/cmd_authorization.h" #include "cmd_interface/cmd_background.h" #include "cmd_interface/cmd_interface.h" #include "cmd_interface/device_manager.h" #include "cmd_interface/session_manager.h" #include "common/buffer_util.h" #include "crypto/hash.h" #include "firmware/firmware_update_control.h" #include "host_fw/host_control.h" #include "host_fw/host_processor.h" #include "manifest/manifest_cmd_interface.h" #include "manifest/pfm/pfm_manager.h" #include "mctp/mctp_base_protocol.h" #include "recovery/recovery_image_cmd_interface.h" #include "recovery/recovery_image_manager.h" /** * Identifier for the type of system log. */ enum { CERBERUS_PROTOCOL_DEBUG_LOG = 1, /**< Debug log type. */ CERBERUS_PROTOCOL_ATTESTATION_LOG, /**< Attestation log type. */ CERBERUS_PROTOCOL_TAMPER_LOG, /**< Tamper log type. */ CERBERUS_PROTOCOL_TCG_LOG, /**< TCG formatted log type. */ CERBERUS_PROTOCOL_VENDOR_DEBUG_LOG, /**< Vendor debug log type. */ }; /** * Identifier for the type of key being exchanged. */ enum { CERBERUS_PROTOCOL_SESSION_KEY = 0, /**< Exchange session encryption key */ CERBERUS_PROTOCOL_PAIRED_KEY_HMAC, /**< Exchange an HMAC paired key */ CERBERUS_PROTOCOL_DELETE_SESSION_KEY, /**< Delete session key */ }; /** * Identifier for the type of HMAC used in a key exchange. */ enum { CERBERUS_PROTOCOL_HMAC_SHA256 = 0, /**< HMAC using SHA256 */ CERBERUS_PROTOCOL_HMAC_SHA384, /**< HMAC using SHA384 */ CERBERUS_PROTOCOL_HMAC_SHA512, /**< HMAC using SHA512 */ }; /** * Identifier for the reset state of the host processor. */ enum { CERBERUS_PROTOCOL_HOST_RUNNING = 0, /**< The host is not in reset */ CERBERUS_PROTOCOL_HOST_HELD_IN_RESET, /**< The host is being held in reset */ CERBERUS_PROTOCOL_HOST_IN_RESET, /**< The host is not being held in reset, but is not running */ }; /** * Identifier for the type of configuration reset to execute. */ enum { CERBERUS_PROTOCOL_REVERT_BYPASS = 0, /**< Reset device to the unprotected state */ CERBERUS_PROTOCOL_FACTORY_RESET = 1, /**< Restore factory default configuration */ CERBERUS_PROTOCOL_CLEAR_PCD = 2, /**< Remove any PCD used by the device. */ CERBERUS_PROTOCOL_CLEAR_CFM = 3, /**< Remove any CFM used for component attestation. */ CERBERUS_PROTOCOL_RESET_INTRUSION = 4, /**< Clear the device intrusion state. */ CERBERUS_PROTOCOL_ALLOW_IMPACTFUL = 5, /**< Allow an impactful firmware update to be accepted. */ }; /** * Identifier for the unsealing HMAC algorithm. */ enum { CERBERUS_PROTOCOL_UNSEAL_HMAC_SHA256 = 0, /**< Unseal HMAC using SHA-256 */ }; /** * Identifier for the unsealing seed type. */ enum { CERBERUS_PROTOCOL_UNSEAL_SEED_RSA = 0, /**< Unseal seed is RSA encrypted */ CERBERUS_PROTOCOL_UNSEAL_SEED_ECDH, /**< Unseal seed uses ECDH */ }; /** * Identifier for unsealing RSA parameters. */ enum { CERBERUS_PROTOCOL_UNSEAL_RSA_PKCS15 = 0, /**< Seed is encrypted with PKCS 1.5 padding */ CERBERUS_PROTOCOL_UNSEAL_RSA_OAEP_SHA1, /**< Seed is encrypted with OAEP-SHA1 padding */ CERBERUS_PROTOCOL_UNSEAL_RSA_OAEP_SHA256, /**< Seed is encrypted with OAEP-SHA256 padding */ }; /** * Identifier for unsealing ECDH parameters. */ enum { CERBERUS_PROTOCOL_UNSEAL_ECDH_RAW = 0, /**< Seed is the raw ECDH output */ CERBERUS_PROTOCOL_UNSEAL_ECDH_SHA256, /**< Seed is the SHA256 hash of the ECDH output */ }; /** * Maximum number of PMRs that can be used for unsealing. */ #define CERBERUS_PROTOCOL_MAX_PMR 5 #pragma pack(push, 1) /** * Cerberus protocol prepare platform firmware manifest request format */ struct cerberus_protocol_prepare_pfm_update { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ uint32_t size; /**< Update size */ }; /** * Cerberus protocol platform firmware manifest update request format */ struct cerberus_protocol_pfm_update { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ uint8_t payload; /**< First byte of the variable PFM data */ }; /** * Get the amount of payload data in a PFM update message. * * @param req The command request structure containing the message. */ #define cerberus_protocol_pfm_update_length(req) \ ((req->length - sizeof (struct cerberus_protocol_pfm_update)) + sizeof (uint8_t)) /** * Cerberus protocol activate platform firmware manifest request format */ struct cerberus_protocol_complete_pfm_update { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ uint8_t activation; /**< 0 for after reboot, 1 to activate immediately */ }; /** * Cerberus protocol get platform firmware manifest ID request format */ struct cerberus_protocol_get_pfm_id { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ uint8_t region; /**< 0 for active, 1 for staging */ uint8_t id; /**< Identifier to retrieve (optional) */ }; /** * Cerberus protocol get platform firmware manifest ID response format with a version identifier */ struct cerberus_protocol_get_pfm_id_version_response { struct cerberus_protocol_header header; /**< Message header */ uint8_t valid; /**< Port contains valid PFM */ uint32_t version; /**< PFM version ID */ }; /** * Cerberus protocol get platform firmware manifest ID response format with a platform identifier */ struct cerberus_protocol_get_pfm_id_platform_response { struct cerberus_protocol_header header; /**< Message header */ uint8_t valid; /**< Port contains valid PFM */ uint8_t platform; /**< First byte of the ASCII platform ID */ }; /** * Get the total response length for a get platform firmware manifest ID response message. * * @param len Length of the platform id string including null terminator */ #define cerberus_protocol_get_pfm_id_platform_response_length(len) \ (len + sizeof (struct cerberus_protocol_get_pfm_id_platform_response) - sizeof (uint8_t)) /** * Maximum amount of platform firmware manifest platform ID data that can be returned * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_MAX_PFM_ID_PLATFORM(req) \ ((req->max_response - sizeof (struct cerberus_protocol_get_pfm_id_platform_response)) + sizeof (uint8_t)) /** * Cerberus protocol get platform firmware manifest supported FW request format. This is the * minimum length of the command and does not include optional arguments. */ struct cerberus_protocol_get_pfm_supported_fw { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ uint8_t region; /**< 0 for active, 1 for staging */ uint32_t offset; /**< Offset to start response at */ }; /** * Cerberus protocol get platform firmware manifest supported FW response format */ struct cerberus_protocol_get_pfm_supported_fw_response { struct cerberus_protocol_header header; /**< Message header */ uint8_t valid; /**< Port contains valid PFM */ uint32_t version; /**< PFM version identifier */ }; /** * Get the length of the firmware ID being queried */ #define cerberus_protocol_get_pfm_supported_fw_id_length(req) *(((uint8_t*) req) + sizeof (*req)) /** * Get the buffer containing the firmware ID string being queried */ #define cerberus_protocol_get_pfm_supported_fw_id(req) \ (((char*) req) + sizeof (*req) + sizeof (uint8_t)) /** * Get the total length of a supported FW request that includes the option firmware ID. */ #define cerberus_protocol_get_pfm_supported_fw_request_length_with_id(req) \ (sizeof (*req) + sizeof (uint8_t) + cerberus_protocol_get_pfm_supported_fw_id_length (req)) /** * Get the buffer containing the support FW versions */ #define cerberus_protocol_pfm_supported_fw(resp) (((uint8_t*) resp) + sizeof (*resp)) /** * Get the total message length for a get PFM support FW versions response message. * * @param len Length of the version data. */ #define cerberus_protocol_get_pfm_supported_fw_response_length(len) \ (len + sizeof (struct cerberus_protocol_get_pfm_supported_fw_response)) /** * Maximum amount of supported FW version data that can be returned in a single request * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_MAX_PFM_VERSIONS(req) \ (req->max_response - sizeof (struct cerberus_protocol_get_pfm_supported_fw_response)) /** * Cerberus protocol recover firmware request format */ struct cerberus_protocol_recover_firmware { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID for recovery */ uint8_t recovery_img; /**< Recovery image ID */ }; /** * Cerberus protocol prepare a host recovery image update request format */ struct cerberus_protocol_prepare_recovery_image_update { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ uint32_t size; /**< Update size */ }; /** * Cerberus protocol host recovery image update request format */ struct cerberus_protocol_recovery_image_update { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ uint8_t payload; /**< First byte of the variable data */ }; /** * Get the amount of payload data in a recovery image update message. * * @param req The command request structure containing the message. */ #define cerberus_protocol_recovery_image_update_length(req) \ ((req->length - sizeof (struct cerberus_protocol_recovery_image_update)) + sizeof (uint8_t)) /** * Cerberus protocol host recovery image activate update request format */ struct cerberus_protocol_complete_recovery_image_update { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ }; /** * Cerberus protocol get host recovery image ID request format */ struct cerberus_protocol_get_recovery_image_id { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ uint8_t id; /**< Identifier to retrieve (optional) */ }; /** * Cerberus protocol get host recovery image ID response format with a version identifier */ struct cerberus_protocol_get_recovery_image_id_version_response { struct cerberus_protocol_header header; /**< Message header */ char version[32]; /**< Version ID */ }; /** * Cerberus protocol get host recovery image ID response format with a platform identifier */ struct cerberus_protocol_get_recovery_image_id_platform_response { struct cerberus_protocol_header header; /**< Message header */ uint8_t platform; /**< First byte of the ASCII platform ID */ }; /** * Cerberus protocol get host reset status request format */ struct cerberus_protocol_get_host_state { struct cerberus_protocol_header header; /**< Message header */ uint8_t port_id; /**< Port ID */ }; /** * Cerberus protocol get host reset status response format */ struct cerberus_protocol_get_host_state_response { struct cerberus_protocol_header header; /**< Message header */ uint8_t reset_status; /**< Host reset status */ }; /** * Cerberus protocol get platform measurement register request format */ struct cerberus_protocol_pmr { struct cerberus_protocol_header header; /**< Message header */ uint8_t measurement_number; /**< PMR to query */ uint8_t nonce[32]; /**< Requestor freshness seed */ }; /** * Cerberus protocol get platform measurement register response format */ struct cerberus_protocol_pmr_response { struct cerberus_protocol_header header; /**< Message header */ uint8_t nonce[32]; /**< Responder freshness seed */ uint8_t pmr_length; /**< Length of the measurement */ uint8_t measurement; /**< First byte of the variable length measurement */ }; /** * Get the buffer containing the PMR response signature. * * @param resp Pointer to a PMR response message. */ #define cerberus_protocol_pmr_get_signature(resp) ((&((resp)->measurement)) + (resp)->pmr_length) /** * Cerberus protocol update platform measurement register request format */ struct cerberus_protocol_update_pmr { struct cerberus_protocol_header header; /**< Message header */ uint8_t measurement_number; /**< Index for the PMR to update */ uint8_t measurement_ext; /**< First byte of the measurement to use for the update */ }; /** * Get the amount of measurement data in an update PMR message. * * @param req The command request structure containing the message. */ #define cerberus_protocol_update_pmr_measurement_length(req) \ ((req->length - sizeof (struct cerberus_protocol_update_pmr)) + sizeof (uint8_t)) /** * Cerberus protocol key exchange request format */ struct cerberus_protocol_key_exchange { struct cerberus_protocol_header header; /**< Message header */ uint8_t key_type; /**< Type of key being exchanged */ }; /** * Get the buffer containing the request data in an exchange request * * @param req The command request structure containing the message. */ #define cerberus_protocol_key_exchange_data(req) \ (((uint8_t*) req) + sizeof (struct cerberus_protocol_key_exchange)) /** * Get request data length from a key exchange request. * * @param req The command request structure containing the message. */ #define cerberus_protocol_key_exchange_data_len(req) \ (req->length - sizeof (struct cerberus_protocol_key_exchange)) /** * Cerberus protocol key exchange response format */ struct cerberus_protocol_key_exchange_response { struct cerberus_protocol_header header; /**< Message header */ uint8_t key_type; /**< Type of key being exchanged */ }; /** * Get the buffer containing the response data in an exchange request * * @param req The command request structure containing the message. */ #define cerberus_protocol_key_exchange_response_data(req) \ (((uint8_t*) req) + sizeof (struct cerberus_protocol_key_exchange_response)) /** * Cerberus protocol key exchange type 0 request format */ struct cerberus_protocol_key_exchange_type_0 { struct cerberus_protocol_key_exchange common; /**< Common request fields between all key exchange requests */ uint8_t hmac_type; /**< Type of HMAC to be used in this exchange */ }; /** * Get the buffer containing the ephemeral key data in a type 0 key exchange request * * @param req The command request structure containing the message. */ #define cerberus_protocol_key_exchange_type_0_key_data(req) \ (((uint8_t*) req) + sizeof (struct cerberus_protocol_key_exchange_type_0)) /** * Get the total message length for a type 0 key exchange request. * * @param len Length of the key data. */ #define cerberus_protocol_key_exchange_type_0_length(len) \ (len + sizeof (struct cerberus_protocol_key_exchange_type_0)) /** * Get the key length from a type 0 key exchange request. * * @param req The command request structure containing the message. */ #define cerberus_protocol_key_exchange_type_0_key_len(req) \ (req->length - sizeof (struct cerberus_protocol_key_exchange_type_0)) /** * Cerberus protocol key exchange type 0 response format */ struct cerberus_protocol_key_exchange_response_type_0 { struct cerberus_protocol_key_exchange common; /**< Common response fields between all key exchange responses */ uint8_t reserved; /**< Reserved */ uint16_t key_len; /**< Cerberus ephemeral key length */ }; /** * Get the buffer containing the ephemeral key data in a type 0 key exchange response * * @param req The cerberus_protocol_key_exchange_response_type_0 structure containing the message. */ #define cerberus_protocol_key_exchange_type_0_response_key_data(req) \ (((uint8_t*) req) + sizeof (struct cerberus_protocol_key_exchange_response_type_0)) /** * Maximum key length that can be returned in a single request * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_KEY_EXCHANGE_TYPE_0_RESPONSE_MAX_KEY_DATA(req) \ (req->max_response - sizeof (struct cerberus_protocol_key_exchange_response_type_0)) /** * Get the buffer containing the signature length in a type 0 key exchange response * * @param req The cerberus_protocol_key_exchange_response_type_0 structure containing the message. */ #define cerberus_protocol_key_exchange_type_0_response_sig_len(req) \ (*((uint16_t*) (cerberus_protocol_key_exchange_type_0_response_key_data (req) + req->key_len))) /** * Get the buffer containing the signature data in a type 0 key exchange response * * @param req The cerberus_protocol_key_exchange_response_type_0 structure containing the message. */ #define cerberus_protocol_key_exchange_type_0_response_sig_data(req) \ (cerberus_protocol_key_exchange_type_0_response_key_data (req) + req->key_len + \ sizeof (uint16_t)) /** * Maximum signature length that can be returned in a single request * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_KEY_EXCHANGE_TYPE_0_RESPONSE_MAX_SIG_DATA(req) \ (CERBERUS_PROTOCOL_KEY_EXCHANGE_TYPE_0_RESPONSE_MAX_KEY_DATA (req) - \ ((struct cerberus_protocol_key_exchange_response_type_0*) (req->data))->key_len - \ sizeof (uint16_t)) /** * Get the buffer containing the HMAC length in a type 0 key exchange response * * @param req The cerberus_protocol_key_exchange_response_type_0 structure containing the message. */ #define cerberus_protocol_key_exchange_type_0_response_hmac_len(req) \ (*((uint16_t*) (((uint8_t*) cerberus_protocol_key_exchange_type_0_response_sig_data (req)) + \ cerberus_protocol_key_exchange_type_0_response_sig_len (req)))) /** * Get the buffer containing the HMAC data in a type 0 key exchange response * * @param req The cerberus_protocol_key_exchange_response_type_0 structure containing the message. */ #define cerberus_protocol_key_exchange_type_0_response_hmac_data(req) \ (((uint8_t*)(cerberus_protocol_key_exchange_type_0_response_sig_data (req))) + \ sizeof (uint16_t) + cerberus_protocol_key_exchange_type_0_response_sig_len (req)) /** * Maximum signature length that can be returned in a single request * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_KEY_EXCHANGE_TYPE_0_RESPONSE_MAX_HMAC_DATA(req) \ (CERBERUS_PROTOCOL_KEY_EXCHANGE_TYPE_0_RESPONSE_MAX_SIG_DATA (req) - sizeof (uint16_t) - \ cerberus_protocol_key_exchange_type_0_response_sig_len ( \ ((struct cerberus_protocol_key_exchange_response_type_0*)req->data))) /** * Get the total message length for a type 0 key exchange response. * * @param key_len Length of the key data. */ #define cerberus_protocol_key_exchange_type_0_response_length(key_len, sig_len, hmac_len) \ (key_len + sig_len + hmac_len + \ sizeof (struct cerberus_protocol_key_exchange_response_type_0) + sizeof (uint16_t) * 2) /** * Cerberus protocol key exchange type 1 request format */ struct cerberus_protocol_key_exchange_type_1 { struct cerberus_protocol_key_exchange common; /**< Common request fields between all key exchange requests */ uint16_t pairing_key_len; /**< Length in bytes of the pairing key */ }; /** * Get the buffer containing the HMAC in a type 1 key exchange request * * @param req The command request structure containing the message. */ #define cerberus_protocol_key_exchange_type_1_hmac_data(req) \ (((uint8_t*) req) + sizeof (struct cerberus_protocol_key_exchange_type_1)) /** * Get the total message length for a type 1 key exchange request. * * @param len Length of the HMAC data. */ #define cerberus_protocol_key_exchange_type_1_length(len) \ (len + sizeof (struct cerberus_protocol_key_exchange_type_1)) /** * Get the HMAC length from a type 1 key exchange request. * * @param req The command request structure containing the message. */ #define cerberus_protocol_key_exchange_type_1_hmac_len(req) \ (req->length - sizeof (struct cerberus_protocol_key_exchange_type_1)) /** * Cerberus protocol key exchange type 2 request format */ struct cerberus_protocol_key_exchange_type_2 { struct cerberus_protocol_key_exchange common; /**< Common request fields between all key exchange requests */ }; /** * Get the buffer containing the HMAC in a type 2 key exchange request * * @param req The command request structure containing the message. */ #define cerberus_protocol_key_exchange_type_2_hmac_data(req) \ (((uint8_t*) req) + sizeof (struct cerberus_protocol_key_exchange_type_2)) /** * Get the total message length for a type 2 key exchange request. * * @param len Length of the HMAC data. */ #define cerberus_protocol_key_exchange_type_2_length(len) \ (len + sizeof (struct cerberus_protocol_key_exchange_type_2)) /** * Get the HMAC length from a type 2 key exchange request. * * @param req The command request structure containing the message. */ #define cerberus_protocol_key_exchange_type_2_hmac_len(req) \ (req->length - sizeof (struct cerberus_protocol_key_exchange_type_2)) /** * Cerberus protocol get log info request format */ struct cerberus_protocol_get_log_info { struct cerberus_protocol_header header; /**< Message header */ }; /** * Cerberus protocol get log info response format */ struct cerberus_protocol_get_log_info_response { struct cerberus_protocol_header header; /**< Message header */ uint32_t debug_log_length; /**< Length of the debug log */ uint32_t attestation_log_length; /**< Length of the attestation log */ uint32_t tamper_log_length; /**< Length of the tamper log */ }; /** * Cerberus protocol get log request format */ struct cerberus_protocol_get_log { struct cerberus_protocol_header header; /**< Message header */ uint8_t log_type; /**< Log identifier to read */ uint32_t offset; /**< Offset to start reding the log */ }; /** * Cerberus protocol get log response format */ struct cerberus_protocol_get_log_response { struct cerberus_protocol_header header; /**< Message header */ }; /** * Get the buffer containing the retrieved log data */ #define cerberus_protocol_log_data(resp) (((uint8_t*) resp) + sizeof (*resp)) /** * Get the total message length for a get log response message. * * @param log_len Length of the log data. */ #define cerberus_protocol_get_log_response_length(log_len) \ (log_len + sizeof (struct cerberus_protocol_get_log_response)) /** * Maximum amount of log data that can be returned in a single request * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_MAX_LOG_DATA(req) \ (req->max_response - sizeof (struct cerberus_protocol_get_log_response)) /** * Cerberus protocol clear log request format */ struct cerberus_protocol_clear_log { struct cerberus_protocol_header header; /**< Message header */ uint8_t log_type; /**< Log to clear */ }; /** * Cerberus protocol get attestation data request format */ struct cerberus_protocol_get_attestation_data { struct cerberus_protocol_header header; /**< Message header */ uint8_t pmr; /**< PMR index for the requested data */ uint8_t entry; /**< Entry index for the requested data */ uint32_t offset; /**< Offset in the data */ }; /** * Cerberus protocol get attestation data response format */ struct cerberus_protocol_get_attestation_data_response { struct cerberus_protocol_header header; /**< Message header */ }; /** * Get the buffer containing the retrieved raw attestation data */ #define cerberus_protocol_attestation_data(resp) (((uint8_t*) resp) + sizeof (*resp)) /** * Get the total message length for a get attestation data response message. * * @param len Length of the log data. */ #define cerberus_protocol_get_attestation_data_response_length(len) \ (len + sizeof (struct cerberus_protocol_get_attestation_data_response)) /** * Maximum amount of attestation data that can be returned in a single request * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_MAX_ATTESTATION_DATA(req) \ (req->max_response - sizeof (struct cerberus_protocol_get_attestation_data_response)) /** * Cerberus protocol get attestation summary request format */ struct cerberus_protocol_get_attestation_summary { struct cerberus_protocol_header header; /**< Message header */ uint32_t component_id; /**< Component ID for the requested data */ uint8_t component_instance; /**< Component instance for the requested data */ }; /** * Cerberus protocol get attestation summary response format */ struct cerberus_protocol_get_attestation_summary_response { struct cerberus_protocol_header header; /**< Message header */ struct device_manager_attestation_summary summary; /**< Attestation summary data */ }; /** * Cerberus protocol prepare firmware update request format */ struct cerberus_protocol_prepare_fw_update { struct cerberus_protocol_header header; /**< Message header */ uint32_t total_size; /**< Total update size */ }; /** * Cerberus protocol firmware update request format */ struct cerberus_protocol_fw_update { struct cerberus_protocol_header header; /**< Message header */ uint8_t payload; /**< First byte of the variable data */ }; /** * Get the amount of payload data in a FW update message. * * @param req The command request structure containing the message. */ #define cerberus_protocol_fw_update_length(req) \ ((req->length - sizeof (struct cerberus_protocol_fw_update)) + sizeof (uint8_t)) /** * Cerberus protocol activate firmware update request format */ struct cerberus_protocol_complete_fw_update { struct cerberus_protocol_header header; /**< Message header */ }; /** * Cerberus protocol reset configuration request format */ struct cerberus_protocol_reset_config { struct cerberus_protocol_header header; /**< Message header */ uint8_t type; /**< The type of reset operation to perform */ }; /** * Get the buffer containing the authorization token for a reset operation. This works with both * reset configuration request and response messages. */ #define cerberus_protocol_reset_authorization(msg) (((uint8_t*) msg) + sizeof (*msg)) /** * Get the amount of authorization token data in a reset configuration message. * * @param req The command request structure containing the message. */ #define cerberus_protocol_reset_authorization_length(req) \ (req->length - sizeof (struct cerberus_protocol_reset_config)) /** * Cerberus protocol reset configuration response format */ struct cerberus_protocol_reset_config_response { struct cerberus_protocol_header header; /**< Message header */ }; /** * Get the total message length for a reset configuration response message. * * @param auth_len Length of the authorization data. */ #define cerberus_protocol_get_reset_config_response_length(auth_len) \ (auth_len + sizeof (struct cerberus_protocol_reset_config_response)) /** * Maximum amount of authorization data that can be returned for a reset configuration request. * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_MAX_AUTHORIZATION_DATA(req) \ (req->max_response - sizeof (struct cerberus_protocol_reset_config_response)) /** * Cerberus protocol message unseal request format */ struct cerberus_protocol_message_unseal { struct cerberus_protocol_header header; /**< Message header */ uint8_t seed_type:2; /**< Type of seed used for unsealing */ uint8_t hmac_type:3; /**< Type of HMAC used for unsealing */ uint8_t reserved:3; /**< Unused */ union { struct { uint8_t padding : 3; /**< RSA encryption padding scheme */ uint8_t reserved : 5; /**< Unused */ } rsa; struct { uint8_t processing : 1; /**< Additional processing on ECDH seed */ uint8_t reserved : 7; /**< Unused. */ } ecdh; uint8_t raw; /**< Raw seed parameter value */ } seed_params; /**< Additional parameters for the seed */ uint16_t seed_length; /**< Length of the unsealing seed */ uint8_t seed; /**< First byte of the unsealing seed */ }; /** * PMRs used for unsealing a message. */ struct cerberus_protocol_unseal_pmrs { uint8_t pmr[CERBERUS_PROTOCOL_MAX_PMR][64]; /**< PMRs used for sealing */ }; /** * Get the pointer to the ciphertext length entry */ #define cerberus_protocol_unseal_ciphertext_length_ptr(req) \ (((uint8_t*) req) + sizeof (*req) + buffer_unaligned_read16 (&req->seed_length) - \ sizeof (req->seed)) /** * Get the ciphertext length in an unseal request message */ #define cerberus_protocol_unseal_ciphertext_length(req) \ *((uint16_t*) cerberus_protocol_unseal_ciphertext_length_ptr (req)) /** * Get the buffer containing the ciphertext from an unseal request message */ #define cerberus_protocol_unseal_ciphertext(req) \ (cerberus_protocol_unseal_ciphertext_length_ptr (req) + sizeof (uint16_t)) /** * Get the pointer to the HMAC length entry */ #define cerberus_protocol_unseal_hmac_length_ptr(req) (cerberus_protocol_unseal_ciphertext (req) + \ buffer_unaligned_read16 ((uint16_t*) cerberus_protocol_unseal_ciphertext_length_ptr (req))) /** * Get the HMAC length in an unseal request message */ #define cerberus_protocol_unseal_hmac_length(req) \ *((uint16_t*) cerberus_protocol_unseal_hmac_length_ptr (req)) /** * Get the buffer containing the HMAC from an unseal request message */ #define cerberus_protocol_unseal_hmac(req) \ (cerberus_protocol_unseal_hmac_length_ptr (req) + sizeof (uint16_t)) /** * Get the list of PMRs to use for unsealing. This will returned as a pointer to * struct cerberus_protocol_unseal_pmrs. */ #define cerberus_protocol_get_unseal_pmr_sealing(req) \ ((const struct cerberus_protocol_unseal_pmrs*) (cerberus_protocol_unseal_hmac (req) + \ cerberus_protocol_unseal_hmac_length (req))) /** * Cerberus protocol message unseal result request format */ struct cerberus_protocol_message_unseal_result { struct cerberus_protocol_header header; /**< Message header */ }; /** * Cerberus protocol message unseal result request format */ struct cerberus_protocol_message_unseal_result_response { struct cerberus_protocol_header header; /**< Message header */ uint32_t unseal_status; /**< Status of the unseal operation */ }; /** * Cerberus protocol message unseal result request format */ struct cerberus_protocol_message_unseal_result_completed_response { struct cerberus_protocol_header header; /**< Message header */ uint32_t unseal_status; /**< Status of the unseal operation */ uint16_t key_length; /**< Length of the unsealed key */ uint8_t key; /**< First byte of the variable length key */ }; /** * Get the total message length for an unseal result response message with key data. * * @param len Length of the key data. */ #define cerberus_protocol_get_unseal_response_length(len) \ ((len + sizeof (struct cerberus_protocol_message_unseal_result_completed_response)) - \ sizeof (uint8_t)) /** * Maximum amount of key data that can be returned from an unseal request * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_MAX_UNSEAL_KEY_DATA(req) ((req->max_response - \ sizeof (struct cerberus_protocol_message_unseal_result_completed_response)) + sizeof (uint8_t)) /** * Cerberus protocol session sync request format */ struct cerberus_protocol_session_sync { struct cerberus_protocol_header header; /**< Message header */ uint32_t rn_req; /**< Random number */ }; /** * Cerberus protocol session sync response format */ struct cerberus_protocol_session_sync_response { struct cerberus_protocol_header header; /**< Message header */ }; /** * Get pointer to the HMAC in a session sync response * * @param req The command request structure containing the message. */ #define cerberus_protocol_session_sync_hmac_data(req) \ (((uint8_t*) req) + sizeof (struct cerberus_protocol_session_sync_response)) /** * Get the total message length for a session sync response. * * @param len Length of the HMAC data. */ #define cerberus_protocol_session_sync_length(len) \ (len + sizeof (struct cerberus_protocol_session_sync_response)) /** * Maximum length that be used for the HMAC buffer in a session sync response. * * @param req The command request structure containing the message. */ #define CERBERUS_PROTOCOL_MAX_SESSION_SYNC_HMAC_LEN(req) \ ((req->max_response - sizeof (struct cerberus_protocol_session_sync_response))) #pragma pack(pop) int cerberus_protocol_fw_update_init (const struct firmware_update_control *control, struct cmd_interface_msg *request); int cerberus_protocol_fw_update (const struct firmware_update_control *control, struct cmd_interface_msg *request); int cerberus_protocol_fw_update_start (const struct firmware_update_control *control, struct cmd_interface_msg *request); int cerberus_protocol_get_log_info (struct pcr_store *pcr_store, struct cmd_interface_msg *request); int cerberus_protocol_log_read (struct pcr_store *pcr_store, const struct hash_engine *hash, struct cmd_interface_msg *request); int cerberus_protocol_log_clear (const struct cmd_background *background, struct cmd_interface_msg *request); int cerberus_protocol_get_pfm_id (const struct pfm_manager *pfm_mgr[], uint8_t num_ports, struct cmd_interface_msg *request); int cerberus_protocol_get_pfm_fw (const struct pfm_manager *pfm_mgr[], uint8_t num_ports, struct cmd_interface_msg *request); int cerberus_protocol_pfm_update_init (const struct manifest_cmd_interface *pfm_cmd[], uint8_t num_ports, struct cmd_interface_msg *request); int cerberus_protocol_pfm_update (const struct manifest_cmd_interface *pfm_cmd[], uint8_t num_ports, struct cmd_interface_msg *request); int cerberus_protocol_pfm_update_complete (const struct manifest_cmd_interface *pfm_cmd[], uint8_t num_ports, struct cmd_interface_msg *request); int cerberus_protocol_get_host_reset_status (const struct host_control *host_0_ctrl, const struct host_control *host_1_ctrl, struct cmd_interface_msg *request); int cerberus_protocol_unseal_message (const struct cmd_background *background, struct cmd_interface_msg *request); int cerberus_protocol_unseal_message_result (const struct cmd_background *background, struct cmd_interface_msg *request); int cerberus_protocol_reset_config (const struct cmd_authorization *cmd_auth, const struct cmd_background *background, struct cmd_interface_msg *request); const struct recovery_image_cmd_interface* cerberus_protocol_get_recovery_image_cmd_interface ( const struct recovery_image_cmd_interface *recovery_0, const struct recovery_image_cmd_interface *recovery_1, uint8_t port); struct recovery_image_manager* cerberus_protocol_get_recovery_image_manager ( struct recovery_image_manager *recovery_manager_0, struct recovery_image_manager *recovery_manager_1, uint8_t port); int cerberus_protocol_prepare_recovery_image (const struct recovery_image_cmd_interface *recovery_0, const struct recovery_image_cmd_interface *recovery_1, struct cmd_interface_msg *request); int cerberus_protocol_update_recovery_image (const struct recovery_image_cmd_interface *recovery_0, const struct recovery_image_cmd_interface *recovery_1, struct cmd_interface_msg *request); int cerberus_protocol_activate_recovery_image ( const struct recovery_image_cmd_interface *recovery_0, const struct recovery_image_cmd_interface *recovery_1, struct cmd_interface_msg *request); int cerberus_protocol_get_recovery_image_id (struct recovery_image_manager *manager_0, struct recovery_image_manager *manager_1, struct cmd_interface_msg *request); int cerberus_protocol_get_attestation_data (struct pcr_store *store, struct cmd_interface_msg *request); int cerberus_protocol_get_attestation_summary (struct device_manager *device_mgr, struct cmd_interface_msg *request); int cerberus_protocol_key_exchange (struct session_manager *session, struct cmd_interface_msg *request, uint8_t encrypted); int cerberus_protocol_session_sync (struct session_manager *session, struct cmd_interface_msg *request, uint8_t encrypted); #endif /* CERBERUS_PROTOCOL_OPTIONAL_COMMANDS_H_ */