Merge "IRemotelyProvisionedComponent returns DeviceInfo" am: 459bf52740 am: 081ed8f3c4

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1650665

Change-Id: Ie4c088aba3e0bb332153e01671c1151e4f955504
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/DeviceInfo.aidl
new file mode 100644
index 0000000..d04d49c
--- /dev/null
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/DeviceInfo.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.security.keymint;
+/* @hide */
+@VintfStability
+parcelable DeviceInfo {
+  byte[] deviceInfo;
+}
diff --git a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 63bad2c..88c479c 100644
--- a/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/keymint/aidl/aidl_api/android.hardware.security.keymint/current/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -36,7 +36,7 @@
 @VintfStability
 interface IRemotelyProvisionedComponent {
   byte[] generateEcdsaP256KeyPair(in boolean testMode, out android.hardware.security.keymint.MacedPublicKey macedPublicKey);
-  void generateCertificateRequest(in boolean testMode, in android.hardware.security.keymint.MacedPublicKey[] keysToSign, in byte[] endpointEncryptionCertChain, in byte[] challenge, out byte[] keysToSignMac, out android.hardware.security.keymint.ProtectedData protectedData);
+  byte[] generateCertificateRequest(in boolean testMode, in android.hardware.security.keymint.MacedPublicKey[] keysToSign, in byte[] endpointEncryptionCertChain, in byte[] challenge, out android.hardware.security.keymint.DeviceInfo deviceInfo, out android.hardware.security.keymint.ProtectedData protectedData);
   const int STATUS_FAILED = 1;
   const int STATUS_INVALID_MAC = 2;
   const int STATUS_PRODUCTION_KEY_IN_TEST_REQUEST = 3;
diff --git a/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
new file mode 100644
index 0000000..3ea14a1
--- /dev/null
+++ b/security/keymint/aidl/android/hardware/security/keymint/DeviceInfo.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.security.keymint;
+
+/**
+ * DeviceInfo contains information about the device that's fed in as AAD in the signature of the
+ * device private key over the MAC key used for the bundle of public keys. These values are intended
+ * to be checked by the server to verify that the certificate signing request crafted by
+ * an IRemotelyProvisionedComponent HAL instance is coming from the expected device based
+ * on values initially uploaded during device manufacture in the factory.
+ * @hide
+ */
+@VintfStability
+parcelable DeviceInfo {
+    /**
+     * DeviceInfo is a CBOR Map structure described by the following CDDL.
+     *
+     *     DeviceInfo = {
+     *         ? "brand" : tstr,
+     *         ? "manufacturer" : tstr,
+     *         ? "product" : tstr,
+     *         ? "model" : tstr,
+     *         ? "board" : tstr,
+     *         ? "vb_state" : "green" / "yellow" / "orange",    // Taken from the AVB values
+     *         ? "bootloader_state" : "locked" / "unlocked",    // Taken from the AVB values
+     *         ? "os_version" : tstr,                    // Same as android.os.Build.VERSION.release
+     *         ? "system_patch_level" : uint,                   // YYYYMMDD
+     *         ? "boot_patch_level" : uint,                     // YYYYMMDD
+     *         ? "vendor_patch_level" : uint,                   // YYYYMMDD
+     *     }
+     */
+    byte[] deviceInfo;
+}
diff --git a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
index 5c8ca6d..1cb50ba 100644
--- a/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
+++ b/security/keymint/aidl/android/hardware/security/keymint/IRemotelyProvisionedComponent.aidl
@@ -16,6 +16,7 @@
 
 package android.hardware.security.keymint;
 
+import android.hardware.security.keymint.DeviceInfo;
 import android.hardware.security.keymint.MacedPublicKey;
 import android.hardware.security.keymint.ProtectedData;
 
@@ -257,7 +258,7 @@
      * @param out ProtectedData contains the encrypted BCC and the ephemeral MAC key used to
      *        authenticate the keysToSign (see keysToSignMac output argument).
      */
-    void generateCertificateRequest(in boolean testMode, in MacedPublicKey[] keysToSign,
-            in byte[] endpointEncryptionCertChain, in byte[] challenge, out byte[] keysToSignMac,
+    byte[] generateCertificateRequest(in boolean testMode, in MacedPublicKey[] keysToSign,
+            in byte[] endpointEncryptionCertChain, in byte[] challenge, out DeviceInfo deviceInfo,
             out ProtectedData protectedData);
 }
diff --git a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp b/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
index 749f0bc..4dbaa05 100644
--- a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
+++ b/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
@@ -322,8 +322,8 @@
 
 ScopedAStatus RemotelyProvisionedComponent::generateCertificateRequest(
         bool testMode, const vector<MacedPublicKey>& keysToSign,
-        const bytevec& endpointEncCertChain, const bytevec& challenge, bytevec* keysToSignMac,
-        ProtectedData* protectedData) {
+        const bytevec& endpointEncCertChain, const bytevec& challenge, DeviceInfo* deviceInfo,
+        ProtectedData* protectedData, bytevec* keysToSignMac) {
     auto pubKeysToSign = validateAndExtractPubkeys(testMode, keysToSign,
                                                    testMode ? remote_prov::kTestMacKey : macKey_);
     if (!pubKeysToSign.isOk()) return pubKeysToSign.moveError();
@@ -343,11 +343,12 @@
         bcc = bcc_.clone();
     }
 
+    deviceInfo->deviceInfo = createDeviceInfo();
     auto signedMac = constructCoseSign1(devicePrivKey /* Signing key */,  //
                                         ephemeralMacKey /* Payload */,
                                         cppbor::Array() /* AAD */
                                                 .add(challenge)
-                                                .add(createDeviceInfo())
+                                                .add(deviceInfo->deviceInfo)
                                                 .encode());
     if (!signedMac) return Status(signedMac.moveMessage());
 
diff --git a/security/keymint/aidl/default/RemotelyProvisionedComponent.h b/security/keymint/aidl/default/RemotelyProvisionedComponent.h
index e8d2343..65b1bbc 100644
--- a/security/keymint/aidl/default/RemotelyProvisionedComponent.h
+++ b/security/keymint/aidl/default/RemotelyProvisionedComponent.h
@@ -39,8 +39,8 @@
                                              const std::vector<MacedPublicKey>& keysToSign,
                                              const std::vector<uint8_t>& endpointEncCertChain,
                                              const std::vector<uint8_t>& challenge,
-                                             std::vector<uint8_t>* keysToSignMac,
-                                             ProtectedData* protectedData) override;
+                                             DeviceInfo* deviceInfo, ProtectedData* protectedData,
+                                             std::vector<uint8_t>* keysToSignMac) override;
 
   private:
     // TODO(swillden): Move these into an appropriate Context class.
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 50e6cce..9b797de 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -227,11 +227,12 @@
 TEST_P(CertificateRequestTest, EmptyRequest_testMode) {
     bool testMode = true;
     bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto challenge = randomBytes(32);
-    auto status = provisionable_->generateCertificateRequest(testMode, {} /* keysToSign */,
-                                                             eekChain_.chain, challenge,
-                                                             &keysToSignMac, &protectedData);
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, eekChain_.chain, challenge, &deviceInfo, &protectedData,
+            &keysToSignMac);
     ASSERT_TRUE(status.isOk()) << status.getMessage();
 
     auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData);
