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