Add method to get random bytes from the TPM.
Change-Id: I66d8a746be5add2d277e2a0783c562206084fcb4
BUG=227
TEST=manual
Review URL: http://codereview.chromium.org/3116014
diff --git a/tpm.cc b/tpm.cc
index 4de12a2..66cb57f 100644
--- a/tpm.cc
+++ b/tpm.cc
@@ -585,4 +585,34 @@
return took_ownership;
}
+bool Tpm::GetRandomData(size_t length, chromeos::Blob* data) {
+ TSS_HCONTEXT context_handle;
+ if (!OpenAndConnectTpm(&context_handle)) {
+ LOG(ERROR) << "Could not open the TPM";
+ return false;
+ }
+
+ TSS_HTPM tpm_handle;
+ if (!GetTpm(context_handle, &tpm_handle)) {
+ LOG(ERROR) << "Could not get a handle to the TPM.";
+ Tspi_Context_Close(context_handle);
+ return false;
+ }
+
+ TSS_RESULT result;
+ SecureBlob random(length);
+ BYTE* tpm_data = NULL;
+ if ((result = Tspi_TPM_GetRandom(tpm_handle, random.size(), &tpm_data))) {
+ LOG(ERROR) << "Could not get random data from the TPM: " << result;
+ Tspi_Context_Close(context_handle);
+ return false;
+ }
+ memcpy(random.data(), tpm_data, random.size());
+ Tspi_Context_FreeMemory(context_handle, tpm_data);
+ chromeos::SecureMemset(tpm_data, 0, random.size());
+ Tspi_Context_Close(context_handle);
+ data->swap(random);
+ return true;
+}
+
} // namespace tpm_init
diff --git a/tpm.h b/tpm.h
index 559c053..97c4d7d 100644
--- a/tpm.h
+++ b/tpm.h
@@ -68,6 +68,13 @@
// call to Tspi_TPM_TakeOwnership.
bool InitializeTpm();
+ // Gets random bytes from the TPM
+ //
+ // Parameters
+ // length - The number of bytes to get
+ // data (OUT) - The random data from the TPM
+ bool GetRandomData(size_t length, chromeos::Blob* data);
+
private:
// Attempts to connect to tcsd
//
diff --git a/tpm_init.cc b/tpm_init.cc
index 92f1c7e..e792141 100644
--- a/tpm_init.cc
+++ b/tpm_init.cc
@@ -28,6 +28,7 @@
bool IsTpmEnabled();
bool GetTpmPassword(chromeos::Blob* password);
long GetInitializationMillis();
+ bool GetRandomData(int length, chromeos::Blob* data);
private:
scoped_ptr<tpm_init::Tpm> default_tpm_;
@@ -44,6 +45,10 @@
TpmInit::~TpmInit() {
}
+bool TpmInit::GetRandomData(int length, chromeos::Blob* data) {
+ return tpm_init_->GetRandomData(length, data);
+}
+
bool TpmInit::StartInitializeTpm() {
tpm_init_->Init();
if (!PlatformThread::CreateNonJoinable(0, tpm_init_.get())) {
@@ -125,4 +130,8 @@
return initialization_time_;
}
+bool TpmInitTask::GetRandomData(int length, chromeos::Blob* data) {
+ return tpm_->GetRandomData(length, data);
+}
+
} // namespace tpm_init
diff --git a/tpm_init.h b/tpm_init.h
index 0dc1086..e2e6bd1 100644
--- a/tpm_init.h
+++ b/tpm_init.h
@@ -23,6 +23,13 @@
virtual ~TpmInit();
+ // Gets random data from the TPM
+ //
+ // Parameters
+ // length - The number of bytes to get
+ // data (OUT) - Receives the random bytes
+ virtual bool GetRandomData(int length, chromeos::Blob* data);
+
// Starts asynchronous initialization of the TPM
virtual bool StartInitializeTpm();