security/tpm/tss/tcg-2.0: Add multi digits support to tlcl_extend()
To support multi digists the tlcl_extend() for TPM2 expects TPML_DIGEST_VALUE pointer as input argument. BUG=N/A TEST=Build binary and verified logging on Facebook FBG-1701 Change-Id: I8d86c41c23e4e93a84e0527d7cddcfd30d5d8394 Signed-off-by: Frans Hendriks <fhendriks@eltan.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/33252 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Lance Zhao <lance.zhao@gmail.com>
This commit is contained in:
parent
563b8694d2
commit
fdb9805d68
|
@ -4,6 +4,7 @@
|
||||||
* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
|
||||||
* Copyright 2017 Facebook Inc.
|
* Copyright 2017 Facebook Inc.
|
||||||
* Copyright 2018 Siemens AG
|
* Copyright 2018 Siemens AG
|
||||||
|
* Copyright 2019 Eltan B.V.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
#include <security/tpm/tspi.h>
|
#include <security/tpm/tspi.h>
|
||||||
#include <security/tpm/tss.h>
|
#include <security/tpm/tss.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#if CONFIG(VBOOT)
|
#if CONFIG(VBOOT)
|
||||||
#include <vb2_api.h>
|
#include <vb2_api.h>
|
||||||
#include <vb2_sha.h>
|
#include <vb2_sha.h>
|
||||||
|
@ -209,7 +211,28 @@ uint32_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo,
|
||||||
if (!digest)
|
if (!digest)
|
||||||
return TPM_E_IOERROR;
|
return TPM_E_IOERROR;
|
||||||
|
|
||||||
|
#if CONFIG(TPM2)
|
||||||
|
TPML_DIGEST_VALUES tpml_digests;
|
||||||
|
|
||||||
|
tpml_digests.count = 1;
|
||||||
|
switch (digest_algo) {
|
||||||
|
case VB2_HASH_SHA1:
|
||||||
|
tpml_digests.digests[0].hashAlg = TPM_ALG_SHA1;
|
||||||
|
memcpy(tpml_digests.digests[0].digest.sha1,
|
||||||
|
digest, sizeof(TPMU_HA));
|
||||||
|
break;
|
||||||
|
case VB2_HASH_SHA256:
|
||||||
|
tpml_digests.digests[0].hashAlg = TPM_ALG_SHA256;
|
||||||
|
memcpy(tpml_digests.digests[0].digest.sha256,
|
||||||
|
digest, sizeof(TPMU_HA));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return TPM_E_IOERROR;
|
||||||
|
}
|
||||||
|
result = tlcl_extend(pcr, (uint8_t *)&tpml_digests, NULL);
|
||||||
|
#else
|
||||||
result = tlcl_extend(pcr, digest, NULL);
|
result = tlcl_extend(pcr, digest, NULL);
|
||||||
|
#endif
|
||||||
if (result != TPM_SUCCESS)
|
if (result != TPM_SUCCESS)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
|
|
@ -127,24 +127,68 @@ uint32_t tlcl_assert_physical_presence(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The caller will provide the digest in a 32 byte buffer, let's consider it a
|
* The caller will provide the digest in a 32 byte buffer
|
||||||
* sha256 digest.
|
|
||||||
*/
|
*/
|
||||||
uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
|
uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest,
|
||||||
uint8_t *out_digest)
|
uint8_t *out_digest)
|
||||||
{
|
{
|
||||||
struct tpm2_pcr_extend_cmd pcr_ext_cmd;
|
struct tpm2_pcr_extend_cmd pcr_ext_cmd;
|
||||||
struct tpm2_response *response;
|
struct tpm2_response *response;
|
||||||
|
int i;
|
||||||
|
TPML_DIGEST_VALUES *tpml_digests;
|
||||||
|
|
||||||
pcr_ext_cmd.pcrHandle = HR_PCR + pcr_num;
|
pcr_ext_cmd.pcrHandle = HR_PCR + pcr_num;
|
||||||
pcr_ext_cmd.digests.count = 1;
|
tpml_digests = (TPML_DIGEST_VALUES *)in_digest;
|
||||||
pcr_ext_cmd.digests.digests[0].hashAlg = TPM_ALG_SHA256;
|
pcr_ext_cmd.digests.count = tpml_digests->count;
|
||||||
memcpy(pcr_ext_cmd.digests.digests[0].digest.sha256, in_digest,
|
|
||||||
sizeof(pcr_ext_cmd.digests.digests[0].digest.sha256));
|
for (i = 0; i < tpml_digests->count ; i++) {
|
||||||
|
pcr_ext_cmd.digests.digests[i].hashAlg =
|
||||||
|
tpml_digests->digests[i].hashAlg;
|
||||||
|
switch (tpml_digests->digests[i].hashAlg) {
|
||||||
|
case TPM_ALG_SHA1:
|
||||||
|
memcpy(pcr_ext_cmd.digests.digests[i].digest.sha1,
|
||||||
|
tpml_digests->digests[i].digest.sha1,
|
||||||
|
sizeof(TPMU_HA));
|
||||||
|
break;
|
||||||
|
case TPM_ALG_SHA256:
|
||||||
|
memcpy(pcr_ext_cmd.digests.digests[i].digest.sha256,
|
||||||
|
tpml_digests->digests[i].digest.sha256,
|
||||||
|
sizeof(TPMU_HA));
|
||||||
|
break;
|
||||||
|
case TPM_ALG_SHA384:
|
||||||
|
memcpy(pcr_ext_cmd.digests.digests[i].digest.sha384,
|
||||||
|
tpml_digests->digests[i].digest.sha384,
|
||||||
|
sizeof(TPMU_HA));
|
||||||
|
break;
|
||||||
|
case TPM_ALG_SHA512:
|
||||||
|
memcpy(pcr_ext_cmd.digests.digests[i].digest.sha512,
|
||||||
|
tpml_digests->digests[i].digest.sha512,
|
||||||
|
sizeof(TPMU_HA));
|
||||||
|
break;
|
||||||
|
case TPM_ALG_SM3_256:
|
||||||
|
memcpy(pcr_ext_cmd.digests.digests[i].digest.sm3_256,
|
||||||
|
tpml_digests->digests[i].digest.sm3_256,
|
||||||
|
sizeof(TPMU_HA));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
response = tpm_process_command(TPM2_PCR_Extend, &pcr_ext_cmd);
|
response = tpm_process_command(TPM2_PCR_Extend, &pcr_ext_cmd);
|
||||||
|
|
||||||
printk(BIOS_INFO, "%s: response is %x\n",
|
/*
|
||||||
|
* Check if we are invalidating the pcrs, ignore the error if this is
|
||||||
|
* the case
|
||||||
|
*/
|
||||||
|
if ((tpml_digests->count == 1) &&
|
||||||
|
(tpml_digests->digests[0].hashAlg == TPM_ALG_ERROR) &&
|
||||||
|
response && (response->hdr.tpm_code & ~TPM_RC_N_MASK) ==
|
||||||
|
(TPM_RC_P | TPM_RC_HASH)) {
|
||||||
|
printk(BIOS_SPEW, "%s: TPM_RC_HASH returned this is"
|
||||||
|
" expected\n", __func__);
|
||||||
|
return TPM_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk(BIOS_INFO, "%s: response is 0x%x\n",
|
||||||
__func__, response ? response->hdr.tpm_code : -1);
|
__func__, response ? response->hdr.tpm_code : -1);
|
||||||
if (!response || response->hdr.tpm_code)
|
if (!response || response->hdr.tpm_code)
|
||||||
return TPM_E_IOERROR;
|
return TPM_E_IOERROR;
|
||||||
|
|
|
@ -97,6 +97,12 @@ struct tpm_header {
|
||||||
space is defined by the lower 16 bits. */
|
space is defined by the lower 16 bits. */
|
||||||
#define TPM_CC_VENDOR_BIT_MASK 0x20000000
|
#define TPM_CC_VENDOR_BIT_MASK 0x20000000
|
||||||
|
|
||||||
|
/* Table 15 - TPM_RC Constants (Actions) */
|
||||||
|
#define RC_FMT1 (TPM_RC)(0x080)
|
||||||
|
#define TPM_RC_HASH (TPM_RC)(RC_FMT1 + 0x003)
|
||||||
|
#define TPM_RC_P (TPM_RC)(0x040)
|
||||||
|
#define TPM_RC_N_MASK (TPM_RC)(0xF00)
|
||||||
|
|
||||||
/* Startup values. */
|
/* Startup values. */
|
||||||
#define TPM_SU_CLEAR 0
|
#define TPM_SU_CLEAR 0
|
||||||
#define TPM_SU_STATE 1
|
#define TPM_SU_STATE 1
|
||||||
|
@ -311,12 +317,13 @@ typedef union {
|
||||||
TPM2B b;
|
TPM2B b;
|
||||||
} TPM2B_MAX_NV_BUFFER;
|
} TPM2B_MAX_NV_BUFFER;
|
||||||
|
|
||||||
/*
|
/* Table 66 - TPMU_HA Union */
|
||||||
* This is a union, but as of now we support just one digest - sha256, so
|
|
||||||
* there is just one element.
|
|
||||||
*/
|
|
||||||
typedef union {
|
typedef union {
|
||||||
uint8_t sha256[SHA256_DIGEST_SIZE];
|
uint8_t sha1[SHA1_DIGEST_SIZE];
|
||||||
|
uint8_t sha256[SHA256_DIGEST_SIZE];
|
||||||
|
uint8_t sm3_256[SM3_256_DIGEST_SIZE];
|
||||||
|
uint8_t sha384[SHA384_DIGEST_SIZE];
|
||||||
|
uint8_t sha512[SHA512_DIGEST_SIZE];
|
||||||
} TPMU_HA;
|
} TPMU_HA;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -324,9 +331,10 @@ typedef struct {
|
||||||
TPMU_HA digest;
|
TPMU_HA digest;
|
||||||
} TPMT_HA;
|
} TPMT_HA;
|
||||||
|
|
||||||
|
/* Table 96 -- TPML_DIGEST_VALUES Structure <I/O> */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
TPMT_HA digests[1]; /* Limit max number of hashes to 1. */
|
TPMT_HA digests[HASH_COUNT];
|
||||||
} TPML_DIGEST_VALUES;
|
} TPML_DIGEST_VALUES;
|
||||||
|
|
||||||
struct nv_read_response {
|
struct nv_read_response {
|
||||||
|
|
Loading…
Reference in New Issue