mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-26 15:28:50 +00:00
tpm: Untangle tpm2_get_pcr_info()
This function was used on measured boot to retrieve the number of active PCR banks and was designed to work with the TCG protocols. Since we now have the need to retrieve the active PCRs outside the measured boot context -- e.g use the in the command line, decouple the function. Create one that will only adheres to TCG TSS2.0 [0] specification called tpm2_get_pcr_info() which can be used by the TPM2.0 APIs and a new one that is called from the measured boot context called tcg2_get_pcr_info() [0] https://trustedcomputinggroup.org/wp-content/uploads/TSS_Overview_Common_Structures_Version-0.9_Revision-03_Review_030918.pdf Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
parent
fed9c11c3b
commit
cba3fa9024
5 changed files with 86 additions and 56 deletions
|
@ -522,14 +522,11 @@ u32 tpm2_get_capability(struct udevice *dev, u32 capability, u32 property,
|
||||||
* tpm2_get_pcr_info() - get the supported, active PCRs and number of banks
|
* tpm2_get_pcr_info() - get the supported, active PCRs and number of banks
|
||||||
*
|
*
|
||||||
* @dev: TPM device
|
* @dev: TPM device
|
||||||
* @supported_pcr: bitmask with the algorithms supported
|
* @pcrs: struct tpml_pcr_selection of available PCRs
|
||||||
* @active_pcr: bitmask with the active algorithms
|
|
||||||
* @pcr_banks: number of PCR banks
|
|
||||||
*
|
*
|
||||||
* @return 0 on success, code of operation or negative errno on failure
|
* @return 0 on success, code of operation or negative errno on failure
|
||||||
*/
|
*/
|
||||||
int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
|
int tpm2_get_pcr_info(struct udevice *dev, struct tpml_pcr_selection *pcrs);
|
||||||
u32 *pcr_banks);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Issue a TPM2_DictionaryAttackLockReset command.
|
* Issue a TPM2_DictionaryAttackLockReset command.
|
||||||
|
@ -715,4 +712,13 @@ enum tpm2_algorithms tpm2_name_to_algorithm(const char *name);
|
||||||
*/
|
*/
|
||||||
const char *tpm2_algorithm_name(enum tpm2_algorithms);
|
const char *tpm2_algorithm_name(enum tpm2_algorithms);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tpm2_is_active_pcr() - check the pcr_select. If at least one of the PCRs
|
||||||
|
* supports the algorithm add it on the active ones
|
||||||
|
*
|
||||||
|
* @selection: PCR selection structure
|
||||||
|
* Return: True if the algorithm is active
|
||||||
|
*/
|
||||||
|
bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection);
|
||||||
|
|
||||||
#endif /* __TPM_V2_H */
|
#endif /* __TPM_V2_H */
|
||||||
|
|
|
@ -93,6 +93,19 @@ struct tcg_pcr_event {
|
||||||
u8 event[];
|
u8 event[];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tcg2_get_pcr_info() - get the supported, active PCRs and number of banks
|
||||||
|
*
|
||||||
|
* @dev: TPM device
|
||||||
|
* @supported_pcr: bitmask with the algorithms supported
|
||||||
|
* @active_pcr: bitmask with the active algorithms
|
||||||
|
* @pcr_banks: number of PCR banks
|
||||||
|
*
|
||||||
|
* @return 0 on success, code of operation or negative errno on failure
|
||||||
|
*/
|
||||||
|
int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
|
||||||
|
u32 *pcr_banks);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crypto Agile Log Entry Format
|
* Crypto Agile Log Entry Format
|
||||||
*
|
*
|
||||||
|
|
|
@ -276,7 +276,7 @@ efi_tcg2_get_capability(struct efi_tcg2_protocol *this,
|
||||||
/* Supported and active PCRs */
|
/* Supported and active PCRs */
|
||||||
capability->hash_algorithm_bitmap = 0;
|
capability->hash_algorithm_bitmap = 0;
|
||||||
capability->active_pcr_banks = 0;
|
capability->active_pcr_banks = 0;
|
||||||
ret = tpm2_get_pcr_info(dev, &capability->hash_algorithm_bitmap,
|
ret = tcg2_get_pcr_info(dev, &capability->hash_algorithm_bitmap,
|
||||||
&capability->active_pcr_banks,
|
&capability->active_pcr_banks,
|
||||||
&capability->number_of_pcr_banks);
|
&capability->number_of_pcr_banks);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
|
73
lib/tpm-v2.c
73
lib/tpm-v2.c
|
@ -395,48 +395,26 @@ static int tpm2_get_num_pcr(struct udevice *dev, u32 *num_pcr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection)
|
int tpm2_get_pcr_info(struct udevice *dev, struct tpml_pcr_selection *pcrs)
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* check the pcr_select. If at least one of the PCRs supports the
|
|
||||||
* algorithm add it on the active ones
|
|
||||||
*/
|
|
||||||
for (i = 0; i < selection->size_of_select; i++) {
|
|
||||||
if (selection->pcr_select[i])
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
|
|
||||||
u32 *pcr_banks)
|
|
||||||
{
|
{
|
||||||
u8 response[(sizeof(struct tpms_capability_data) -
|
u8 response[(sizeof(struct tpms_capability_data) -
|
||||||
offsetof(struct tpms_capability_data, data))];
|
offsetof(struct tpms_capability_data, data))];
|
||||||
struct tpml_pcr_selection pcrs;
|
|
||||||
u32 num_pcr;
|
u32 num_pcr;
|
||||||
size_t i;
|
size_t i;
|
||||||
u32 ret;
|
u32 ret;
|
||||||
|
|
||||||
*supported_pcr = 0;
|
|
||||||
*active_pcr = 0;
|
|
||||||
*pcr_banks = 0;
|
|
||||||
memset(response, 0, sizeof(response));
|
|
||||||
ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1);
|
ret = tpm2_get_capability(dev, TPM2_CAP_PCRS, 0, response, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
pcrs.count = get_unaligned_be32(response);
|
pcrs->count = get_unaligned_be32(response);
|
||||||
/*
|
/*
|
||||||
* We only support 5 algorithms for now so check against that
|
* We only support 5 algorithms for now so check against that
|
||||||
* instead of TPM2_NUM_PCR_BANKS
|
* instead of TPM2_NUM_PCR_BANKS
|
||||||
*/
|
*/
|
||||||
if (pcrs.count > ARRAY_SIZE(hash_algo_list) ||
|
if (pcrs->count > ARRAY_SIZE(hash_algo_list) ||
|
||||||
pcrs.count < 1) {
|
pcrs->count < 1) {
|
||||||
printf("%s: too many pcrs: %u\n", __func__, pcrs.count);
|
printf("%s: too many pcrs: %u\n", __func__, pcrs->count);
|
||||||
return -EMSGSIZE;
|
return -EMSGSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,7 +422,7 @@ int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
for (i = 0; i < pcrs.count; i++) {
|
for (i = 0; i < pcrs->count; i++) {
|
||||||
/*
|
/*
|
||||||
* Definition of TPMS_PCR_SELECTION Structure
|
* Definition of TPMS_PCR_SELECTION Structure
|
||||||
* hash: u16
|
* hash: u16
|
||||||
|
@ -464,35 +442,20 @@ int tpm2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
|
||||||
hash_offset + offsetof(struct tpms_pcr_selection,
|
hash_offset + offsetof(struct tpms_pcr_selection,
|
||||||
pcr_select);
|
pcr_select);
|
||||||
|
|
||||||
pcrs.selection[i].hash =
|
pcrs->selection[i].hash =
|
||||||
get_unaligned_be16(response + hash_offset);
|
get_unaligned_be16(response + hash_offset);
|
||||||
pcrs.selection[i].size_of_select =
|
pcrs->selection[i].size_of_select =
|
||||||
__get_unaligned_be(response + size_select_offset);
|
__get_unaligned_be(response + size_select_offset);
|
||||||
if (pcrs.selection[i].size_of_select > TPM2_PCR_SELECT_MAX) {
|
if (pcrs->selection[i].size_of_select > TPM2_PCR_SELECT_MAX) {
|
||||||
printf("%s: pcrs selection too large: %u\n", __func__,
|
printf("%s: pcrs selection too large: %u\n", __func__,
|
||||||
pcrs.selection[i].size_of_select);
|
pcrs->selection[i].size_of_select);
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
/* copy the array of pcr_select */
|
/* copy the array of pcr_select */
|
||||||
memcpy(pcrs.selection[i].pcr_select, response + pcr_select_offset,
|
memcpy(pcrs->selection[i].pcr_select, response + pcr_select_offset,
|
||||||
pcrs.selection[i].size_of_select);
|
pcrs->selection[i].size_of_select);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < pcrs.count; i++) {
|
|
||||||
u32 hash_mask = tcg2_algorithm_to_mask(pcrs.selection[i].hash);
|
|
||||||
|
|
||||||
if (hash_mask) {
|
|
||||||
*supported_pcr |= hash_mask;
|
|
||||||
if (tpm2_is_active_pcr(&pcrs.selection[i]))
|
|
||||||
*active_pcr |= hash_mask;
|
|
||||||
} else {
|
|
||||||
printf("%s: unknown algorithm %x\n", __func__,
|
|
||||||
pcrs.selection[i].hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*pcr_banks = pcrs.count;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,6 +843,18 @@ u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool tpm2_is_active_pcr(struct tpms_pcr_selection *selection)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < selection->size_of_select; i++) {
|
||||||
|
if (selection->pcr_select[i])
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
enum tpm2_algorithms tpm2_name_to_algorithm(const char *name)
|
enum tpm2_algorithms tpm2_name_to_algorithm(const char *name)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
|
@ -20,6 +20,42 @@
|
||||||
#include <linux/unaligned/le_byteshift.h>
|
#include <linux/unaligned/le_byteshift.h>
|
||||||
#include "tpm-utils.h"
|
#include "tpm-utils.h"
|
||||||
|
|
||||||
|
int tcg2_get_pcr_info(struct udevice *dev, u32 *supported_pcr, u32 *active_pcr,
|
||||||
|
u32 *pcr_banks)
|
||||||
|
{
|
||||||
|
u8 response[(sizeof(struct tpms_capability_data) -
|
||||||
|
offsetof(struct tpms_capability_data, data))];
|
||||||
|
struct tpml_pcr_selection pcrs;
|
||||||
|
size_t i;
|
||||||
|
u32 ret;
|
||||||
|
|
||||||
|
*supported_pcr = 0;
|
||||||
|
*active_pcr = 0;
|
||||||
|
*pcr_banks = 0;
|
||||||
|
memset(response, 0, sizeof(response));
|
||||||
|
|
||||||
|
ret = tpm2_get_pcr_info(dev, &pcrs);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
for (i = 0; i < pcrs.count; i++) {
|
||||||
|
u32 hash_mask = tcg2_algorithm_to_mask(pcrs.selection[i].hash);
|
||||||
|
|
||||||
|
if (hash_mask) {
|
||||||
|
*supported_pcr |= hash_mask;
|
||||||
|
if (tpm2_is_active_pcr(&pcrs.selection[i]))
|
||||||
|
*active_pcr |= hash_mask;
|
||||||
|
} else {
|
||||||
|
printf("%s: unknown algorithm %x\n", __func__,
|
||||||
|
pcrs.selection[i].hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*pcr_banks = pcrs.count;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks)
|
int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks)
|
||||||
{
|
{
|
||||||
u32 supported = 0;
|
u32 supported = 0;
|
||||||
|
@ -27,7 +63,7 @@ int tcg2_get_active_pcr_banks(struct udevice *dev, u32 *active_pcr_banks)
|
||||||
u32 active = 0;
|
u32 active = 0;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = tpm2_get_pcr_info(dev, &supported, &active, &pcr_banks);
|
rc = tcg2_get_pcr_info(dev, &supported, &active, &pcr_banks);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue