int attestation_requester_attest_device()

in core/attestation/attestation_requester.c [3269:3394]


int attestation_requester_attest_device (const struct attestation_requester *attestation,
	uint8_t eid)
{
	struct cfm_component_device component_device;
	const struct cfm *active_cfm;
	uint32_t component_id;
	enum cfm_attestation_type attestation_protocol;
	int device_addr;
	int device_state;
	int status;

	if (attestation == NULL) {
		return ATTESTATION_INVALID_ARGUMENT;
	}

	if (attestation->state->get_routing_table) {
		return ATTESTATION_REFRESH_ROUTING_TABLE;
	}

	memset (&attestation->state->txn, 0, sizeof (struct attestation_requester_transaction_state));

	device_addr = device_manager_get_device_addr_by_eid (attestation->device_mgr, eid);
	if (ROT_IS_ERROR (device_addr)) {
		return device_addr;
	}

	status = device_manager_get_component_id (attestation->device_mgr, eid, &component_id);
	if (status != 0) {
		return status;
	}

	active_cfm = attestation->cfm_manager->get_active_cfm (attestation->cfm_manager);
	if (active_cfm == NULL) {
		status = device_manager_update_device_state_by_eid (attestation->device_mgr, eid,
			DEVICE_MANAGER_ATTESTATION_INVALID_CFM);
		if (status != 0) {
			return status;
		}

		return ATTESTATION_NO_CFM;
	}

	status = active_cfm->get_component_device (active_cfm, component_id, &component_device);
	if (status != 0) {
		device_manager_update_device_state_by_eid (attestation->device_mgr, eid,
			DEVICE_MANAGER_ATTESTATION_INVALID_CFM);

		goto free_cfm;
	}

	attestation->state->txn.slot_num = component_device.cert_slot;
	attestation->state->txn.transcript_hash_type = component_device.transcript_hash_type;
	attestation->state->txn.measurement_hash_type = component_device.measurement_hash_type;

	attestation_protocol = component_device.attestation_protocol;

	active_cfm->free_component_device (active_cfm, &component_device);

	/* update previous attestation state in device manager attestation event */
	device_manager_update_attestation_summary_prev_state_by_eid (attestation->device_mgr, eid);

	device_state = device_manager_get_device_state_by_eid (attestation->device_mgr, eid);

	if (!(device_state == DEVICE_MANAGER_AUTHENTICATED) ||
		(device_state == DEVICE_MANAGER_AUTHENTICATED_WITHOUT_CERTS)) {
		status = device_manager_update_device_state_by_eid (attestation->device_mgr, eid,
			DEVICE_MANAGER_READY_FOR_ATTESTATION);
		if (status != 0) {
			goto free_cfm;
		}
	}

	switch (attestation_protocol) {
#ifdef ATTESTATION_SUPPORT_CERBERUS_CHALLENGE
		case CFM_ATTESTATION_CERBERUS_PROTOCOL:
			status = attestation_requester_attest_device_cerberus_protocol (attestation, eid,
				device_addr, active_cfm, component_id);

			break;
#endif

#ifdef ATTESTATION_SUPPORT_SPDM
		case CFM_ATTESTATION_DMTF_SPDM:
			if (attestation->secondary_hash == NULL) {
				status = ATTESTATION_UNSUPPORTED_OPERATION;
			}
			else {
				status = attestation_requester_attest_device_spdm (attestation, eid, device_addr,
					active_cfm, component_id);
			}

			break;
#endif

		default:
			status = ATTESTATION_UNSUPPORTED_PROTOCOL;
	}

free_cfm:
	attestation->cfm_manager->free_cfm (attestation->cfm_manager, active_cfm);

	if (status == 0) {
		if (attestation_protocol == CFM_ATTESTATION_DMTF_SPDM) {
			device_manager_update_device_state_by_eid (attestation->device_mgr, eid,
				attestation->state->txn.cert_supported ?
					DEVICE_MANAGER_AUTHENTICATED : DEVICE_MANAGER_AUTHENTICATED_WITHOUT_CERTS);
		}
		else {
			device_manager_update_device_state_by_eid (attestation->device_mgr, eid,
				DEVICE_MANAGER_AUTHENTICATED);
		}
	}
	else {
		device_state = device_manager_get_device_state_by_eid (attestation->device_mgr, eid);

		if ((device_state == DEVICE_MANAGER_NEVER_ATTESTED) ||
			(device_state == DEVICE_MANAGER_READY_FOR_ATTESTATION)) {
			device_manager_update_device_state_by_eid (attestation->device_mgr, eid,
				DEVICE_MANAGER_ATTESTATION_FAILED);
		}
	}

	device_manager_update_attestation_summary_event_counters_by_eid (attestation->device_mgr, eid);

	return status;
}