in core/attestation/pcr.c [857:996]
static int pcr_get_measurement_data_internal (struct pcr_bank *pcr, uint8_t measurement_index,
size_t offset, uint8_t *buffer, size_t length, size_t *total_len)
{
const struct pcr_measured_data *measured_data;
bool include_event;
bool include_version;
size_t total_bytes = 0;
size_t bytes_read;
uint32_t data_len;
int status = 0;
if (measurement_index >= pcr->config.num_measurements) {
return PCR_INVALID_INDEX;
}
*total_len = 0;
measured_data = pcr->measurement_list[measurement_index].measured_data;
if (measured_data == NULL) {
return 0;
}
include_event = pcr->measurement_list[measurement_index].measurement_config &
PCR_MEASUREMENT_FLAG_EVENT;
include_version = pcr->measurement_list[measurement_index].measurement_config &
PCR_MEASUREMENT_FLAG_VERSION;
if (include_event) {
if (offset < 4) {
bytes_read =
pcr_read_measurement_data_bytes (
(uint8_t*) &pcr->measurement_list[measurement_index].event_type, 4, offset, buffer,
length);
offset = 0;
length -= bytes_read;
buffer = buffer + bytes_read;
total_bytes += bytes_read;
}
else {
offset -= 4;
}
*total_len += 4;
}
if (include_version) {
if (offset < 1) {
bytes_read =
pcr_read_measurement_data_bytes (&pcr->measurement_list[measurement_index].version,
1, offset, buffer, length);
offset = 0;
length -= bytes_read;
buffer = buffer + bytes_read;
total_bytes += bytes_read;
}
else {
offset -= 1;
}
*total_len += 1;
}
switch (measured_data->type) {
case PCR_DATA_TYPE_1BYTE:
bytes_read = pcr_read_measurement_data_bytes (&measured_data->data.value_1byte, 1,
offset, buffer, length);
status = bytes_read + total_bytes;
*total_len += 1;
break;
case PCR_DATA_TYPE_2BYTE:
bytes_read =
pcr_read_measurement_data_bytes ((uint8_t*) &measured_data->data.value_2byte, 2,
offset, buffer, length);
status = bytes_read + total_bytes;
*total_len += 2;
break;
case PCR_DATA_TYPE_4BYTE:
bytes_read =
pcr_read_measurement_data_bytes ((uint8_t*) &measured_data->data.value_4byte, 4,
offset, buffer, length);
status = bytes_read + total_bytes;
*total_len += 4;
break;
case PCR_DATA_TYPE_8BYTE:
bytes_read =
pcr_read_measurement_data_bytes ((uint8_t*) &measured_data->data.value_8byte, 8,
offset, buffer, length);
status = bytes_read + total_bytes;
*total_len += 8;
break;
case PCR_DATA_TYPE_MEMORY:
bytes_read = pcr_read_measurement_data_bytes (measured_data->data.memory.buffer,
measured_data->data.memory.length, offset, buffer, length);
status = bytes_read + total_bytes;
*total_len += measured_data->data.memory.length;
break;
case PCR_DATA_TYPE_FLASH: {
const struct flash *flash_device = measured_data->data.flash.flash;
size_t read_addr = measured_data->data.flash.addr + offset;
if (offset > (measured_data->data.flash.length - 1)) {
status = total_bytes;
}
else {
bytes_read = (((measured_data->data.flash.length - offset) > length) ? length :
(measured_data->data.flash.length - offset));
status = flash_device->read (flash_device, read_addr, buffer, bytes_read);
if (status == 0) {
status = bytes_read + total_bytes;
}
}
*total_len += measured_data->data.flash.length;
break;
}
case PCR_DATA_TYPE_CALLBACK:
status = measured_data->data.callback.get_data (measured_data->data.callback.context,
offset, buffer, length, &data_len);
if (!ROT_IS_ERROR (status)) {
status = status + total_bytes;
}
*total_len += data_len;
break;
default:
status = PCR_INVALID_DATA_TYPE;
break;
}
return status;
}