forked from pool/tboot
failed to validate a number of immutable function pointers, which could allow an attacker to bypass the chain of trust and execute arbitrary code (bnc#1068390, CVE-2017-16837). OBS-URL: https://build.opensuse.org/package/show/security/tboot?expand=0&rev=69
1060 lines
41 KiB
Diff
1060 lines
41 KiB
Diff
changeset: 508:521c58e51eb5
|
|
tag: tip
|
|
user: Ning Sun <ning.sun@intel.com>
|
|
date: Mon Nov 13 12:02:07 2017 -0800
|
|
summary: Fix security vulnerabilities rooted in tpm_if structure and g_tpm variable.
|
|
|
|
Index: tboot-1.9.6/tboot/common/cmdline.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/common/cmdline.c
|
|
+++ tboot-1.9.6/tboot/common/cmdline.c
|
|
@@ -503,28 +503,29 @@ bool get_tboot_measure_nv(void)
|
|
void get_tboot_extpol(void)
|
|
{
|
|
const char *extpol = get_option_val(g_tboot_cmdline_options, g_tboot_param_values, "extpol");
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
|
|
if ( extpol == NULL ) {
|
|
- g_tpm->extpol = TB_EXTPOL_FIXED;
|
|
- g_tpm->cur_alg = TB_HALG_SHA256;
|
|
+ tpm->extpol = TB_EXTPOL_FIXED;
|
|
+ tpm->cur_alg = TB_HALG_SHA256;
|
|
return;
|
|
}
|
|
|
|
if ( strcmp(extpol, "agile") == 0 ) {
|
|
- g_tpm->extpol = TB_EXTPOL_AGILE;
|
|
- g_tpm->cur_alg = TB_HALG_SHA256;
|
|
+ tpm->extpol = TB_EXTPOL_AGILE;
|
|
+ tpm->cur_alg = TB_HALG_SHA256;
|
|
} else if ( strcmp(extpol, "embedded") == 0 ) {
|
|
- g_tpm->extpol = TB_EXTPOL_EMBEDDED;
|
|
- g_tpm->cur_alg = TB_HALG_SHA256;
|
|
+ tpm->extpol = TB_EXTPOL_EMBEDDED;
|
|
+ tpm->cur_alg = TB_HALG_SHA256;
|
|
} else if ( strcmp(extpol, "sha256") == 0 ) {
|
|
- g_tpm->extpol = TB_EXTPOL_FIXED;
|
|
- g_tpm->cur_alg = TB_HALG_SHA256;
|
|
+ tpm->extpol = TB_EXTPOL_FIXED;
|
|
+ tpm->cur_alg = TB_HALG_SHA256;
|
|
} else if ( strcmp(extpol, "sha1") == 0 ) {
|
|
- g_tpm->extpol = TB_EXTPOL_FIXED;
|
|
- g_tpm->cur_alg = TB_HALG_SHA1;
|
|
+ tpm->extpol = TB_EXTPOL_FIXED;
|
|
+ tpm->cur_alg = TB_HALG_SHA1;
|
|
} else if ( strcmp(extpol, "sm3") == 0 ) {
|
|
- g_tpm->extpol = TB_EXTPOL_FIXED;
|
|
- g_tpm->cur_alg = TB_HALG_SM3;
|
|
+ tpm->extpol = TB_EXTPOL_FIXED;
|
|
+ tpm->cur_alg = TB_HALG_SM3;
|
|
}
|
|
}
|
|
|
|
Index: tboot-1.9.6/tboot/common/integrity.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/common/integrity.c
|
|
+++ tboot-1.9.6/tboot/common/integrity.c
|
|
@@ -87,8 +87,10 @@ typedef struct {
|
|
|
|
static bool extend_pcrs(void)
|
|
{
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
for ( int i = 0; i < g_pre_k_s3_state.num_vl_entries; i++ ) {
|
|
- if ( !g_tpm->pcr_extend(g_tpm, 2, g_pre_k_s3_state.vl_entries[i].pcr,
|
|
+ if ( !tpm_fp->pcr_extend(tpm, 2, g_pre_k_s3_state.vl_entries[i].pcr,
|
|
&g_pre_k_s3_state.vl_entries[i].hl) )
|
|
return false;
|
|
if ( !evtlog_append(g_pre_k_s3_state.vl_entries[i].pcr,
|
|
@@ -102,13 +104,15 @@ static bool extend_pcrs(void)
|
|
|
|
static void print_pre_k_s3_state(void)
|
|
{
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+
|
|
printk(TBOOT_DETA"pre_k_s3_state:\n");
|
|
printk(TBOOT_DETA"\t vtd_pmr_lo_base: 0x%Lx\n", g_pre_k_s3_state.vtd_pmr_lo_base);
|
|
printk(TBOOT_DETA"\t vtd_pmr_lo_size: 0x%Lx\n", g_pre_k_s3_state.vtd_pmr_lo_size);
|
|
printk(TBOOT_DETA"\t vtd_pmr_hi_base: 0x%Lx\n", g_pre_k_s3_state.vtd_pmr_hi_base);
|
|
printk(TBOOT_DETA"\t vtd_pmr_hi_size: 0x%Lx\n", g_pre_k_s3_state.vtd_pmr_hi_size);
|
|
printk(TBOOT_DETA"\t pol_hash: ");
|
|
- print_hash(&g_pre_k_s3_state.pol_hash, g_tpm->cur_alg);
|
|
+ print_hash(&g_pre_k_s3_state.pol_hash, tpm->cur_alg);
|
|
printk(TBOOT_DETA"\t VL measurements:\n");
|
|
for ( unsigned int i = 0; i < g_pre_k_s3_state.num_vl_entries; i++ ) {
|
|
printk(TBOOT_DETA"\t PCR %d (alg count %d):\n",
|
|
@@ -141,16 +145,18 @@ static bool seal_data(const void *data,
|
|
uint8_t secrets[secrets_size];
|
|
} blob;
|
|
uint32_t err;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
|
|
memset(&blob, 0, sizeof(blob));
|
|
- if ( !hash_buffer(data, data_size, &blob.data_hash, g_tpm->cur_alg) ) {
|
|
+ if ( !hash_buffer(data, data_size, &blob.data_hash, tpm->cur_alg) ) {
|
|
printk(TBOOT_ERR"failed to hash data\n");
|
|
return false;
|
|
}
|
|
|
|
if ( secrets != NULL && secrets_size > 0 ) memcpy(blob.secrets, secrets, secrets_size);
|
|
|
|
- err = g_tpm->seal(g_tpm, 2, sizeof(blob), (const uint8_t *)&blob, sealed_data_size, sealed_data);
|
|
+ err = tpm_fp->seal(tpm, 2, sizeof(blob), (const uint8_t *)&blob, sealed_data_size, sealed_data);
|
|
if ( !err ) printk(TBOOT_WARN"failed to seal data\n");
|
|
|
|
/* since blob might contain secret, clear it */
|
|
@@ -167,9 +173,11 @@ static bool verify_sealed_data(const uin
|
|
uint8_t secrets[secrets_size];
|
|
} blob;
|
|
bool err = true;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
|
|
uint32_t data_size = sizeof(blob);
|
|
- if ( !g_tpm->unseal(g_tpm, g_tpm->cur_loc, sealed_data_size, sealed_data, &data_size, (uint8_t *)&blob) ) {
|
|
+ if ( !tpm_fp->unseal(tpm, tpm->cur_loc, sealed_data_size, sealed_data, &data_size, (uint8_t *)&blob) ) {
|
|
printk(TBOOT_ERR"failed to unseal blob\n");
|
|
return false;
|
|
}
|
|
@@ -181,11 +189,11 @@ static bool verify_sealed_data(const uin
|
|
/* verify that (hash of) current data maches sealed hash */
|
|
tb_hash_t curr_data_hash;
|
|
memset(&curr_data_hash, 0, sizeof(curr_data_hash));
|
|
- if ( !hash_buffer(curr_data, curr_data_size, &curr_data_hash, g_tpm->cur_alg) ) {
|
|
+ if ( !hash_buffer(curr_data, curr_data_size, &curr_data_hash, tpm->cur_alg) ) {
|
|
printk(TBOOT_WARN"failed to hash state data\n");
|
|
goto done;
|
|
}
|
|
- if ( !are_hashes_equal(&blob.data_hash, &curr_data_hash, g_tpm->cur_alg) ) {
|
|
+ if ( !are_hashes_equal(&blob.data_hash, &curr_data_hash, tpm->cur_alg) ) {
|
|
printk(TBOOT_WARN"sealed hash does not match current hash\n");
|
|
goto done;
|
|
}
|
|
@@ -208,9 +216,12 @@ static bool verify_sealed_data(const uin
|
|
*/
|
|
bool seal_pre_k_state(void)
|
|
{
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
+
|
|
/* save hash of current policy into g_pre_k_s3_state */
|
|
memset(&g_pre_k_s3_state.pol_hash, 0, sizeof(g_pre_k_s3_state.pol_hash));
|
|
- if ( !hash_policy(&g_pre_k_s3_state.pol_hash, g_tpm->cur_alg) ) {
|
|
+ if ( !hash_policy(&g_pre_k_s3_state.pol_hash, tpm->cur_alg) ) {
|
|
printk(TBOOT_ERR"failed to hash policy\n");
|
|
goto error;
|
|
}
|
|
@@ -218,9 +229,9 @@ bool seal_pre_k_state(void)
|
|
print_pre_k_s3_state();
|
|
|
|
/* read PCR 17/18, only for tpm1.2 */
|
|
- if ( g_tpm->major == TPM12_VER_MAJOR ) {
|
|
- if ( !g_tpm->pcr_read(g_tpm, 2, 17, &post_launch_pcr17) ||
|
|
- !g_tpm->pcr_read(g_tpm, 2, 18, &post_launch_pcr18) )
|
|
+ if ( tpm->major == TPM12_VER_MAJOR ) {
|
|
+ if ( !tpm_fp->pcr_read(tpm, 2, 17, &post_launch_pcr17) ||
|
|
+ !tpm_fp->pcr_read(tpm, 2, 18, &post_launch_pcr18) )
|
|
goto error;
|
|
}
|
|
|
|
@@ -371,11 +382,13 @@ static bool measure_memory_integrity(vma
|
|
bool verify_integrity(void)
|
|
{
|
|
tpm_pcr_value_t pcr17, pcr18;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
|
|
/* read PCR 17/18, only for tpm1.2 */
|
|
- if ( g_tpm->major == TPM12_VER_MAJOR ) {
|
|
- if ( !g_tpm->pcr_read(g_tpm, 2, 17, &pcr17) ||
|
|
- !g_tpm->pcr_read(g_tpm, 2, 18, &pcr18) )
|
|
+ if ( tpm->major == TPM12_VER_MAJOR ) {
|
|
+ if ( !tpm_fp->pcr_read(tpm, 2, 17, &pcr17) ||
|
|
+ !tpm_fp->pcr_read(tpm, 2, 18, &pcr18) )
|
|
goto error;
|
|
printk(TBOOT_DETA"PCRs before unseal:\n");
|
|
printk(TBOOT_DETA" PCR 17: ");
|
|
@@ -391,7 +404,7 @@ bool verify_integrity(void)
|
|
NULL, 0) )
|
|
goto error;
|
|
|
|
- if ( !g_tpm->verify_creation(g_tpm, sealed_post_k_state_size, sealed_post_k_state) ) {
|
|
+ if ( !tpm_fp->verify_creation(tpm, sealed_post_k_state_size, sealed_post_k_state) ) {
|
|
printk(TBOOT_ERR"extended PCR values don't match creation values in sealed blob.\n");
|
|
goto error;
|
|
}
|
|
@@ -440,7 +453,7 @@ bool verify_integrity(void)
|
|
/* since we can't leave the system without any measurments representing the
|
|
code-about-to-execute, and yet there is no integrity of that code,
|
|
just cap PCR 18 */
|
|
- if ( !g_tpm->cap_pcrs(g_tpm, g_tpm->cur_loc, 18) )
|
|
+ if ( !tpm_fp->cap_pcrs(tpm, tpm->cur_loc, 18) )
|
|
apply_policy(TB_ERR_FATAL);
|
|
return false;
|
|
}
|
|
@@ -452,6 +465,8 @@ bool verify_integrity(void)
|
|
bool seal_post_k_state(void)
|
|
{
|
|
sealed_secrets_t secrets;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
|
|
/* since tboot relies on the module it launches for resource protection,
|
|
that module should have at least one region for itself, otherwise
|
|
@@ -464,7 +479,7 @@ bool seal_post_k_state(void)
|
|
/* calculate the memory integrity hash */
|
|
uint32_t key_size = sizeof(secrets.mac_key);
|
|
/* key must be random and secret even though auth not necessary */
|
|
- if ( !g_tpm->get_random(g_tpm, g_tpm->cur_loc, secrets.mac_key, &key_size) ||key_size != sizeof(secrets.mac_key) ) return false;
|
|
+ if ( !tpm_fp->get_random(tpm, tpm->cur_loc, secrets.mac_key, &key_size) ||key_size != sizeof(secrets.mac_key) ) return false;
|
|
if ( !measure_memory_integrity(&g_post_k_s3_state.kernel_integ, secrets.mac_key) ) return false;
|
|
|
|
/* copy s3_key into secrets to be sealed */
|
|
Index: tboot-1.9.6/tboot/common/loader.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/common/loader.c
|
|
+++ tboot-1.9.6/tboot/common/loader.c
|
|
@@ -1355,15 +1355,15 @@ bool launch_kernel(bool is_measured_laun
|
|
|
|
void *kernel_entry_point;
|
|
uint32_t mb_type = MB_NONE;
|
|
-
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
|
|
if (g_tpm_family != TPM_IF_20_CRB ) {
|
|
- if (!release_locality(g_tpm->cur_loc))
|
|
- printk(TBOOT_ERR"Release TPM FIFO locality %d failed \n", g_tpm->cur_loc);
|
|
+ if (!release_locality(tpm->cur_loc))
|
|
+ printk(TBOOT_ERR"Release TPM FIFO locality %d failed \n", tpm->cur_loc);
|
|
}
|
|
else {
|
|
- if (!tpm_relinquish_locality_crb(g_tpm->cur_loc))
|
|
- printk(TBOOT_ERR"Relinquish TPM CRB locality %d failed \n", g_tpm->cur_loc);
|
|
+ if (!tpm_relinquish_locality_crb(tpm->cur_loc))
|
|
+ printk(TBOOT_ERR"Relinquish TPM CRB locality %d failed \n", tpm->cur_loc);
|
|
if (!tpm_workaround_crb())
|
|
printk(TBOOT_ERR"CRB workaround failed \n");
|
|
}
|
|
Index: tboot-1.9.6/tboot/common/policy.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/common/policy.c
|
|
+++ tboot-1.9.6/tboot/common/policy.c
|
|
@@ -209,13 +209,15 @@ static bool read_policy_from_tpm(uint32_
|
|
unsigned int offset = 0;
|
|
unsigned int data_size = 0;
|
|
uint32_t ret, index_size;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
|
|
if ( policy_index_size == NULL ) {
|
|
printk(TBOOT_ERR"size is NULL\n");
|
|
return false;
|
|
}
|
|
|
|
- ret = g_tpm->get_nvindex_size(g_tpm, g_tpm->cur_loc, index, &index_size);
|
|
+ ret = tpm_fp->get_nvindex_size(tpm, tpm->cur_loc, index, &index_size);
|
|
if ( !ret )
|
|
return false;
|
|
|
|
@@ -233,7 +235,7 @@ static bool read_policy_from_tpm(uint32_
|
|
data_size = (uint32_t)(index_size - offset);
|
|
|
|
/* read! */
|
|
- ret = g_tpm->nv_read(g_tpm, g_tpm->cur_loc, index, offset,
|
|
+ ret = tpm_fp->nv_read(tpm, tpm->cur_loc, index, offset,
|
|
(uint8_t *)policy_index + offset, &data_size);
|
|
if ( !ret || data_size == 0 )
|
|
break;
|
|
@@ -330,10 +332,12 @@ static bool unwrap_lcp_policy(void)
|
|
*/
|
|
tb_error_t set_policy(void)
|
|
{
|
|
+ const struct tpm_if *tpm = get_tpm();
|
|
+
|
|
/* try to read tboot policy from TB_POLICY_INDEX in TPM NV */
|
|
size_t policy_index_size = sizeof(_policy_index_buf);
|
|
printk(TBOOT_INFO"reading Verified Launch Policy from TPM NV...\n");
|
|
- if ( read_policy_from_tpm(g_tpm->tb_policy_index,
|
|
+ if ( read_policy_from_tpm(tpm->tb_policy_index,
|
|
_policy_index_buf, &policy_index_size) ) {
|
|
printk(TBOOT_DETA"\t:%lu bytes read\n", policy_index_size);
|
|
if ( verify_policy((tb_policy_t *)_policy_index_buf,
|
|
@@ -349,7 +353,7 @@ tb_error_t set_policy(void)
|
|
* type is LCP_POLTYPE_LIST (since we could have been give a policy data
|
|
* file even though the policy was not a LIST */
|
|
printk(TBOOT_INFO"reading Launch Control Policy from TPM NV...\n");
|
|
- if ( read_policy_from_tpm(g_tpm->lcp_own_index,
|
|
+ if ( read_policy_from_tpm(tpm->lcp_own_index,
|
|
_policy_index_buf, &policy_index_size) ) {
|
|
printk(TBOOT_DETA"\t:%lu bytes read\n", policy_index_size);
|
|
/* assume lcp policy has been verified by sinit already */
|
|
@@ -411,6 +415,9 @@ static bool hash_module(hash_list_t *hl,
|
|
const char* cmdline, void *base,
|
|
size_t size)
|
|
{
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
+
|
|
if ( hl == NULL ) {
|
|
printk(TBOOT_ERR"Error: input parameter is wrong.\n");
|
|
return false;
|
|
@@ -427,19 +434,19 @@ static bool hash_module(hash_list_t *hl,
|
|
// else
|
|
// cmdline = skip_filename(cmdline);
|
|
|
|
- switch (g_tpm->extpol) {
|
|
+ switch (tpm->extpol) {
|
|
case TB_EXTPOL_FIXED:
|
|
hl->count = 1;
|
|
- hl->entries[0].alg = g_tpm->cur_alg;
|
|
+ hl->entries[0].alg = tpm->cur_alg;
|
|
|
|
if ( !hash_buffer((const unsigned char *)cmdline, strlen(cmdline),
|
|
- &hl->entries[0].hash, g_tpm->cur_alg) )
|
|
+ &hl->entries[0].hash, tpm->cur_alg) )
|
|
return false;
|
|
/* hash image and extend into cmdline hash */
|
|
tb_hash_t img_hash;
|
|
- if ( !hash_buffer(base, size, &img_hash, g_tpm->cur_alg) )
|
|
+ if ( !hash_buffer(base, size, &img_hash, tpm->cur_alg) )
|
|
return false;
|
|
- if ( !extend_hash(&hl->entries[0].hash, &img_hash, g_tpm->cur_alg) )
|
|
+ if ( !extend_hash(&hl->entries[0].hash, &img_hash, tpm->cur_alg) )
|
|
return false;
|
|
|
|
break;
|
|
@@ -447,16 +454,16 @@ static bool hash_module(hash_list_t *hl,
|
|
case TB_EXTPOL_AGILE:
|
|
{
|
|
hash_list_t img_hl, final_hl;
|
|
- if ( !g_tpm->hash(g_tpm, 2, (const unsigned char *)cmdline,
|
|
+ if ( !tpm_fp->hash(tpm, 2, (const unsigned char *)cmdline,
|
|
strlen(cmdline), hl) ) {
|
|
- if ( !g_tpm->hash(g_tpm, 2, base, size, hl) )
|
|
+ if ( !tpm_fp->hash(tpm, 2, base, size, hl) )
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
uint8_t buf[128];
|
|
|
|
- if ( !g_tpm->hash(g_tpm, 2, base, size, &img_hl) )
|
|
+ if ( !tpm_fp->hash(tpm, 2, base, size, &img_hl) )
|
|
return false;
|
|
for (unsigned int i=0; i<hl->count; i++) {
|
|
for (unsigned int j=0; j<img_hl.count; j++) {
|
|
@@ -465,7 +472,7 @@ static bool hash_module(hash_list_t *hl,
|
|
hl->entries[i].alg);
|
|
copy_hash((tb_hash_t *)buf + get_hash_size(hl->entries[i].alg),
|
|
&img_hl.entries[j].hash, hl->entries[i].alg);
|
|
- if ( !g_tpm->hash(g_tpm, 2, buf,
|
|
+ if ( !tpm_fp->hash(tpm, 2, buf,
|
|
2*get_hash_size(hl->entries[i].alg), &final_hl) )
|
|
return false;
|
|
|
|
@@ -489,16 +496,16 @@ static bool hash_module(hash_list_t *hl,
|
|
case TB_EXTPOL_EMBEDDED:
|
|
{
|
|
tb_hash_t img_hash;
|
|
- hl->count = g_tpm->alg_count;
|
|
+ hl->count = tpm->alg_count;
|
|
for (unsigned int i=0; i<hl->count; i++) {
|
|
- hl->entries[i].alg = g_tpm->algs[i];
|
|
+ hl->entries[i].alg = tpm->algs[i];
|
|
if ( !hash_buffer((const unsigned char *)cmdline, strlen(cmdline),
|
|
- &hl->entries[i].hash, g_tpm->algs[i]) )
|
|
+ &hl->entries[i].hash, tpm->algs[i]) )
|
|
return false;
|
|
|
|
- if ( !hash_buffer(base, size, &img_hash, g_tpm->algs[i]) )
|
|
+ if ( !hash_buffer(base, size, &img_hash, tpm->algs[i]) )
|
|
return false;
|
|
- if ( !extend_hash(&hl->entries[i].hash, &img_hash, g_tpm->algs[i]) )
|
|
+ if ( !extend_hash(&hl->entries[i].hash, &img_hash, tpm->algs[i]) )
|
|
return false;
|
|
}
|
|
|
|
@@ -616,6 +623,7 @@ static tb_error_t verify_module(module_t
|
|
void *base = (void *)module->mod_start;
|
|
size_t size = module->mod_end - module->mod_start;
|
|
char *cmdline = get_module_cmd(g_ldr_ctx, module);
|
|
+ const struct tpm_if *tpm = get_tpm();
|
|
|
|
if ( pol_entry != NULL ) {
|
|
/* chunk the command line into 80 byte chunks */
|
|
@@ -653,7 +661,7 @@ static tb_error_t verify_module(module_t
|
|
VL_ENTRIES(NUM_VL_ENTRIES++).hl = hl;
|
|
}
|
|
|
|
- if ( g_tpm->extpol != TB_EXTPOL_FIXED )
|
|
+ if ( tpm->extpol != TB_EXTPOL_FIXED )
|
|
return TB_ERR_NONE;
|
|
|
|
if ( pol_entry != NULL &&
|
|
@@ -671,6 +679,9 @@ static tb_error_t verify_module(module_t
|
|
|
|
static void verify_g_policy(void)
|
|
{
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
+
|
|
/* assumes mbi is valid */
|
|
printk(TBOOT_INFO"verifying policy \n");
|
|
|
|
@@ -682,35 +693,35 @@ static void verify_g_policy(void)
|
|
memcpy(buf, &g_policy->policy_control, sizeof(g_policy->policy_control));
|
|
if ( g_policy->policy_control & TB_POLCTL_EXTEND_PCR17 ) {
|
|
if ( !hash_policy((tb_hash_t *)&buf[sizeof(g_policy->policy_control)],
|
|
- g_tpm->cur_alg) ) {
|
|
+ tpm->cur_alg) ) {
|
|
printk(TBOOT_ERR"policy hash failed\n");
|
|
apply_policy(TB_ERR_MODULE_VERIFICATION_FAILED);
|
|
}
|
|
}
|
|
|
|
- u32 size = get_hash_size(g_tpm->cur_alg) + sizeof(g_policy->policy_control);
|
|
- switch (g_tpm->extpol) {
|
|
+ u32 size = get_hash_size(tpm->cur_alg) + sizeof(g_policy->policy_control);
|
|
+ switch (tpm->extpol) {
|
|
case TB_EXTPOL_FIXED:
|
|
VL_ENTRIES(NUM_VL_ENTRIES).hl.count = 1;
|
|
- VL_ENTRIES(NUM_VL_ENTRIES).hl.entries[0].alg = g_tpm->cur_alg;
|
|
+ VL_ENTRIES(NUM_VL_ENTRIES).hl.entries[0].alg = tpm->cur_alg;
|
|
if ( !hash_buffer(buf, size,
|
|
- &VL_ENTRIES(NUM_VL_ENTRIES).hl.entries[0].hash, g_tpm->cur_alg) )
|
|
+ &VL_ENTRIES(NUM_VL_ENTRIES).hl.entries[0].hash, tpm->cur_alg) )
|
|
apply_policy(TB_ERR_MODULE_VERIFICATION_FAILED);
|
|
|
|
break;
|
|
|
|
case TB_EXTPOL_AGILE:
|
|
- if ( !g_tpm->hash(g_tpm, 2, buf, size, &VL_ENTRIES(NUM_VL_ENTRIES).hl) )
|
|
+ if ( !tpm_fp->hash(tpm, 2, buf, size, &VL_ENTRIES(NUM_VL_ENTRIES).hl) )
|
|
apply_policy(TB_ERR_MODULE_VERIFICATION_FAILED);
|
|
break;
|
|
|
|
case TB_EXTPOL_EMBEDDED:
|
|
{
|
|
- VL_ENTRIES(NUM_VL_ENTRIES).hl.count = g_tpm->alg_count;
|
|
- for (int i=0; i<g_tpm->alg_count; i++) {
|
|
- VL_ENTRIES(NUM_VL_ENTRIES).hl.entries[i].alg = g_tpm->algs[i];
|
|
+ VL_ENTRIES(NUM_VL_ENTRIES).hl.count = tpm->alg_count;
|
|
+ for (int i=0; i<tpm->alg_count; i++) {
|
|
+ VL_ENTRIES(NUM_VL_ENTRIES).hl.entries[i].alg = tpm->algs[i];
|
|
if ( !hash_buffer(buf, size, &VL_ENTRIES(NUM_VL_ENTRIES).hl.entries[i].hash,
|
|
- g_tpm->algs[i]) )
|
|
+ tpm->algs[i]) )
|
|
return;
|
|
}
|
|
|
|
@@ -807,6 +818,8 @@ static tb_error_t verify_nvindex(tb_poli
|
|
size_t nv_size = sizeof(nv_buf);
|
|
tb_hash_t digest;
|
|
uint32_t attribute;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
|
|
if ( pol_entry == NULL )
|
|
return TB_ERR_NV_VERIFICATION_FAILED;
|
|
@@ -814,7 +827,7 @@ static tb_error_t verify_nvindex(tb_poli
|
|
printk(TBOOT_INFO"verifying nv index 0x%08X\n", pol_entry->nv_index);
|
|
|
|
/* check nv attribute */
|
|
- if ( !g_tpm->get_nvindex_permission(g_tpm, 0, pol_entry->nv_index,
|
|
+ if ( !tpm_fp->get_nvindex_permission(tpm, 0, pol_entry->nv_index,
|
|
&attribute) ) {
|
|
printk(TBOOT_ERR"\t :reading nv index permission failed\n");
|
|
return TB_ERR_NV_VERIFICATION_FAILED;
|
|
Index: tboot-1.9.6/tboot/common/tb_error.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/common/tb_error.c
|
|
+++ tboot-1.9.6/tboot/common/tb_error.c
|
|
@@ -135,6 +135,8 @@ void print_tb_error_msg(tb_error_t error
|
|
bool read_tb_error_code(tb_error_t *error)
|
|
{
|
|
uint32_t size = sizeof(tb_error_t);
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
|
|
if ( error == NULL ) {
|
|
printk(TBOOT_ERR"Error: error pointer is zero.\n");
|
|
@@ -144,9 +146,9 @@ bool read_tb_error_code(tb_error_t *erro
|
|
memset(error, 0, size);
|
|
|
|
/* read! */
|
|
- if ( !g_tpm->nv_read(g_tpm, 0, g_tpm->tb_err_index, 0,
|
|
+ if ( !tpm_fp->nv_read(tpm, 0, tpm->tb_err_index, 0,
|
|
(uint8_t *)error, &size) ) {
|
|
- printk(TBOOT_WARN"Error: read TPM error: 0x%x.\n", g_tpm->error);
|
|
+ printk(TBOOT_WARN"Error: read TPM error: 0x%x.\n", tpm->error);
|
|
no_err_idx = true;
|
|
return false;
|
|
}
|
|
@@ -163,12 +165,15 @@ bool read_tb_error_code(tb_error_t *erro
|
|
*/
|
|
bool write_tb_error_code(tb_error_t error)
|
|
{
|
|
- if ( !g_tpm || no_err_idx )
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
+
|
|
+ if ( !tpm || no_err_idx )
|
|
return false;
|
|
|
|
- if ( !g_tpm->nv_write(g_tpm, g_tpm->cur_loc, g_tpm->tb_err_index, 0,
|
|
+ if ( !tpm_fp->nv_write(tpm, tpm->cur_loc, tpm->tb_err_index, 0,
|
|
(uint8_t *)&error, sizeof(tb_error_t)) ) {
|
|
- printk(TBOOT_WARN"Error: write TPM error: 0x%x.\n", g_tpm->error);
|
|
+ printk(TBOOT_WARN"Error: write TPM error: 0x%x.\n", tpm->error);
|
|
no_err_idx = true;
|
|
return false;
|
|
}
|
|
Index: tboot-1.9.6/tboot/common/tboot.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/common/tboot.c
|
|
+++ tboot-1.9.6/tboot/common/tboot.c
|
|
@@ -156,6 +156,8 @@ static void post_launch(void)
|
|
{
|
|
uint64_t base, size;
|
|
tb_error_t err;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
extern tboot_log_t *g_log;
|
|
extern void shutdown_entry(void);
|
|
|
|
@@ -228,7 +230,7 @@ static void post_launch(void)
|
|
/*
|
|
* verify nv indices against policy
|
|
*/
|
|
- if ( (g_tpm->major == TPM12_VER_MAJOR) && get_tboot_measure_nv() )
|
|
+ if ( (tpm->major == TPM12_VER_MAJOR) && get_tboot_measure_nv() )
|
|
verify_all_nvindices();
|
|
|
|
/*
|
|
@@ -238,8 +240,8 @@ static void post_launch(void)
|
|
apply_policy(TB_ERR_S3_INTEGRITY);
|
|
|
|
|
|
- if ( g_tpm->major == TPM20_VER_MAJOR ) {
|
|
- g_tpm->context_save(g_tpm, g_tpm->cur_loc, handle2048, &tpm2_context_saved);
|
|
+ if ( tpm->major == TPM20_VER_MAJOR ) {
|
|
+ tpm_fp->context_save(tpm, tpm->cur_loc, handle2048, &tpm2_context_saved);
|
|
}
|
|
|
|
/*
|
|
@@ -253,7 +255,7 @@ static void post_launch(void)
|
|
_tboot_shared.tboot_base = (uint32_t)&_start;
|
|
_tboot_shared.tboot_size = (uint32_t)&_end - (uint32_t)&_start;
|
|
uint32_t key_size = sizeof(_tboot_shared.s3_key);
|
|
- if ( !g_tpm->get_random(g_tpm, 2, _tboot_shared.s3_key, &key_size) || key_size != sizeof(_tboot_shared.s3_key) )
|
|
+ if ( !tpm_fp->get_random(tpm, 2, _tboot_shared.s3_key, &key_size) || key_size != sizeof(_tboot_shared.s3_key) )
|
|
apply_policy(TB_ERR_S3_INTEGRITY);
|
|
_tboot_shared.num_in_wfs = atomic_read(&ap_wfs_count);
|
|
if ( use_mwait() ) {
|
|
@@ -475,15 +477,15 @@ void begin_launch(void *addr, uint32_t m
|
|
|
|
void s3_launch(void)
|
|
{
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
/* restore backed-up s3 wakeup page */
|
|
restore_saved_s3_wakeup_page();
|
|
-
|
|
- /* load saved tpm2 context for unseal */
|
|
- if ( g_tpm->major == TPM20_VER_MAJOR ) {
|
|
- g_tpm->context_flush(g_tpm, g_tpm->cur_loc, handle2048);
|
|
- g_tpm->context_load(g_tpm, g_tpm->cur_loc, &tpm2_context_saved, &handle2048);
|
|
- }
|
|
-
|
|
+ /* load saved tpm2 context for unseal */
|
|
+ if ( tpm->major == TPM20_VER_MAJOR ) {
|
|
+ tpm_fp->context_flush(tpm, tpm->cur_loc, handle2048);
|
|
+ tpm_fp->context_load(tpm, tpm->cur_loc, &tpm2_context_saved, &handle2048);
|
|
+ }
|
|
|
|
/* remove DMAR table if necessary */
|
|
remove_vtd_dmar_table();
|
|
@@ -560,6 +562,9 @@ static void shutdown_system(uint32_t shu
|
|
|
|
void shutdown(void)
|
|
{
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
+
|
|
/* wait-for-sipi only invoked for APs, so skip all BSP shutdown code */
|
|
if ( _tboot_shared.shutdown_type == TB_SHUTDOWN_WFS ) {
|
|
atomic_inc(&ap_wfs_count);
|
|
@@ -585,24 +590,24 @@ void shutdown(void)
|
|
printk(TBOOT_ERR"Release TPM FIFO locality 0 failed \n");
|
|
if (!release_locality(1))
|
|
printk(TBOOT_ERR"Release TPM FIFO locality 1 failed \n");
|
|
- if (!tpm_wait_cmd_ready(g_tpm->cur_loc))
|
|
- printk(TBOOT_ERR"Request TPM FIFO locality %d failed \n", g_tpm->cur_loc);
|
|
+ if (!tpm_wait_cmd_ready(tpm->cur_loc))
|
|
+ printk(TBOOT_ERR"Request TPM FIFO locality %d failed \n", tpm->cur_loc);
|
|
}
|
|
else {
|
|
if (!tpm_relinquish_locality_crb(0))
|
|
printk(TBOOT_ERR"Release TPM CRB locality 0 failed \n");
|
|
if (!tpm_relinquish_locality_crb(1))
|
|
printk(TBOOT_ERR"Release TPM CRB locality 1 failed \n");
|
|
- if (!tpm_request_locality_crb(g_tpm->cur_loc))
|
|
- printk(TBOOT_ERR"Request TPM CRB locality %d failed \n", g_tpm->cur_loc);
|
|
+ if (!tpm_request_locality_crb(tpm->cur_loc))
|
|
+ printk(TBOOT_ERR"Request TPM CRB locality %d failed \n", tpm->cur_loc);
|
|
}
|
|
|
|
if ( _tboot_shared.shutdown_type == TB_SHUTDOWN_S3 ) {
|
|
/* restore DMAR table if needed */
|
|
restore_vtd_dmar_table();
|
|
- if ( g_tpm->major == TPM20_VER_MAJOR ) {
|
|
- g_tpm->context_flush(g_tpm, g_tpm->cur_loc, handle2048);
|
|
- g_tpm->context_load(g_tpm, g_tpm->cur_loc, &tpm2_context_saved, &handle2048);
|
|
+ if ( tpm->major == TPM20_VER_MAJOR ) {
|
|
+ tpm_fp->context_flush(tpm, tpm->cur_loc, handle2048);
|
|
+ tpm_fp->context_load(tpm, tpm->cur_loc, &tpm2_context_saved, &handle2048);
|
|
}
|
|
|
|
|
|
@@ -624,13 +629,13 @@ void shutdown(void)
|
|
if ( is_launched() ) {
|
|
|
|
/* cap PCRs to ensure no follow-on code can access sealed data */
|
|
- g_tpm->cap_pcrs(g_tpm, g_tpm->cur_loc, -1);
|
|
+ tpm_fp->cap_pcrs(tpm, tpm->cur_loc, -1);
|
|
|
|
/* have TPM save static PCRs (in case VMM/kernel didn't) */
|
|
/* per TCG spec, TPM can invalidate saved state if any other TPM
|
|
operation is performed afterwards--so do this last */
|
|
if ( _tboot_shared.shutdown_type == TB_SHUTDOWN_S3 )
|
|
- g_tpm->save_state(g_tpm, g_tpm->cur_loc);
|
|
+ tpm_fp->save_state(tpm, tpm->cur_loc);
|
|
|
|
/* scrub any secrets by clearing their memory, then flush cache */
|
|
/* we don't have any secrets to scrub, however */
|
|
Index: tboot-1.9.6/tboot/common/tpm.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/common/tpm.c
|
|
+++ tboot-1.9.6/tboot/common/tpm.c
|
|
@@ -45,13 +45,16 @@
|
|
#include <tpm.h>
|
|
#include <sha1.h>
|
|
|
|
-__data struct tpm_if *g_tpm = NULL;
|
|
-u16 tboot_alg_list[] = {TB_HALG_SHA1, TB_HALG_SHA256};
|
|
-
|
|
-
|
|
-
|
|
-
|
|
+__data uint8_t g_tpm_ver = TPM_VER_UNKNOWN;
|
|
+__data struct tpm_if g_tpm = {
|
|
+ .cur_loc = 0,
|
|
+ .timeout.timeout_a = TIMEOUT_A,
|
|
+ .timeout.timeout_b = TIMEOUT_B,
|
|
+ .timeout.timeout_c = TIMEOUT_C,
|
|
+ .timeout.timeout_d = TIMEOUT_D,
|
|
+};
|
|
|
|
+u16 tboot_alg_list[] = {TB_HALG_SHA1, TB_HALG_SHA256};
|
|
|
|
/* Global variables for TPM status register */
|
|
static tpm20_reg_sts_t g_reg_sts, *g_reg_sts_20 = &g_reg_sts;
|
|
@@ -70,15 +73,15 @@ typedef union {
|
|
} tpm_reg_data_crb_t;
|
|
|
|
#define TPM_ACTIVE_LOCALITY_TIME_OUT \
|
|
- (TIMEOUT_UNIT * g_tpm->timeout.timeout_a) /* according to spec */
|
|
+ (TIMEOUT_UNIT *get_tpm()->timeout.timeout_a) /* according to spec */
|
|
#define TPM_CMD_READY_TIME_OUT \
|
|
- (TIMEOUT_UNIT * g_tpm->timeout.timeout_b) /* according to spec */
|
|
+ (TIMEOUT_UNIT *get_tpm()->timeout.timeout_b) /* according to spec */
|
|
#define TPM_CMD_WRITE_TIME_OUT \
|
|
- (TIMEOUT_UNIT * g_tpm->timeout.timeout_d) /* let it long enough */
|
|
+ (TIMEOUT_UNIT *get_tpm()->timeout.timeout_d) /* let it long enough */
|
|
#define TPM_DATA_AVAIL_TIME_OUT \
|
|
- (TIMEOUT_UNIT * g_tpm->timeout.timeout_c) /* let it long enough */
|
|
+ (TIMEOUT_UNIT *get_tpm()->timeout.timeout_c) /* let it long enough */
|
|
#define TPM_RSP_READ_TIME_OUT \
|
|
- (TIMEOUT_UNIT * g_tpm->timeout.timeout_d) /* let it long enough */
|
|
+ (TIMEOUT_UNIT *get_tpm()->timeout.timeout_d) /* let it long enough */
|
|
#define TPM_VALIDATE_LOCALITY_TIME_OUT 0x100
|
|
|
|
#define read_tpm_sts_reg(locality) { \
|
|
@@ -828,6 +831,8 @@ bool tpm_workaround_crb(void)
|
|
|
|
bool tpm_detect(void)
|
|
{
|
|
+ struct tpm_if *tpm;
|
|
+ const struct tpm_if_fp *tpm_fp;
|
|
if (is_tpm_crb()) {
|
|
printk(TBOOT_INFO"TPM: This is Intel PTT, TPM Family 0x%d\n", g_tpm_family);
|
|
if (!txt_is_launched()) {
|
|
@@ -854,14 +859,17 @@ bool tpm_detect(void)
|
|
}
|
|
}
|
|
else {
|
|
- g_tpm = &tpm_12_if; /* Don't leave g_tpm as NULL*/
|
|
+ g_tpm_ver = TPM_VER_12;
|
|
+ tpm = get_tpm(); /* Don't leave tpm and tpm_fp as NULL*/
|
|
+ tpm_fp = get_tpm_fp();
|
|
+
|
|
if ( tpm_validate_locality(0) ) printk(TBOOT_INFO"TPM: FIFO_INF Locality 0 is open\n");
|
|
else {
|
|
printk(TBOOT_ERR"TPM: FIFO_INF Locality 0 is not open\n");
|
|
return false;
|
|
}
|
|
/* determine TPM family from command check */
|
|
- if ( g_tpm->check() ) {
|
|
+ if ( tpm_fp->check() ) {
|
|
g_tpm_family = TPM_IF_12;
|
|
printk(TBOOT_INFO"TPM: discrete TPM1.2 Family 0x%d\n", g_tpm_family);
|
|
}
|
|
@@ -871,21 +879,12 @@ bool tpm_detect(void)
|
|
}
|
|
}
|
|
|
|
- if (g_tpm_family == TPM_IF_12) g_tpm = &tpm_12_if;
|
|
- if (g_tpm_family == TPM_IF_20_FIFO) g_tpm = &tpm_20_if;
|
|
- if (g_tpm_family == TPM_IF_20_CRB) g_tpm = &tpm_20_if;
|
|
-
|
|
- /* if (!txt_is_launched())
|
|
- g_tpm->cur_loc = 0;
|
|
- else
|
|
- g_tpm->cur_loc = 2;
|
|
-
|
|
- g_tpm->timeout.timeout_a = TIMEOUT_A;
|
|
- g_tpm->timeout.timeout_b = TIMEOUT_B;
|
|
- g_tpm->timeout.timeout_c = TIMEOUT_C;
|
|
- g_tpm->timeout.timeout_d = TIMEOUT_D;
|
|
-*/
|
|
- return g_tpm->init(g_tpm);
|
|
+ if (g_tpm_family == TPM_IF_12) g_tpm_ver = TPM_VER_12;
|
|
+ if (g_tpm_family == TPM_IF_20_FIFO) g_tpm_ver = TPM_VER_20;
|
|
+ if (g_tpm_family == TPM_IF_20_CRB) g_tpm_ver = TPM_VER_20;
|
|
+
|
|
+ tpm_fp = get_tpm_fp();
|
|
+ return tpm_fp->init(tpm);
|
|
}
|
|
|
|
void tpm_print(struct tpm_if *ti)
|
|
@@ -897,8 +896,23 @@ void tpm_print(struct tpm_if *ti)
|
|
printk(TBOOT_INFO"\t extend policy: %d\n", ti->extpol);
|
|
printk(TBOOT_INFO"\t current alg id: 0x%x\n", ti->cur_alg);
|
|
printk(TBOOT_INFO"\t timeout values: A: %u, B: %u, C: %u, D: %u\n", ti->timeout.timeout_a, ti->timeout.timeout_b, ti->timeout.timeout_c, ti->timeout.timeout_d);
|
|
+}
|
|
+
|
|
+struct tpm_if *get_tpm(void)
|
|
+{
|
|
+ return &g_tpm;
|
|
}
|
|
|
|
+const struct tpm_if_fp *get_tpm_fp(void)
|
|
+{
|
|
+ if ( g_tpm_ver == TPM_VER_12 )
|
|
+ return &tpm_12_if_fp;
|
|
+ else if ( g_tpm_ver == TPM_VER_20)
|
|
+ return &tpm_20_if_fp;
|
|
+
|
|
+ return NULL;
|
|
+
|
|
+}
|
|
/*
|
|
* Local variables:
|
|
* mode: C
|
|
Index: tboot-1.9.6/tboot/common/tpm_12.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/common/tpm_12.c
|
|
+++ tboot-1.9.6/tboot/common/tpm_12.c
|
|
@@ -1914,8 +1914,7 @@ static bool tpm12_check(void)
|
|
|
|
return ( ret == TPM_BAD_ORDINAL );
|
|
}
|
|
-
|
|
-struct tpm_if tpm_12_if = {
|
|
+const struct tpm_if_fp tpm_12_if_fp = {
|
|
.init = tpm12_init,
|
|
.pcr_read = tpm12_pcr_read,
|
|
.pcr_extend = tpm12_pcr_extend,
|
|
@@ -1931,11 +1930,6 @@ struct tpm_if tpm_12_if = {
|
|
.save_state = tpm12_save_state,
|
|
.cap_pcrs = tpm12_cap_pcrs,
|
|
.check = tpm12_check,
|
|
- .cur_loc = 0,
|
|
- .timeout.timeout_a = TIMEOUT_A,
|
|
- .timeout.timeout_b = TIMEOUT_B,
|
|
- .timeout.timeout_c = TIMEOUT_C,
|
|
- .timeout.timeout_d = TIMEOUT_D,
|
|
};
|
|
|
|
/*
|
|
Index: tboot-1.9.6/tboot/common/tpm_20.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/common/tpm_20.c
|
|
+++ tboot-1.9.6/tboot/common/tpm_20.c
|
|
@@ -2609,7 +2609,7 @@ out:
|
|
return true;
|
|
}
|
|
|
|
-struct tpm_if tpm_20_if = {
|
|
+const struct tpm_if_fp tpm_20_if_fp = {
|
|
.init = tpm20_init,
|
|
.pcr_read = tpm20_pcr_read,
|
|
.pcr_extend = tpm20_pcr_extend,
|
|
Index: tboot-1.9.6/tboot/include/tpm.h
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/include/tpm.h
|
|
+++ tboot-1.9.6/tboot/include/tpm.h
|
|
@@ -48,6 +48,10 @@
|
|
#define TPM_IF_20_FIFO 1
|
|
#define TPM_IF_20_CRB 2
|
|
|
|
+#define TPM_VER_UNKNOWN 0
|
|
+#define TPM_VER_12 1
|
|
+#define TPM_VER_20 2
|
|
+
|
|
#define TPM_INTERFACE_ID_FIFO_20 0x0
|
|
#define TPM_INTERFACE_ID_CRB 0x1
|
|
#define TPM_INTERFACE_ID_FIFO_13 0xF
|
|
@@ -413,6 +417,7 @@ extern tpm_pcr_value_t post_launch_pcr17
|
|
extern tpm_pcr_value_t post_launch_pcr18;
|
|
|
|
struct tpm_if;
|
|
+struct tpm_if_fp;
|
|
|
|
struct tpm_if {
|
|
#define TPM12_VER_MAJOR 1
|
|
@@ -447,6 +452,9 @@ struct tpm_if {
|
|
u32 tb_policy_index;
|
|
u32 tb_err_index;
|
|
u32 sgx_svn_index;
|
|
+};
|
|
+
|
|
+struct tpm_if_fp {
|
|
|
|
bool (*init)(struct tpm_if *ti);
|
|
|
|
@@ -483,9 +491,10 @@ struct tpm_if {
|
|
bool (*check)(void);
|
|
};
|
|
|
|
-extern struct tpm_if tpm_12_if;
|
|
-extern struct tpm_if tpm_20_if;
|
|
-extern struct tpm_if *g_tpm;
|
|
+extern struct tpm_if_data tpm_if_data;
|
|
+extern const struct tpm_if_fp tpm_12_if_fp;
|
|
+extern const struct tpm_if_fp tpm_20_if_fp;
|
|
+extern uint8_t g_tpm_ver;
|
|
extern uint8_t g_tpm_family;
|
|
|
|
extern bool tpm_validate_locality(uint32_t locality);
|
|
@@ -501,6 +510,8 @@ extern bool tpm_request_locality_crb(uin
|
|
extern bool tpm_relinquish_locality_crb(uint32_t locality);
|
|
extern bool txt_is_launched(void);
|
|
extern bool tpm_workaround_crb(void);
|
|
+extern struct tpm_if *get_tpm(void);
|
|
+extern const struct tpm_if_fp *get_tpm_fp(void);
|
|
|
|
|
|
//#define TPM_UNIT_TEST 1
|
|
Index: tboot-1.9.6/tboot/txt/acmod.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/txt/acmod.c
|
|
+++ tboot-1.9.6/tboot/txt/acmod.c
|
|
@@ -834,6 +834,8 @@ bool verify_racm(const acm_hdr_t *acm_hd
|
|
#ifndef IS_INCLUDED /* defined in utils/acminfo.c */
|
|
void verify_IA32_se_svn_status(const acm_hdr_t *acm_hdr)
|
|
{
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ const struct tpm_if_fp *tpm_fp = get_tpm_fp();
|
|
|
|
printk(TBOOT_INFO"SGX:verify_IA32_se_svn_status is called\n");
|
|
|
|
@@ -847,8 +849,8 @@ void verify_IA32_se_svn_status(const acm
|
|
|
|
if (((rdmsr(MSR_IA32_SE_SVN_STATUS)>>16) & 0xff) != acm_hdr->se_svn) {
|
|
printk(TBOOT_INFO"se_svn is not equal to ACM se_svn\n");
|
|
- if (!g_tpm->nv_write(g_tpm, 0, g_tpm->sgx_svn_index, 0, (uint8_t *)&(acm_hdr->se_svn), 1))
|
|
- printk(TBOOT_ERR"Write sgx_svn_index 0x%x failed. \n", g_tpm->sgx_svn_index);
|
|
+ if (!tpm_fp->nv_write(tpm, 0, tpm->sgx_svn_index, 0, (uint8_t *)&(acm_hdr->se_svn), 1))
|
|
+ printk(TBOOT_ERR"Write sgx_svn_index 0x%x failed. \n", tpm->sgx_svn_index);
|
|
else
|
|
printk(TBOOT_INFO"Write sgx_svn_index with 0x%x successful.\n", acm_hdr->se_svn);
|
|
|
|
Index: tboot-1.9.6/tboot/txt/heap.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/txt/heap.c
|
|
+++ tboot-1.9.6/tboot/txt/heap.c
|
|
@@ -709,30 +709,31 @@ uint64_t calc_os_sinit_data_size(uint32_
|
|
2 * sizeof(heap_ext_data_element_t) +
|
|
sizeof(heap_event_log_ptr_elt_t)
|
|
};
|
|
- txt_caps_t sinit_caps;
|
|
+ txt_caps_t sinit_caps;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
|
|
- if ( g_tpm->major == TPM20_VER_MAJOR ) {
|
|
- if (g_sinit != NULL) {
|
|
- sinit_caps = get_sinit_capabilities(g_sinit);
|
|
- }
|
|
+ if ( tpm->major == TPM20_VER_MAJOR ) {
|
|
+ if (g_sinit != NULL) {
|
|
+ sinit_caps = get_sinit_capabilities(g_sinit);
|
|
+ }
|
|
if (sinit_caps.tcg_event_log_format) {
|
|
- size[2] = sizeof(os_sinit_data_t) + sizeof(uint64_t) +
|
|
+ size[2] = sizeof(os_sinit_data_t) + sizeof(uint64_t) +
|
|
2 * sizeof(heap_ext_data_element_t) +
|
|
sizeof(heap_event_log_ptr_elt2_1_t);
|
|
}
|
|
- else {
|
|
- u32 count;
|
|
- if ( g_tpm->extpol == TB_EXTPOL_AGILE )
|
|
- count = g_tpm->banks;
|
|
- else
|
|
- if ( g_tpm->extpol == TB_EXTPOL_EMBEDDED )
|
|
- count = g_tpm->alg_count;
|
|
- else
|
|
- count = 1;
|
|
- size[2] = sizeof(os_sinit_data_t) + sizeof(uint64_t) +
|
|
- 2 * sizeof(heap_ext_data_element_t) +
|
|
- 4 + count*sizeof(heap_event_log_descr_t);
|
|
- }
|
|
+ else {
|
|
+ u32 count;
|
|
+ if ( tpm->extpol == TB_EXTPOL_AGILE )
|
|
+ count = tpm->banks;
|
|
+ else
|
|
+ if ( tpm->extpol == TB_EXTPOL_EMBEDDED )
|
|
+ count = tpm->alg_count;
|
|
+ else
|
|
+ count = 1;
|
|
+ size[2] = sizeof(os_sinit_data_t) + sizeof(uint64_t) +
|
|
+ 2 * sizeof(heap_ext_data_element_t) + 4 +
|
|
+ count*sizeof(heap_event_log_descr_t);
|
|
+ }
|
|
}
|
|
|
|
if ( version >= 6 )
|
|
Index: tboot-1.9.6/tboot/txt/txt.c
|
|
===================================================================
|
|
--- tboot-1.9.6.orig/tboot/txt/txt.c
|
|
+++ tboot-1.9.6/tboot/txt/txt.c
|
|
@@ -247,10 +247,11 @@ static void init_evtlog_desc(heap_event_
|
|
{
|
|
unsigned int i;
|
|
os_mle_data_t *os_mle_data = get_os_mle_data_start(get_txt_heap());
|
|
- switch (g_tpm->extpol) {
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ switch (tpm->extpol) {
|
|
case TB_EXTPOL_AGILE:
|
|
for (i=0; i<evt_log->count; i++) {
|
|
- evt_log->event_log_descr[i].alg = g_tpm->algs_banks[i];
|
|
+ evt_log->event_log_descr[i].alg = tpm->algs_banks[i];
|
|
evt_log->event_log_descr[i].phys_addr =
|
|
(uint64_t)(unsigned long)(os_mle_data->event_log_buffer + i*4096);
|
|
evt_log->event_log_descr[i].size = 4096;
|
|
@@ -260,7 +261,7 @@ static void init_evtlog_desc(heap_event_
|
|
break;
|
|
case TB_EXTPOL_EMBEDDED:
|
|
for (i=0; i<evt_log->count; i++) {
|
|
- evt_log->event_log_descr[i].alg = g_tpm->algs[i];
|
|
+ evt_log->event_log_descr[i].alg = tpm->algs[i];
|
|
evt_log->event_log_descr[i].phys_addr =
|
|
(uint64_t)(unsigned long)(os_mle_data->event_log_buffer + i*4096);
|
|
evt_log->event_log_descr[i].size = 4096;
|
|
@@ -269,7 +270,7 @@ static void init_evtlog_desc(heap_event_
|
|
}
|
|
break;
|
|
case TB_EXTPOL_FIXED:
|
|
- evt_log->event_log_descr[0].alg = g_tpm->cur_alg;
|
|
+ evt_log->event_log_descr[0].alg = tpm->cur_alg;
|
|
evt_log->event_log_descr[0].phys_addr =
|
|
(uint64_t)(unsigned long)os_mle_data->event_log_buffer;
|
|
evt_log->event_log_descr[0].size = 4096;
|
|
@@ -286,15 +287,16 @@ static void init_os_sinit_ext_data(heap_
|
|
heap_ext_data_element_t* elt = elts;
|
|
heap_event_log_ptr_elt_t* evt_log;
|
|
txt_caps_t sinit_caps;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
|
|
- if ( g_tpm->major == TPM12_VER_MAJOR ) {
|
|
+ if ( tpm->major == TPM12_VER_MAJOR ) {
|
|
evt_log = (heap_event_log_ptr_elt_t *)elt->data;
|
|
evt_log->event_log_phys_addr = (uint64_t)(unsigned long)init_event_log();
|
|
elt->type = HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR;
|
|
elt->size = sizeof(*elt) + sizeof(*evt_log);
|
|
}
|
|
else
|
|
- if ( g_tpm->major == TPM20_VER_MAJOR ) {
|
|
+ if ( tpm->major == TPM20_VER_MAJOR ) {
|
|
if (g_sinit != NULL) {
|
|
sinit_caps = get_sinit_capabilities(g_sinit);
|
|
}
|
|
@@ -311,11 +313,11 @@ static void init_os_sinit_ext_data(heap_
|
|
}
|
|
else {
|
|
g_elog_2 = (heap_event_log_ptr_elt2_t *)elt->data;
|
|
- if ( g_tpm->extpol == TB_EXTPOL_AGILE )
|
|
- g_elog_2->count = g_tpm->banks;
|
|
+ if ( tpm->extpol == TB_EXTPOL_AGILE )
|
|
+ g_elog_2->count = tpm->banks;
|
|
else
|
|
- if ( g_tpm->extpol == TB_EXTPOL_EMBEDDED )
|
|
- g_elog_2->count = g_tpm->alg_count;
|
|
+ if ( tpm->extpol == TB_EXTPOL_EMBEDDED )
|
|
+ g_elog_2->count = tpm->alg_count;
|
|
else
|
|
g_elog_2->count = 1;
|
|
init_evtlog_desc(g_elog_2);
|
|
@@ -428,7 +430,8 @@ bool evtlog_append_tpm20(uint8_t pcr, ui
|
|
|
|
bool evtlog_append(uint8_t pcr, hash_list_t *hl, uint32_t type)
|
|
{
|
|
- switch (g_tpm->major) {
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
+ switch (tpm->major) {
|
|
case TPM12_VER_MAJOR:
|
|
evtlog_append_tpm12(pcr, &hl->entries[0].hash, type);
|
|
break;
|
|
@@ -454,6 +457,7 @@ static txt_heap_t *init_txt_heap(void *p
|
|
{
|
|
txt_heap_t *txt_heap;
|
|
uint64_t *size;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
|
|
txt_heap = get_txt_heap();
|
|
|
|
@@ -588,8 +592,8 @@ static txt_heap_t *init_txt_heap(void *p
|
|
|
|
/* PCR mapping selection MUST be zero in TPM2.0 mode
|
|
* since D/A mapping is the only supported by TPM2.0 */
|
|
- if ( g_tpm->major >= TPM20_VER_MAJOR ) {
|
|
- os_sinit_data->flags = (g_tpm->extpol == TB_EXTPOL_AGILE) ? 0 : 1;
|
|
+ if ( tpm->major >= TPM20_VER_MAJOR ) {
|
|
+ os_sinit_data->flags = (tpm->extpol == TB_EXTPOL_AGILE) ? 0 : 1;
|
|
os_sinit_data->capabilities.pcr_map_no_legacy = 0;
|
|
os_sinit_data->capabilities.pcr_map_da = 0;
|
|
g_using_da = 1;
|
|
@@ -779,6 +783,7 @@ bool txt_s3_launch_environment(void)
|
|
/* so don't re-create; this is OK because it was untrusted initially */
|
|
/* and would be untrusted now */
|
|
txt_caps_t sinit_caps;
|
|
+ struct tpm_if *tpm = get_tpm();
|
|
|
|
/* get sinit binary loaded */
|
|
g_sinit = (acm_hdr_t *)(uint32_t)read_pub_config_reg(TXTCR_SINIT_BASE);
|
|
@@ -787,10 +792,10 @@ bool txt_s3_launch_environment(void)
|
|
}
|
|
/* initialize event log in os_sinit_data, so that events will not */
|
|
/* repeat when s3 */
|
|
- if ( g_tpm->major == TPM12_VER_MAJOR && g_elog )
|
|
+ if ( tpm->major == TPM12_VER_MAJOR && g_elog )
|
|
g_elog = (event_log_container_t *)init_event_log();
|
|
else
|
|
- if ( g_tpm->major == TPM20_VER_MAJOR ){
|
|
+ if ( tpm->major == TPM20_VER_MAJOR ){
|
|
sinit_caps = get_sinit_capabilities(g_sinit);
|
|
if (sinit_caps.tcg_event_log_format && g_elog_2_1)
|
|
init_evtlog_desc_1(g_elog_2_1);
|