Merge "Implement SE root of trust provisioning." into tm-dev
diff --git a/guest/hals/keymint/remote/remote_keymaster.cpp b/guest/hals/keymint/remote/remote_keymaster.cpp
index 6675810..763c139 100644
--- a/guest/hals/keymint/remote/remote_keymaster.cpp
+++ b/guest/hals/keymint/remote/remote_keymaster.cpp
@@ -312,4 +312,11 @@
   return response;
 }
 
+GetRootOfTrustResponse RemoteKeymaster::GetRootOfTrust(
+    const GetRootOfTrustRequest& request) {
+  GetRootOfTrustResponse response(message_version());
+  ForwardCommand(GET_ROOT_OF_TRUST, request, &response);
+  return response;
+}
+
 }  // namespace keymaster
diff --git a/guest/hals/keymint/remote/remote_keymaster.h b/guest/hals/keymint/remote/remote_keymaster.h
index 240e610..2e0668f 100644
--- a/guest/hals/keymint/remote/remote_keymaster.h
+++ b/guest/hals/keymint/remote/remote_keymaster.h
@@ -94,6 +94,7 @@
       const ConfigureVerifiedBootInfoRequest& request);
   void GenerateTimestampToken(GenerateTimestampTokenRequest& request,
                               GenerateTimestampTokenResponse* response);
+  GetRootOfTrustResponse GetRootOfTrust(const GetRootOfTrustRequest& request);
 
   // CF HAL and remote sides are always compiled together, so will never
   // disagree about message versions.
diff --git a/guest/hals/keymint/remote/remote_keymint_device.cpp b/guest/hals/keymint/remote/remote_keymint_device.cpp
index 4f9606f..c6db283 100644
--- a/guest/hals/keymint/remote/remote_keymint_device.cpp
+++ b/guest/hals/keymint/remote/remote_keymint_device.cpp
@@ -449,9 +449,20 @@
 }
 
 ScopedAStatus RemoteKeyMintDevice::getRootOfTrust(
-    const std::array<uint8_t, 16>& /* challenge */,
-    std::vector<uint8_t>* /* rootOfTrust */) {
-  return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
+    const std::array<uint8_t, 16>& challenge,
+    std::vector<uint8_t>* rootOfTrust) {
+  if (!rootOfTrust) {
+    return kmError2ScopedAStatus(KM_ERROR_UNEXPECTED_NULL_POINTER);
+  }
+  GetRootOfTrustRequest request(impl_.message_version(),
+                                {challenge.begin(), challenge.end()});
+  GetRootOfTrustResponse response = impl_.GetRootOfTrust(request);
+  if (response.error != KM_ERROR_OK) {
+    return kmError2ScopedAStatus(response.error);
+  }
+
+  *rootOfTrust = std::move(response.rootOfTrust);
+  return ScopedAStatus::ok();
 }
 
 ScopedAStatus RemoteKeyMintDevice::sendRootOfTrust(
diff --git a/host/commands/secure_env/keymaster_responder.cpp b/host/commands/secure_env/keymaster_responder.cpp
index c5d4e3b..688ddf3 100644
--- a/host/commands/secure_env/keymaster_responder.cpp
+++ b/host/commands/secure_env/keymaster_responder.cpp
@@ -89,6 +89,7 @@
     HANDLE_MESSAGE_W_RETURN(CONFIGURE_BOOT_PATCHLEVEL, ConfigureBootPatchlevel)
     HANDLE_MESSAGE_W_RETURN(CONFIGURE_VERIFIED_BOOT_INFO,
                             ConfigureVerifiedBootInfo)
+    HANDLE_MESSAGE_W_RETURN(GET_ROOT_OF_TRUST, GetRootOfTrust)
 #undef HANDLE_MESSAGE_W_RETURN
 #define HANDLE_MESSAGE_W_RETURN_NO_ARG(ENUM_NAME, METHOD_NAME) \
   case ENUM_NAME: {                                            \
diff --git a/host/commands/secure_env/proxy_keymaster_context.h b/host/commands/secure_env/proxy_keymaster_context.h
index c3c93fc..e3bf426 100644
--- a/host/commands/secure_env/proxy_keymaster_context.h
+++ b/host/commands/secure_env/proxy_keymaster_context.h
@@ -97,6 +97,10 @@
     return wrapped_.enforcement_policy();
   }
 
+  keymaster::AttestationContext* attestation_context() override {
+    return wrapped_.attestation_context();
+  }
+
   keymaster::CertificateChain GenerateAttestation(
       const keymaster::Key& key,
       const keymaster::AuthorizationSet& attest_params,
diff --git a/host/commands/secure_env/tpm_keymaster_context.h b/host/commands/secure_env/tpm_keymaster_context.h
index afd8f6f..dbcdcb4 100644
--- a/host/commands/secure_env/tpm_keymaster_context.h
+++ b/host/commands/secure_env/tpm_keymaster_context.h
@@ -92,6 +92,10 @@
 
   keymaster::KeymasterEnforcement* enforcement_policy() override;
 
+  keymaster::AttestationContext* attestation_context() override {
+    return attestation_context_.get();
+  }
+
   keymaster::CertificateChain GenerateAttestation(
       const keymaster::Key& key,
       const keymaster::AuthorizationSet& attest_params,
diff --git a/host/commands/secure_env/tpm_keymaster_enforcement.cpp b/host/commands/secure_env/tpm_keymaster_enforcement.cpp
index e73c57b..a5368c5 100644
--- a/host/commands/secure_env/tpm_keymaster_enforcement.cpp
+++ b/host/commands/secure_env/tpm_keymaster_enforcement.cpp
@@ -303,6 +303,24 @@
   return KM_ERROR_OK;
 }
 
+keymaster::KmErrorOr<std::array<uint8_t, 32>>
+TpmKeymasterEnforcement::ComputeHmac(
+    const std::vector<uint8_t>& data_to_mac) const {
+  std::array<uint8_t, 32> result;
+
+  const uint8_t* auth_token_key = nullptr;
+  uint32_t auth_token_key_len = 0;
+  if (!gatekeeper_.GetAuthTokenKey(&auth_token_key, &auth_token_key_len)) {
+    LOG(WARNING) << "Unable to get gatekeeper auth token";
+    return KM_ERROR_UNKNOWN_ERROR;
+  }
+
+  gatekeeper_.ComputeSignature(result.data(), result.size(), auth_token_key,
+                               auth_token_key_len, data_to_mac.data(),
+                               data_to_mac.size());
+  return result;
+}
+
 bool TpmKeymasterEnforcement::CreateKeyId(const keymaster_key_blob_t& key_blob,
                                           km_id_t* keyid) const {
   auto signing_key_builder = PrimaryKeyBuilder();
diff --git a/host/commands/secure_env/tpm_keymaster_enforcement.h b/host/commands/secure_env/tpm_keymaster_enforcement.h
index e1de8c7..1178932 100644
--- a/host/commands/secure_env/tpm_keymaster_enforcement.h
+++ b/host/commands/secure_env/tpm_keymaster_enforcement.h
@@ -54,6 +54,9 @@
   keymaster_error_t GenerateTimestampToken(
       keymaster::TimestampToken* token) override;
 
+  keymaster::KmErrorOr<std::array<uint8_t, 32>> ComputeHmac(
+      const std::vector<uint8_t>& data_to_mac) const override;
+
   bool CreateKeyId(const keymaster_key_blob_t& key_blob,
                    keymaster::km_id_t* keyid) const override;