Philipp Deppenwiese has uploaded this change for review.

View Change

security/tpm: Implement hashing function in TSS

* Implement hash_start, hash_update and hash_complete
functionality of the TPM into the TSS.
* TPM 1.2 and 2.0 support.

Change-Id: I6c570a6725ff2f26c9d480303eff273ae9d5ac3b
Signed-off-by: Philipp Deppenwiese <zaolin@das-labor.org>
---
M src/security/tpm/tss.h
M src/security/tpm/tss/tcg-1.2/tss.c
M src/security/tpm/tss/tcg-1.2/tss_commands.h
M src/security/tpm/tss/tcg-1.2/tss_structures.h
M src/security/tpm/tss/tcg-2.0/tss.c
M src/security/tpm/tss_errors.h
6 files changed, 121 insertions(+), 1 deletion(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/08/24908/1
diff --git a/src/security/tpm/tss.h b/src/security/tpm/tss.h
index 151d450..1b928ab 100644
--- a/src/security/tpm/tss.h
+++ b/src/security/tpm/tss.h
@@ -159,6 +159,22 @@
uint8_t *out_digest);

/**
+ * Hash start function, returns size of data which can hashed at once.
+ */
+uint32_t tlcl_hash_start(uint32_t *data_length);
+
+/**
+ * Hash update function, measures a message into the hash.
+ */
+uint32_t tlcl_hash_update(const void *message, uint32_t message_length);
+
+/**
+ * Hash complete function, hashes the lastest chunk and returns the digest.
+ */
+uint32_t tlcl_hash_complete(const void *message, uint32_t message_length,
+ uint8_t *digest, uint32_t *digest_length);
+
+/**
* Get the entire set of permanent flags.
*/
uint32_t tlcl_get_permanent_flags(TPM_PERMANENT_FLAGS *pflags);
diff --git a/src/security/tpm/tss/tcg-1.2/tss.c b/src/security/tpm/tss/tcg-1.2/tss.c
index b6a61c1..0d317e0 100644
--- a/src/security/tpm/tss/tcg-1.2/tss.c
+++ b/src/security/tpm/tss/tcg-1.2/tss.c
@@ -352,3 +352,68 @@
kPcrDigestLength);
return result;
}
+
+uint32_t tlcl_hash_start(uint32_t *data_length)
+{
+ struct s_tpm_sha1_start_cmd cmd = tpm_sha1_start_cmd;
+ uint8_t response[kTpmResponseHeaderLength + sizeof(uint32_t)];
+ uint32_t result;
+
+ result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
+ if (result != TPM_SUCCESS)
+ return result;
+
+ if (data_length) {
+ from_tpm_uint32(response + kTpmResponseHeaderLength,
+ data_length);
+ if (*data_length >= TPM_MAX_COMMAND_SIZE)
+ *data_length = TPM_MAX_COMMAND_SIZE;
+ }
+
+ return result;
+}
+
+uint32_t tlcl_hash_update(const void *message, uint32_t message_length)
+{
+ struct s_tpm_sha1_update_cmd cmd = tpm_sha1_update_cmd;
+ uint32_t total_length;
+ uint8_t response[TPM_MAX_COMMAND_SIZE];
+
+ total_length =
+ kTpmRequestHeaderLength + sizeof(uint32_t) + message_length;
+ assert(total_length <= TPM_MAX_COMMAND_SIZE);
+ set_tpm_command_size(cmd.buffer, total_length);
+
+ to_tpm_uint32(cmd.buffer + tpm_sha1_update_cmd.length, message_length);
+ memcpy(cmd.buffer + tpm_sha1_update_cmd.data, message, message_length);
+
+ return tlcl_send_receive(cmd.buffer, response, sizeof(response));
+}
+
+uint32_t tlcl_hash_complete(const void *message, uint32_t message_length,
+ uint8_t *digest, uint32_t *digest_length)
+{
+ struct s_tpm_sha1_complete_cmd cmd = tpm_sha1_complete_cmd;
+ uint32_t total_length;
+ uint32_t result;
+ uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
+
+ total_length =
+ kTpmRequestHeaderLength + sizeof(uint32_t) + message_length;
+ assert(total_length <= TPM_LARGE_ENOUGH_COMMAND_SIZE);
+ set_tpm_command_size(cmd.buffer, total_length);
+
+ to_tpm_uint32(cmd.buffer + tpm_sha1_complete_cmd.length,
+ message_length);
+ memcpy(cmd.buffer + tpm_sha1_complete_cmd.data, message,
+ message_length);
+
+ result = tlcl_send_receive(cmd.buffer, response, sizeof(response));
+ if (result == TPM_SUCCESS) {
+ memcpy(digest, response + kTpmResponseHeaderLength,
+ kPcrDigestLength);
+ *digest_length = TPM_PCR_DIGEST;
+ }
+
+ return result;
+}
diff --git a/src/security/tpm/tss/tcg-1.2/tss_commands.h b/src/security/tpm/tss/tcg-1.2/tss_commands.h
index f245664..e9e77b2 100644
--- a/src/security/tpm/tss/tcg-1.2/tss_commands.h
+++ b/src/security/tpm/tss/tcg-1.2/tss_commands.h
@@ -173,5 +173,26 @@
12, 70, 77,
};

