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>
This commit is contained in:
parent
4e57a54703
commit
1be65c56c6
|
@ -167,27 +167,32 @@ static const struct hash_parameters {
|
||||||
u8 hashalg_flag;
|
u8 hashalg_flag;
|
||||||
u8 hash_buffersize;
|
u8 hash_buffersize;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
void (*hashfunc)(const u8 *data, u32 length, u8 *hash);
|
||||||
} hash_parameters[] = {
|
} hash_parameters[] = {
|
||||||
{
|
{
|
||||||
.hashalg = TPM2_ALG_SHA1,
|
.hashalg = TPM2_ALG_SHA1,
|
||||||
.hashalg_flag = TPM2_ALG_SHA1_FLAG,
|
.hashalg_flag = TPM2_ALG_SHA1_FLAG,
|
||||||
.hash_buffersize = SHA1_BUFSIZE,
|
.hash_buffersize = SHA1_BUFSIZE,
|
||||||
.name = "SHA1",
|
.name = "SHA1",
|
||||||
|
.hashfunc = sha1,
|
||||||
}, {
|
}, {
|
||||||
.hashalg = TPM2_ALG_SHA256,
|
.hashalg = TPM2_ALG_SHA256,
|
||||||
.hashalg_flag = TPM2_ALG_SHA256_FLAG,
|
.hashalg_flag = TPM2_ALG_SHA256_FLAG,
|
||||||
.hash_buffersize = SHA256_BUFSIZE,
|
.hash_buffersize = SHA256_BUFSIZE,
|
||||||
.name = "SHA256",
|
.name = "SHA256",
|
||||||
|
.hashfunc = sha256,
|
||||||
}, {
|
}, {
|
||||||
.hashalg = TPM2_ALG_SHA384,
|
.hashalg = TPM2_ALG_SHA384,
|
||||||
.hashalg_flag = TPM2_ALG_SHA384_FLAG,
|
.hashalg_flag = TPM2_ALG_SHA384_FLAG,
|
||||||
.hash_buffersize = SHA384_BUFSIZE,
|
.hash_buffersize = SHA384_BUFSIZE,
|
||||||
.name = "SHA384",
|
.name = "SHA384",
|
||||||
|
.hashfunc = sha384,
|
||||||
}, {
|
}, {
|
||||||
.hashalg = TPM2_ALG_SHA512,
|
.hashalg = TPM2_ALG_SHA512,
|
||||||
.hashalg_flag = TPM2_ALG_SHA512_FLAG,
|
.hashalg_flag = TPM2_ALG_SHA512_FLAG,
|
||||||
.hash_buffersize = SHA512_BUFSIZE,
|
.hash_buffersize = SHA512_BUFSIZE,
|
||||||
.name = "SHA512",
|
.name = "SHA512",
|
||||||
|
.hashfunc = sha512,
|
||||||
}, {
|
}, {
|
||||||
.hashalg = TPM2_ALG_SM3_256,
|
.hashalg = TPM2_ALG_SM3_256,
|
||||||
.hashalg_flag = TPM2_ALG_SM3_256_FLAG,
|
.hashalg_flag = TPM2_ALG_SM3_256_FLAG,
|
||||||
|
@ -259,6 +264,21 @@ tpm20_hashalg_flag_to_name(u8 hashalg_flag)
|
||||||
return NULL;
|
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
|
// Add an entry at the start of the log describing digest formats
|
||||||
static int
|
static int
|
||||||
tpm20_write_EfiSpecIdEventStruct(void)
|
tpm20_write_EfiSpecIdEventStruct(void)
|
||||||
|
@ -342,14 +362,16 @@ tpm20_write_EfiSpecIdEventStruct(void)
|
||||||
* hash when writing it in the area of the sha1 hash.
|
* hash when writing it in the area of the sha1 hash.
|
||||||
*
|
*
|
||||||
* le: the log entry to build the digest in
|
* 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
|
* bigEndian: whether to build in big endian format for the TPM or
|
||||||
* little endian for the log
|
* little endian for the log
|
||||||
*
|
*
|
||||||
* Returns the digest size; -1 on fatal error
|
* Returns the digest size; -1 on fatal error
|
||||||
*/
|
*/
|
||||||
static int
|
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)
|
if (!tpm20_pcr_selection)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -391,8 +413,8 @@ tpm20_build_digest(struct tpm_log_entry *le, const u8 *sha1, int bigEndian)
|
||||||
else
|
else
|
||||||
v->hashAlg = be16_to_cpu(sel->hashAlg);
|
v->hashAlg = be16_to_cpu(sel->hashAlg);
|
||||||
|
|
||||||
memset(v->hash, 0, hsize);
|
tpm2_hash_data(be16_to_cpu(sel->hashAlg), hashdata, hashdata_len,
|
||||||
memcpy(v->hash, sha1, hsize > SHA1_BUFSIZE ? SHA1_BUFSIZE : hsize);
|
v->hash);
|
||||||
|
|
||||||
dest += sizeof(*v) + hsize;
|
dest += sizeof(*v) + hsize;
|
||||||
sel = nsel;
|
sel = nsel;
|
||||||
|
@ -415,7 +437,15 @@ tpm20_build_digest(struct tpm_log_entry *le, const u8 *sha1, int bigEndian)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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
|
// On TPM 1.2 the digest contains just the SHA1 hash
|
||||||
memcpy(le->hdr.digest, sha1, SHA1_BUFSIZE);
|
memcpy(le->hdr.digest, sha1, SHA1_BUFSIZE);
|
||||||
|
@ -423,13 +453,14 @@ tpm12_build_digest(struct tpm_log_entry *le, const u8 *sha1)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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) {
|
switch (TPM_version) {
|
||||||
case TPM_VERSION_1_2:
|
case TPM_VERSION_1_2:
|
||||||
return tpm12_build_digest(le, sha1);
|
return tpm12_build_digest(le, hashdata, hashdata_len);
|
||||||
case TPM_VERSION_2:
|
case TPM_VERSION_2:
|
||||||
return tpm20_build_digest(le, sha1, bigEndian);
|
return tpm20_build_digest(le, hashdata, hashdata_len, bigEndian);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -978,14 +1009,11 @@ tpm_add_measurement_to_log(u32 pcrindex, u32 event_type,
|
||||||
if (!tpm_is_working())
|
if (!tpm_is_working())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
u8 hash[SHA1_BUFSIZE];
|
|
||||||
sha1(hashdata, hashdata_length, hash);
|
|
||||||
|
|
||||||
struct tpm_log_entry le = {
|
struct tpm_log_entry le = {
|
||||||
.hdr.pcrindex = pcrindex,
|
.hdr.pcrindex = pcrindex,
|
||||||
.hdr.eventtype = event_type,
|
.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)
|
if (digest_len < 0)
|
||||||
return;
|
return;
|
||||||
int ret = tpm_extend(&le, digest_len);
|
int ret = tpm_extend(&le, digest_len);
|
||||||
|
@ -993,7 +1021,7 @@ tpm_add_measurement_to_log(u32 pcrindex, u32 event_type,
|
||||||
tpm_set_failure();
|
tpm_set_failure();
|
||||||
return;
|
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);
|
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.pcrindex = pcpes->pcrindex,
|
||||||
.hdr.eventtype = pcpes->eventtype,
|
.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)
|
if (digest_len < 0)
|
||||||
return TCG_GENERAL_ERROR;
|
return TCG_GENERAL_ERROR;
|
||||||
if (extend) {
|
if (extend) {
|
||||||
|
@ -1415,7 +1443,7 @@ hash_log_extend(struct pcpes *pcpes, const void *hashdata, u32 hashdata_length
|
||||||
if (ret)
|
if (ret)
|
||||||
return TCG_TCG_COMMAND_ERROR;
|
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
|
int ret = tpm_log_event(&le.hdr, digest_len
|
||||||
, pcpes->event, pcpes->eventdatasize);
|
, pcpes->event, pcpes->eventdatasize);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in New Issue