@@ -297,11 +298,12 @@
 TEST_P(CertificateRequestTest, EmptyRequest_prodMode) {
     bool testMode = false;
     bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto challenge = randomBytes(32);
-    auto status = provisionable_->generateCertificateRequest(testMode, {} /* keysToSign */,
-                                                             eekChain_.chain, challenge,
-                                                             &keysToSignMac, &protectedData);
+    auto status = provisionable_->generateCertificateRequest(
+            testMode, {} /* keysToSign */, eekChain_.chain, challenge, &deviceInfo, &protectedData,
+            &keysToSignMac);
     ASSERT_FALSE(status.isOk());
     ASSERT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
 }
@@ -314,10 +316,12 @@
     generateKeys(testMode, 4 /* numKeys */);
 
     bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto challenge = randomBytes(32);
-    auto status = provisionable_->generateCertificateRequest(
-            testMode, keysToSign_, eekChain_.chain, challenge, &keysToSignMac, &protectedData);
+    auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, eekChain_.chain,
+                                                             challenge, &deviceInfo, &protectedData,
+                                                             &keysToSignMac);
     ASSERT_TRUE(status.isOk()) << status.getMessage();
 
     auto [parsedProtectedData, _, protDataErrMsg] = cppbor::parse(protectedData.protectedData);
@@ -384,10 +388,12 @@
     generateKeys(testMode, 4 /* numKeys */);
 
     bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto challenge = randomBytes(32);
-    auto status = provisionable_->generateCertificateRequest(
-            testMode, keysToSign_, eekChain_.chain, challenge, &keysToSignMac, &protectedData);
+    auto status = provisionable_->generateCertificateRequest(testMode, keysToSign_, eekChain_.chain,
+                                                             challenge, &deviceInfo, &protectedData,
+                                                             &keysToSignMac);
     ASSERT_FALSE(status.isOk());
     ASSERT_EQ(status.getServiceSpecificError(), BnRemotelyProvisionedComponent::STATUS_INVALID_EEK);
 }
@@ -400,11 +406,12 @@
     generateKeys(false /* testMode */, 2 /* numKeys */);
 
     bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto challenge = randomBytes(32);
-    auto status = provisionable_->generateCertificateRequest(true /* testMode */, keysToSign_,
-                                                             eekChain_.chain, challenge,
-                                                             &keysToSignMac, &protectedData);
+    auto status = provisionable_->generateCertificateRequest(
+            true /* testMode */, keysToSign_, eekChain_.chain, challenge, &deviceInfo,
+            &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk());
     ASSERT_EQ(status.getServiceSpecificError(),
               BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST);
@@ -418,10 +425,11 @@
     generateKeys(true /* testMode */, 2 /* numKeys */);
 
     bytevec keysToSignMac;
+    DeviceInfo deviceInfo;
     ProtectedData protectedData;
     auto status = provisionable_->generateCertificateRequest(
             false /* testMode */, keysToSign_, eekChain_.chain, randomBytes(32) /* challenge */,
-            &keysToSignMac, &protectedData);
+            &deviceInfo, &protectedData, &keysToSignMac);
     ASSERT_FALSE(status.isOk());
     ASSERT_EQ(status.getServiceSpecificError(),
               BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST);