static int pcr_get_measurement_data_internal()

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