diff --git a/src/evmctl.c b/src/evmctl.c index 4fd0ed8..08e6148 100644 --- a/src/evmctl.c +++ b/src/evmctl.c @@ -1615,10 +1615,15 @@ static struct tpm_bank_info *init_tpm_banks(int *num_banks) /* * Compare the calculated TPM PCR banks against the PCR values read. + * The banks_mask parameter allows to select which banks to consider. + * A banks_maks of 0x3 would consider banks 1 and 2, 0x2 would only + * consider the 2nd bank, ~0 would consider all banks. + * * On failure to match any TPM bank, fail comparison. */ static int compare_tpm_banks(int num_banks, struct tpm_bank_info *bank, - struct tpm_bank_info *tpm_bank) + struct tpm_bank_info *tpm_bank, + unsigned int banks_mask, unsigned long entry_num) { int i, j; int ret = 0; @@ -1626,6 +1631,9 @@ static int compare_tpm_banks(int num_banks, struct tpm_bank_info *bank, for (i = 0; i < num_banks; i++) { if (!bank[i].supported || !tpm_bank[i].supported) continue; + /* do we need to look at the n-th bank ? */ + if ((banks_mask & (1 << i)) == 0) + continue; for (j = 0; j < NUM_PCRS; j++) { if (memcmp(bank[i].pcr[j], zero, bank[i].digest_size) == 0) @@ -1646,8 +1654,8 @@ static int compare_tpm_banks(int num_banks, struct tpm_bank_info *bank, log_dump(tpm_bank[i].pcr[j], tpm_bank[i].digest_size); if (!ret) - log_info("%s PCR-%d: succeed\n", - bank[i].algo_name, j); + log_info("%s PCR-%d: succeed at entry %lu\n", + bank[i].algo_name, j, entry_num); else log_info("%s: PCRAgg %d does not match TPM PCR-%d\n", bank[i].algo_name, j, j); @@ -1962,6 +1970,9 @@ static int ima_measurement(const char *file) int num_banks = 0; int tpmbanks = 1; int first_record = 1; + unsigned int pseudo_padded_banks_mask, pseudo_banks_mask; + unsigned long entry_num = 0; + int c; struct template_entry entry = { .template = 0 }; FILE *fp; @@ -1995,7 +2006,12 @@ static int ima_measurement(const char *file) if (read_tpm_banks(num_banks, tpm_banks) != 0) tpmbanks = 0; + /* A mask where each bit represents the banks to check against */ + pseudo_banks_mask = (1 << num_banks) - 1; + pseudo_padded_banks_mask = pseudo_banks_mask; + while (fread(&entry.header, sizeof(entry.header), 1, fp)) { + entry_num++; if (entry.header.name_len > TCG_EVENT_NAME_LEN_MAX) { log_err("%d ERROR: event name too long!\n", entry.header.name_len); @@ -2107,18 +2123,33 @@ static int ima_measurement(const char *file) if (!tpmbanks) continue; - /* The measurement list might contain too many entries, - * compare the re-calculated TPM PCR values after each - * extend. - */ - err = compare_tpm_banks(num_banks, pseudo_banks, tpm_banks); - if (!err) + for (c = 0; c < num_banks; c++) { + if ((pseudo_banks_mask & (1 << c)) == 0) + continue; + /* The measurement list might contain too many entries, + * compare the re-calculated TPM PCR values after each + * extend. + */ + err = compare_tpm_banks(num_banks, pseudo_banks, + tpm_banks, 1 << c, entry_num); + if (!err) + pseudo_banks_mask ^= (1 << c); + } + if (pseudo_banks_mask == 0) break; - /* Compare against original SHA1 zero padded TPM PCR values */ - err_padded = compare_tpm_banks(num_banks, pseudo_padded_banks, - tpm_banks); - if (!err_padded) + for (c = 0; c < num_banks; c++) { + if ((pseudo_padded_banks_mask & (1 << c)) == 0) + continue; + /* Compare against original SHA1 zero padded TPM PCR values */ + err_padded = compare_tpm_banks(num_banks, + pseudo_padded_banks, + tpm_banks, + 1 << c, entry_num); + if (!err_padded) + pseudo_padded_banks_mask ^= (1 << c); + } + if (pseudo_padded_banks_mask == 0) break; }