in core/cmd_interface/cmd_background_handler.c [244:394]
void cmd_background_handler_execute (const struct event_task_handler *handler,
struct event_task_context *context, bool *reset)
{
const struct cmd_background_handler *cmd = TO_DERIVED_TYPE (handler,
const struct cmd_background_handler, base_event);
int *op_status = NULL;
int status = CMD_BACKGROUND_UNSUPPORTED_OP;
switch (context->action) {
#ifdef CMD_ENABLE_UNSEAL
case CMD_BACKGROUND_HANDLER_ACTION_RUN_UNSEAL: {
struct cerberus_protocol_message_unseal *unseal =
(struct cerberus_protocol_message_unseal*) context->event_buffer;
enum aux_attestation_seed_param seed_param;
op_status = &cmd->state->attestation_status;
if (unseal->seed_type == CERBERUS_PROTOCOL_UNSEAL_SEED_ECDH) {
seed_param = (enum aux_attestation_seed_param) unseal->seed_params.ecdh.processing;
}
else {
seed_param = (enum aux_attestation_seed_param) unseal->seed_params.rsa.padding;
}
status = cmd->attestation->aux_attestation_unseal (cmd->attestation, cmd->hash,
AUX_ATTESTATION_KEY_256BIT, &unseal->seed,
buffer_unaligned_read16 (&unseal->seed_length),
(enum aux_attestation_seed_type) unseal->seed_type, seed_param,
cerberus_protocol_unseal_hmac (unseal), HMAC_SHA256,
cerberus_protocol_unseal_ciphertext (unseal),
buffer_unaligned_read16 (
(uint16_t*) cerberus_protocol_unseal_ciphertext_length_ptr (unseal)),
cerberus_protocol_get_unseal_pmr_sealing (unseal)->pmr, CERBERUS_PROTOCOL_MAX_PMR,
cmd->state->key, sizeof (cmd->state->key));
if (status != 0) {
debug_log_create_entry (DEBUG_LOG_SEVERITY_ERROR, DEBUG_LOG_COMPONENT_CMD_INTERFACE,
CMD_LOGGING_UNSEAL_FAIL, status, 0);
status = CMD_BACKGROUND_STATUS (ATTESTATION_CMD_STATUS_FAILURE, status);
}
break;
}
#endif
#ifdef CMD_ENABLE_RESET_CONFIG
case CMD_BACKGROUND_HANDLER_ACTION_AUTHORIZED_OP: {
const struct authorized_execution **execution =
(const struct authorized_execution**) context->event_buffer;
uint8_t op_start;
uint8_t op_error;
(*execution)->get_status_identifiers (*execution, &op_start, &op_error);
op_status = &cmd->state->config_status;
cmd_background_handler_set_status (cmd, &cmd->state->config_status, op_start);
status = (*execution)->execute (*execution, reset);
if (status != 0) {
status = CMD_BACKGROUND_STATUS (op_error, status);
}
break;
}
#endif
#ifdef CMD_ENABLE_DEBUG_LOG
case CMD_BACKGROUND_HANDLER_ACTION_DEBUG_LOG_CLEAR:
status = debug_log_clear ();
if (status == 0) {
debug_log_create_entry (DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_CMD_INTERFACE,
CMD_LOGGING_DEBUG_LOG_CLEARED, 0, 0);
}
else {
debug_log_create_entry (DEBUG_LOG_SEVERITY_ERROR, DEBUG_LOG_COMPONENT_CMD_INTERFACE,
CMD_LOGGING_DEBUG_LOG_CLEAR_FAIL, status, 0);
}
break;
#ifdef CMD_SUPPORT_DEBUG_COMMANDS
case CMD_BACKGROUND_HANDLER_ACTION_DEBUG_LOG_FILL: {
/* This command assumes logging to flash. To implement a more portable command would
* require an API from the logging interface to indicate the maximum number of entries
* or a direct API to fill the log with data. It's not worth that flexibility for a
* seldom used debug command. */
int max_count =
(FLASH_SECTOR_SIZE / sizeof (struct debug_log_entry)) * LOGGING_FLASH_SECTORS;
int i_entry;
debug_log_clear ();
for (i_entry = 0; i_entry < max_count; ++i_entry) {
debug_log_create_entry (DEBUG_LOG_SEVERITY_INFO,
DEBUG_LOG_COMPONENT_DEVICE_SPECIFIC, 0, 0, 0);
}
break;
}
#endif
#endif
case CMD_BACKGROUND_HANDLER_ACTION_AUTH_RIOT:
op_status = &cmd->state->cert_state;
status = riot_key_manager_verify_stored_certs (cmd->keys);
if (status != 0) {
debug_log_create_entry (DEBUG_LOG_SEVERITY_WARNING, DEBUG_LOG_COMPONENT_RIOT,
RIOT_LOGGING_DEVID_AUTH_STATUS, status, 0);
status = CMD_BACKGROUND_STATUS (RIOT_CERT_STATE_CHAIN_INVALID, status);
}
break;
#ifdef ATTESTATION_SUPPORT_RSA_UNSEAL
case CMD_BACKGROUND_HANDLER_ACTION_AUX_KEY_GEN:
status =
aux_attestation_generate_key (*((struct aux_attestation**) context->event_buffer));
debug_log_create_entry ((status ==
0) ? DEBUG_LOG_SEVERITY_INFO : DEBUG_LOG_SEVERITY_ERROR,
DEBUG_LOG_COMPONENT_CMD_INTERFACE, CMD_LOGGING_AUX_KEY, status, 0);
break;
#endif
case CMD_BACKGROUND_HANDLER_ACTION_REBOOT_DEVICE:
/* Just inform the event task executing this handler that a reset is required. The task
* will execute the warm reset. */
*reset = true;
break;
default:
debug_log_create_entry (DEBUG_LOG_SEVERITY_WARNING, DEBUG_LOG_COMPONENT_CMD_INTERFACE,
CMD_LOGGING_NOTIFICATION_ERROR, context->action, 0);
#ifdef CMD_ENABLE_UNSEAL
if (cmd->state->attestation_status == ATTESTATION_CMD_STATUS_RUNNING) {
op_status = &cmd->state->attestation_status;
status = CMD_BACKGROUND_STATUS (ATTESTATION_CMD_STATUS_INTERNAL_ERROR, status);
}
#endif
#ifdef CMD_ENABLE_RESET_CONFIG
if (cmd->state->config_status == CONFIG_RESET_STATUS_STARTING) {
op_status = &cmd->state->config_status;
status = CMD_BACKGROUND_STATUS (CONFIG_RESET_STATUS_INTERNAL_ERROR, status);
}
#endif
if (cmd->state->cert_state == RIOT_CERT_STATE_VALIDATING) {
op_status = &cmd->state->cert_state;
status = CMD_BACKGROUND_STATUS (RIOT_CERT_STATE_CHAIN_INVALID, status);
}
break;
}
cmd_background_handler_set_status (cmd, op_status, status);
}