mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-11 07:24:46 +00:00
tpm: add wrapper and helper APIs for PCR allocate
Add PCR allocate wrapper APIs for using in tcg2 protocol. The wrapper proceeds a PCR allocate command, followed by a shutdown command. A system boot is required after two commands since TPM device needs a HW reset to activate the new algorithms config. Also, a helper function is included to determine the new bank mask for PCR allocation by combining the status of current active, supported and eventlog bank masks. A new kconfig is created. PCR allocate and system reboot only happens when the kconfig is selected, otherwise just exit with errors. Signed-off-by: Raymond Mao <raymond.mao@linaro.org> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
parent
9d2bc92ba7
commit
b6228b2e78
3 changed files with 154 additions and 0 deletions
|
@ -703,6 +703,18 @@ u32 tpm2_report_state(struct udevice *dev, uint vendor_cmd, uint vendor_subcmd,
|
|||
u32 tpm2_enable_nvcommits(struct udevice *dev, uint vendor_cmd,
|
||||
uint vendor_subcmd);
|
||||
|
||||
/**
|
||||
* tpm2_scan_masks - Scan the bitmask of algorithms based on the
|
||||
* active/supported banks and the one from eventlog.
|
||||
*
|
||||
* @dev TPM device
|
||||
* @log_active Active algorithm bitmask
|
||||
* @mask Bitmask to set
|
||||
*
|
||||
* Return: zero on success, negative errno otherwise
|
||||
*/
|
||||
int tpm2_scan_masks(struct udevice *dev, u32 log_active, u32 *mask);
|
||||
|
||||
/**
|
||||
* tpm2_pcr_config_algo() - Allocate the active PCRs. Requires reboot
|
||||
*
|
||||
|
@ -730,6 +742,15 @@ u32 tpm2_pcr_config_algo(struct udevice *dev, u32 algo_mask,
|
|||
u32 tpm2_send_pcr_allocate(struct udevice *dev, const char *pw,
|
||||
const ssize_t pw_sz, struct tpml_pcr_selection *pcr,
|
||||
u32 pcr_len);
|
||||
/**
|
||||
* tpm2_activate_banks() - Activate PCR banks
|
||||
*
|
||||
* @param dev TPM device
|
||||
* @log_active Bitmask of eventlog algorithms
|
||||
*
|
||||
* Return: code of the operation
|
||||
*/
|
||||
int tpm2_activate_banks(struct udevice *dev, u32 log_active);
|
||||
|
||||
/**
|
||||
* tpm2_auto_start() - start up the TPM and perform selftests.
|
||||
|
|
12
lib/Kconfig
12
lib/Kconfig
|
@ -514,6 +514,18 @@ config VPL_TPM
|
|||
for the low-level TPM interface, but only one TPM is supported at
|
||||
a time by the TPM library.
|
||||
|
||||
config TPM_PCR_ALLOCATE
|
||||
bool "Re-configurate TPM algorithms in run-time (PCR allocate)"
|
||||
depends on TPM_V2 && (MEASURED_BOOT || EFI_TCG2_PROTOCOL)
|
||||
help
|
||||
This enables a detection for the dismatches of algorithms among TPM
|
||||
device, eventlog from previous boot stage and U-Boot support.
|
||||
A PCR allocate command will be sent to reconfigurate the TPM device
|
||||
in run-time to make sure algorithms in TPM device, eventlog and
|
||||
U-Boot are aligned with each other.
|
||||
A system reboot will be proceeded after then to activate the new
|
||||
algorithms.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "Android Verified Boot"
|
||||
|
|
121
lib/tpm-v2.c
121
lib/tpm-v2.c
|
@ -44,6 +44,127 @@ static int tpm2_update_active_banks(struct udevice *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void tpm2_print_selected_algorithm_name(u32 selected)
|
||||
{
|
||||
size_t i;
|
||||
const char *str;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hash_algo_list); i++) {
|
||||
const struct digest_info *algo = &hash_algo_list[i];
|
||||
|
||||
if (!(selected & algo->hash_mask))
|
||||
continue;
|
||||
|
||||
str = tpm2_algorithm_name(algo->hash_alg);
|
||||
if (str)
|
||||
log_info("%s\n", str);
|
||||
}
|
||||
}
|
||||
|
||||
int tpm2_scan_masks(struct udevice *dev, u32 log_active, u32 *mask)
|
||||
{
|
||||
struct tpml_pcr_selection pcrs;
|
||||
u32 active = 0;
|
||||
u32 supported = 0;
|
||||
int rc, i;
|
||||
|
||||
*mask = 0;
|
||||
|
||||
rc = tpm2_get_pcr_info(dev, &pcrs);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < pcrs.count; i++) {
|
||||
struct tpms_pcr_selection *sel = &pcrs.selection[i];
|
||||
size_t j;
|
||||
u32 hash_mask = 0;
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(hash_algo_list); j++) {
|
||||
if (hash_algo_list[j].hash_alg == sel->hash)
|
||||
hash_mask = hash_algo_list[j].hash_mask;
|
||||
}
|
||||
|
||||
if (tpm2_algorithm_supported(sel->hash))
|
||||
supported |= hash_mask;
|
||||
|
||||
if (tpm2_is_active_bank(sel))
|
||||
active |= hash_mask;
|
||||
}
|
||||
|
||||
/* All eventlog algorithm(s) must be supported */
|
||||
if (log_active & ~supported) {
|
||||
log_err("EventLog contains U-Boot unsupported algorithm(s)\n");
|
||||
tpm2_print_selected_algorithm_name(log_active & ~supported);
|
||||
rc = -1;
|
||||
}
|
||||
if (log_active && active & ~log_active) {
|
||||
log_warning("TPM active algorithm(s) not exist in eventlog\n");
|
||||
tpm2_print_selected_algorithm_name(active & ~log_active);
|
||||
*mask = log_active;
|
||||
}
|
||||
|
||||
/* Any active algorithm(s) which are not supported must be removed */
|
||||
if (active & ~supported) {
|
||||
log_warning("TPM active algorithm(s) unsupported by u-boot\n");
|
||||
tpm2_print_selected_algorithm_name(active & ~supported);
|
||||
if (*mask)
|
||||
*mask = active & supported & *mask;
|
||||
else
|
||||
*mask = active & supported;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int tpm2_pcr_allocate(struct udevice *dev, u32 algo_mask)
|
||||
{
|
||||
struct tpml_pcr_selection pcr = { 0 };
|
||||
u32 pcr_len = 0;
|
||||
int rc;
|
||||
|
||||
rc = tpm2_get_pcr_info(dev, &pcr);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = tpm2_pcr_config_algo(dev, algo_mask, &pcr, &pcr_len);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Assume no password */
|
||||
rc = tpm2_send_pcr_allocate(dev, NULL, 0, &pcr, pcr_len);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Send TPM2_Shutdown, assume mode = TPM2_SU_CLEAR */
|
||||
return tpm2_startup(dev, false, TPM2_SU_CLEAR);
|
||||
}
|
||||
|
||||
int tpm2_activate_banks(struct udevice *dev, u32 log_active)
|
||||
{
|
||||
u32 algo_mask = 0;
|
||||
int rc;
|
||||
|
||||
rc = tpm2_scan_masks(dev, log_active, &algo_mask);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (algo_mask) {
|
||||
if (!IS_ENABLED(CONFIG_TPM_PCR_ALLOCATE))
|
||||
return -1;
|
||||
|
||||
rc = tpm2_pcr_allocate(dev, algo_mask);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
log_info("PCR allocate done, shutdown TPM and reboot\n");
|
||||
do_reset(NULL, 0, 0, NULL);
|
||||
log_err("reset does not work!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 tpm2_startup(struct udevice *dev, bool bon, enum tpm2_startup_types mode)
|
||||
{
|
||||
int op = bon ? TPM2_CC_STARTUP : TPM2_CC_SHUTDOWN;
|
||||
|
|
Loading…
Add table
Reference in a new issue