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,
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)
* 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;
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;
}
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);
}
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;
}
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);
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);
}
.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) {
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)