void cmd_background_handler_execute()

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);
}