+const struct s_tpm_sha1_start_cmd{
+ uint8_t buffer[10];
+} tpm_sha1_start_cmd = {{0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa0, },
+};
+
+const struct s_tpm_sha1_update_cmd{
+ uint8_t buffer[64];
+ uint16_t length;
+ uint16_t data;
+} tpm_sha1_update_cmd = {
+ {0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0xa1, },
+ 10, 14, };
+
+const struct s_tpm_sha1_complete_cmd{
+ uint8_t buffer[64];
+ uint16_t length;
+ uint16_t data;
+} tpm_sha1_complete_cmd = {
+ {0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0xa2, },
+ 10, 14, };
+
const int kWriteInfoLength = 12;
const int kNvDataPublicPermissionsOffset = 60;
diff --git a/src/security/tpm/tss/tcg-1.2/tss_structures.h b/src/security/tpm/tss/tcg-1.2/tss_structures.h
index 9429b79..c9ac8cf 100644
--- a/src/security/tpm/tss/tcg-1.2/tss_structures.h
+++ b/src/security/tpm/tss/tcg-1.2/tss_structures.h
@@ -11,10 +11,13 @@
#include <stdint.h>
#include "../common/tss_common.h"

-#define TPM_MAX_COMMAND_SIZE 4096
+#define TPM_MAX_COMMAND_SIZE 1400
#define TPM_LARGE_ENOUGH_COMMAND_SIZE 256 /* saves space in the firmware */
#define TPM_PUBEK_SIZE 256

+#define TPM_HASH_MIN_COUNT 64
+#define TPM_HASH_MAX_COUNT 1024
+
#define TPM_NV_INDEX0 ((uint32_t)0x00000000)
#define TPM_NV_INDEX_LOCK ((uint32_t)0xffffffff)
#define TPM_NV_PER_GLOBALLOCK (((uint32_t)1)<<15)
diff --git a/src/security/tpm/tss/tcg-2.0/tss.c b/src/security/tpm/tss/tcg-2.0/tss.c
index b64593a..5731be1 100644
--- a/src/security/tpm/tss/tcg-2.0/tss.c
+++ b/src/security/tpm/tss/tcg-2.0/tss.c
@@ -321,3 +321,17 @@

return TPM_SUCCESS;
}
+
+uint32_t tlcl_hash_start(uint32_t *data_length)
+{
+ return NOT_IMPLEMENTED;
+}
+uint32_t tlcl_hash_update(const void *message, uint32_t message_length)
+{
+ return NOT_IMPLEMENTED;
+}
+uint32_t tlcl_hash_complete(const void *message, uint32_t message_length,
+ uint8_t *digest, uint32_t *digest_length)
+{
+ return NOT_IMPLEMENTED;
+}
diff --git a/src/security/tpm/tss_errors.h b/src/security/tpm/tss_errors.h
index e2f1486..e958ef2 100644
--- a/src/security/tpm/tss_errors.h
+++ b/src/security/tpm/tss_errors.h
@@ -14,6 +14,7 @@

#define TPM_E_BASE 0x0
#define TPM_E_NON_FATAL 0x800
+#define NOT_IMPLEMENTED 0x100

#define TPM_E_AREA_LOCKED ((uint32_t)0x0000003c)
#define TPM_E_BADINDEX ((uint32_t)0x00000002)

To view, visit change 24908. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6c570a6725ff2f26c9d480303eff273ae9d5ac3b
Gerrit-Change-Number: 24908
Gerrit-PatchSet: 1
Gerrit-Owner: Philipp Deppenwiese <zaolin.daisuki@gmail.com>