Trusty IRemotelyProvisionedComponent v3 TA implementation

Introduce TRUSTY_KM_RKP_VERSION build flag to build older versions of
RKP. This flag defaults to the latest version (currently, 3).

Bug: 235265072
Test: atest VtsHalRemotelyProvisionedComponentTargetTest
Change-Id: I7104a7c2cfa6155f530b6edf4e7f7d60382a3c39
diff --git a/ipc/keymaster_ipc.cpp b/ipc/keymaster_ipc.cpp
index 5c3bd6c..bcaf2ab 100644
--- a/ipc/keymaster_ipc.cpp
+++ b/ipc/keymaster_ipc.cpp
@@ -611,6 +611,11 @@
         return do_dispatch(&TrustyKeymaster::GenerateCsr, msg, payload_size,
                            out, out_size);
 
+    case KM_GENERATE_CSR_V2:
+        LOG_D("Dispatching KM_GENERATE_CSR_V2, size %d", payload_size);
+        return do_dispatch(&TrustyKeymaster::GenerateCsrV2, msg, payload_size,
+                           out, out_size);
+
     case KM_CONFIGURE_VENDOR_PATCHLEVEL:
         LOG_D("Dispatching KM_CONFIGURE_VENDOR_PATCHLEVEL, size %d",
               payload_size);
diff --git a/ipc/keymaster_ipc.h b/ipc/keymaster_ipc.h
index bac8ae9..b7706b1 100644
--- a/ipc/keymaster_ipc.h
+++ b/ipc/keymaster_ipc.h
@@ -61,6 +61,7 @@
     KM_CONFIGURE_VENDOR_PATCHLEVEL = (33 << KEYMASTER_REQ_SHIFT),
     KM_GET_ROOT_OF_TRUST = (34 << KEYMASTER_REQ_SHIFT),
     KM_GET_HW_INFO = (35 << KEYMASTER_REQ_SHIFT),
+    KM_GENERATE_CSR_V2 = (36 << KEYMASTER_REQ_SHIFT),
 
     // Bootloader calls.
     KM_SET_BOOT_PARAMS = (0x1000 << KEYMASTER_REQ_SHIFT),
diff --git a/rules.mk b/rules.mk
index b9dc790..e8df11e 100644
--- a/rules.mk
+++ b/rules.mk
@@ -165,6 +165,11 @@
 
 endif
 
+TRUSTY_KM_RKP_VERSION ?= 3
+ifdef TRUSTY_KM_RKP_VERSION
+    MODULE_COMPILEFLAGS += -DTRUSTY_KM_RKP_VERSION=$(TRUSTY_KM_RKP_VERSION)
+endif
+
 include $(LOCAL_DIR)/atap/rules.mk
 include $(LOCAL_DIR)/ipc/rules.mk
 
diff --git a/trusty_remote_provisioning_context.cpp b/trusty_remote_provisioning_context.cpp
index bb4991d..5315ded 100644
--- a/trusty_remote_provisioning_context.cpp
+++ b/trusty_remote_provisioning_context.cpp
@@ -43,6 +43,7 @@
 using cppcose::VERIFY;
 
 constexpr uint32_t kMacKeyLength = 32;
+constexpr uint32_t kRkpVersion = TRUSTY_KM_RKP_VERSION;
 
 static const uint8_t kMasterKeyDerivationData[kMacKeyLength] =
         "RemoteKeyProvisioningMasterKey";
@@ -143,7 +144,7 @@
                                      ? 0
                                      : 1);
         result->add("security_level", "tee");
-        result->add("version", 2);
+        result->add("version", kRkpVersion);
     }
 
     result->canonicalize();
@@ -189,10 +190,46 @@
 
 void TrustyRemoteProvisioningContext::GetHwInfo(
         GetHwInfoResponse* hwInfo) const {
-    hwInfo->version = 2;
+    hwInfo->version = kRkpVersion;
     hwInfo->rpcAuthorName = "Google";
     hwInfo->supportedEekCurve = 2 /* CURVE_25519 */;
-    hwInfo->uniqueId = "Google Trusty Default Implementation";
+    hwInfo->uniqueId = "Google Trusty Implementation";
+}
+
+cppcose::ErrMsgOr<cppbor::Array> TrustyRemoteProvisioningContext::BuildCsr(
+        const std::vector<uint8_t>& challenge,
+        cppbor::Array keysToSign) const {
+    auto deviceInfo = std::move(*CreateDeviceInfo());
+    auto signedDataPayload = cppbor::Array()
+                                     .add(1 /* version */)
+                                     .add("keymint" /* CertificateType */)
+                                     .add(std::move(deviceInfo))
+                                     .add(challenge)
+                                     .add(std::move(keysToSign))
+                                     .encode();
+
+    std::vector<uint8_t> signedData(HWBCC_MAX_RESP_PAYLOAD_SIZE);
+    std::vector<uint8_t> bcc(HWBCC_MAX_RESP_PAYLOAD_SIZE);
+    size_t actualSignedDataSize = 0;
+    size_t actualBccSize = 0;
+
+    int rc = hwbcc_get_protected_data(
+            false /* test_mode */, EDDSA, signedDataPayload.data(),
+            signedDataPayload.size(), NULL, 0, signedData.data(),
+            signedData.size(), &actualSignedDataSize, bcc.data(), bcc.size(),
+            &actualBccSize);
+    if (rc != 0) {
+        LOG_E("Error: [%d] Failed hwbcc_get_protected_data()", rc);
+        return "Failed hwbcc_get_protected_data";
+    }
+    signedData.resize(actualSignedDataSize);
+    bcc.resize(actualBccSize);
+
+    return cppbor::Array()
+            .add(3 /* version */)
+            .add(cppbor::Map() /* UdsCerts */)
+            .add(cppbor::EncodedItem(std::move(bcc)))
+            .add(cppbor::EncodedItem(std::move(signedData)));
 }
 
 void TrustyRemoteProvisioningContext::SetBootParams(
diff --git a/trusty_remote_provisioning_context.h b/trusty_remote_provisioning_context.h
index a57688e..28ea072 100644
--- a/trusty_remote_provisioning_context.h
+++ b/trusty_remote_provisioning_context.h
@@ -50,6 +50,10 @@
     std::optional<cppcose::HmacSha256> GenerateHmacSha256(
             const cppcose::bytevec& input) const override;
     void GetHwInfo(GetHwInfoResponse* hwInfo) const override;
+    cppcose::ErrMsgOr<cppbor::Array> BuildCsr(
+            const std::vector<uint8_t>& challenge,
+            cppbor::Array keysToSign) const override;
+
     void SetBootParams(const BootParams* bootParams);
     void SetVendorPatchlevel(uint32_t vendor_patchlevel) {
         vendor_patchlevel_ = vendor_patchlevel;