diff options
author | Stefan Berger <stefanb@linux.ibm.com> | 2021-06-14 13:35:49 -0400 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2021-06-30 16:58:48 -0400 |
commit | 1be65c56c603163b07ebcec3bc88aa7ae0b1bb80 (patch) | |
tree | 8d679e0e5b30125357510ad81f0795db933493c9 | |
parent | 4e57a54703a5a28681bb86288a971cb83a05359c (diff) | |
download | seabios-hppa-1be65c56c603163b07ebcec3bc88aa7ae0b1bb80.zip seabios-hppa-1be65c56c603163b07ebcec3bc88aa7ae0b1bb80.tar.gz seabios-hppa-1be65c56c603163b07ebcec3bc88aa7ae0b1bb80.tar.bz2 |
tcgbios: Use The proper sha function for each PCR bank
Instead of just using sha1 for all PCR banks (and truncating
the value or zero-padding it) use the proper hash function for
each one of the banks. For unimplemented hashes, fill the buffer
with 0xff.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
-rw-r--r-- | src/tcgbios.c | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/src/tcgbios.c b/src/tcgbios.c index a9d62c8..02921d8 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -167,27 +167,32 @@ static const struct hash_parameters { u8 hashalg_flag; u8 hash_buffersize; const char *name; + void (*hashfunc)(const u8 *data, u32 length, u8 *hash); } hash_parameters[] = { { .hashalg = TPM2_ALG_SHA1, .hashalg_flag = TPM2_ALG_SHA1_FLAG, .hash_buffersize = SHA1_BUFSIZE, .name = "SHA1", + .hashfunc = sha1, }, { .hashalg = TPM2_ALG_SHA256, .hashalg_flag = TPM2_ALG_SHA256_FLAG, .hash_buffersize = SHA256_BUFSIZE, .name = "SHA256", + .hashfunc = sha256, }, { .hashalg = TPM2_ALG_SHA384, .hashalg_flag = TPM2_ALG_SHA384_FLAG, .hash_buffersize = SHA384_BUFSIZE, .name = "SHA384", + .hashfunc = sha384, }, { .hashalg = TPM2_ALG_SHA512, .hashalg_flag = TPM2_ALG_SHA512_FLAG, .hash_buffersize = SHA512_BUFSIZE, .name = "SHA512", + .hashfunc = sha512, }, { .hashalg = TPM2_ALG_SM3_256, .hashalg_flag = TPM2_ALG_SM3_256_FLAG, @@ -259,6 +264,21 @@ tpm20_hashalg_flag_to_name(u8 hashalg_flag) return NULL; } +static void tpm2_hash_data(u16 hashAlg, const u8 *data, u32 data_len, u8 *hash) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(hash_parameters); i++) { + if (hash_parameters[i].hashalg == hashAlg) { + if (hash_parameters[i].hashfunc) { + hash_parameters[i].hashfunc(data, data_len, hash); + } else { + memset(hash, 0xff, hash_parameters[i].hash_buffersize); + } + } + } +} + // Add an entry at the start of the log describing digest formats static int tpm20_write_EfiSpecIdEventStruct(void) @@ -342,14 +362,16 @@ tpm20_write_EfiSpecIdEventStruct(void) * hash when writing it in the area of the sha1 hash. * * le: the log entry to build the digest in - * sha1: the sha1 hash value to use + * hashdata: the data to hash + * hashdata_len: the length of the hashdata * bigEndian: whether to build in big endian format for the TPM or * little endian for the log * * Returns the digest size; -1 on fatal error */ static int -tpm20_build_digest(struct tpm_log_entry *le, const u8 *sha1, int bigEndian) +tpm20_build_digest(struct tpm_log_entry *le, + const u8 *hashdata, u32 hashdata_len, int bigEndian) { if (!tpm20_pcr_selection) return -1; @@ -391,8 +413,8 @@ tpm20_build_digest(struct tpm_log_entry *le, const u8 *sha1, int bigEndian) else v->hashAlg = be16_to_cpu(sel->hashAlg); - memset(v->hash, 0, hsize); - memcpy(v->hash, sha1, hsize > SHA1_BUFSIZE ? SHA1_BUFSIZE : hsize); + tpm2_hash_data(be16_to_cpu(sel->hashAlg), hashdata, hashdata_len, + v->hash); dest += sizeof(*v) + hsize; sel = nsel; @@ -415,7 +437,15 @@ tpm20_build_digest(struct tpm_log_entry *le, const u8 *sha1, int bigEndian) } static int -tpm12_build_digest(struct tpm_log_entry *le, const u8 *sha1) +tpm12_build_digest(struct tpm_log_entry *le, + const u8 *hashdata, u32 hashdata_len) +{ + sha1(hashdata, hashdata_len, le->hdr.digest); + return SHA1_BUFSIZE; +} + +static int +tpm12_build_digest_direct(struct tpm_log_entry *le, const u8 *sha1) { // On TPM 1.2 the digest contains just the SHA1 hash memcpy(le->hdr.digest, sha1, SHA1_BUFSIZE); @@ -423,13 +453,14 @@ tpm12_build_digest(struct tpm_log_entry *le, const u8 *sha1) } static int -tpm_build_digest(struct tpm_log_entry *le, const u8 *sha1, int bigEndian) +tpm_build_digest(struct tpm_log_entry *le, const u8 *hashdata, u32 hashdata_len + , int bigEndian) { switch (TPM_version) { case TPM_VERSION_1_2: - return tpm12_build_digest(le, sha1); + return tpm12_build_digest(le, hashdata, hashdata_len); case TPM_VERSION_2: - return tpm20_build_digest(le, sha1, bigEndian); + return tpm20_build_digest(le, hashdata, hashdata_len, bigEndian); } return -1; } @@ -978,14 +1009,11 @@ tpm_add_measurement_to_log(u32 pcrindex, u32 event_type, if (!tpm_is_working()) return; - u8 hash[SHA1_BUFSIZE]; - sha1(hashdata, hashdata_length, hash); - struct tpm_log_entry le = { .hdr.pcrindex = pcrindex, .hdr.eventtype = event_type, }; - int digest_len = tpm_build_digest(&le, hash, 1); + int digest_len = tpm_build_digest(&le, hashdata, hashdata_length, 1); if (digest_len < 0) return; int ret = tpm_extend(&le, digest_len); @@ -993,7 +1021,7 @@ tpm_add_measurement_to_log(u32 pcrindex, u32 event_type, tpm_set_failure(); return; } - tpm_build_digest(&le, hash, 0); + tpm_build_digest(&le, hashdata, hashdata_length, 0); tpm_log_event(&le.hdr, digest_len, event, event_length); } @@ -1407,7 +1435,7 @@ hash_log_extend(struct pcpes *pcpes, const void *hashdata, u32 hashdata_length .hdr.pcrindex = pcpes->pcrindex, .hdr.eventtype = pcpes->eventtype, }; - int digest_len = tpm_build_digest(&le, pcpes->digest, 1); + int digest_len = tpm12_build_digest_direct(&le, pcpes->digest); if (digest_len < 0) return TCG_GENERAL_ERROR; if (extend) { @@ -1415,7 +1443,7 @@ hash_log_extend(struct pcpes *pcpes, const void *hashdata, u32 hashdata_length if (ret) return TCG_TCG_COMMAND_ERROR; } - tpm_build_digest(&le, pcpes->digest, 0); + tpm12_build_digest_direct(&le, pcpes->digest); int ret = tpm_log_event(&le.hdr, digest_len , pcpes->event, pcpes->eventdatasize); if (ret) |