Implement secretkeeper HAL v2

Extend secretkeeper to include a method to query the key

Test: TH
Bug: 372223451
Change-Id: I6dbf473060dced3923d4b269f52ee9cc4377c509
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index e019902..0cdc992 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -304,7 +304,7 @@
     </hal>
     <hal format="aidl">
         <name>android.hardware.security.secretkeeper</name>
-        <version>1</version>
+        <version>1-2</version>
         <interface>
             <name>ISecretkeeper</name>
             <instance>default</instance>
diff --git a/security/secretkeeper/aidl/Android.bp b/security/secretkeeper/aidl/Android.bp
index d282621..f0b7894 100644
--- a/security/secretkeeper/aidl/Android.bp
+++ b/security/secretkeeper/aidl/Android.bp
@@ -25,7 +25,7 @@
         "android.hardware.security.authgraph-V1",
     ],
     stability: "vintf",
-    frozen: true,
+    frozen: false,
     backend: {
         java: {
             enabled: true,
@@ -88,6 +88,6 @@
 rust_defaults {
     name: "secretkeeper_use_latest_hal_aidl_rust",
     rustlibs: [
-        "android.hardware.security.secretkeeper-V1-rust",
+        "android.hardware.security.secretkeeper-V2-rust",
     ],
 }
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index 8ce37cd..ed48480 100644
--- a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -38,6 +38,7 @@
   byte[] processSecretManagementRequest(in byte[] request);
   void deleteIds(in android.hardware.security.secretkeeper.SecretId[] ids);
   void deleteAll();
+  android.hardware.security.secretkeeper.PublicKey getSecretkeeperIdentity();
   const int ERROR_UNKNOWN_KEY_ID = 1;
   const int ERROR_INTERNAL_ERROR = 2;
   const int ERROR_REQUEST_MALFORMED = 3;
diff --git a/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/PublicKey.aidl b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/PublicKey.aidl
new file mode 100644
index 0000000..f690abf
--- /dev/null
+++ b/security/secretkeeper/aidl/aidl_api/android.hardware.security.secretkeeper/current/android/hardware/security/secretkeeper/PublicKey.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024 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.secretkeeper;
+/* @hide */
+@VintfStability
+parcelable PublicKey {
+  byte[] keyMaterial;
+}
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
index b07dba8..91493a1 100644
--- a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
@@ -17,6 +17,7 @@
 package android.hardware.security.secretkeeper;
 
 import android.hardware.security.authgraph.IAuthGraphKeyExchange;
+import android.hardware.security.secretkeeper.PublicKey;
 import android.hardware.security.secretkeeper.SecretId;
 
 @VintfStability
@@ -101,4 +102,12 @@
      * Delete data of all clients.
      */
     void deleteAll();
+
+    /**
+     * Gets the public key of the secret keeper instance. This should be a CBOR-encoded
+     * COSE_Key, as a PubKeyEd25519 / PubKeyECDSA256 / PubKeyECDSA384, as defined in
+     * generateCertificateRequestV2.cddl. Clients must have a trusted way of ensuring
+     * this key is valid.
+     */
+    PublicKey getSecretkeeperIdentity();
 }
diff --git a/security/secretkeeper/aidl/android/hardware/security/secretkeeper/PublicKey.aidl b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/PublicKey.aidl
new file mode 100644
index 0000000..ccc89b3
--- /dev/null
+++ b/security/secretkeeper/aidl/android/hardware/security/secretkeeper/PublicKey.aidl
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 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.secretkeeper;
+
+/**
+ * Contents of a pubkey.
+ * @hide
+ */
+@VintfStability
+parcelable PublicKey {
+    /**
+     * CBOR-encoded COSE_Key
+     */
+    byte[] keyMaterial;
+}
diff --git a/security/secretkeeper/aidl/vts/Android.bp b/security/secretkeeper/aidl/vts/Android.bp
index be07a7b..c84afae 100644
--- a/security/secretkeeper/aidl/vts/Android.bp
+++ b/security/secretkeeper/aidl/vts/Android.bp
@@ -38,6 +38,7 @@
     srcs: ["secretkeeper_test_client.rs"],
     defaults: [
         "rdroidtest.defaults",
+        "secretkeeper_use_latest_hal_aidl_rust",
     ],
     test_suites: [
         "general-tests",
@@ -45,7 +46,6 @@
     ],
     test_config: "AndroidTest.xml",
     rustlibs: [
-        "android.hardware.security.secretkeeper-V1-rust",
         "libauthgraph_boringssl",
         "libauthgraph_core",
         "libauthgraph_wire",
@@ -66,9 +66,10 @@
 rust_binary {
     name: "secretkeeper_cli",
     srcs: ["secretkeeper_cli.rs"],
+    defaults: ["secretkeeper_use_latest_hal_aidl_rust"],
     lints: "android",
-    rlibs: [
-        "android.hardware.security.secretkeeper-V1-rust",
+    prefer_rlib: true,
+    rustlibs: [
         "libanyhow",
         "libauthgraph_boringssl",
         "libauthgraph_core",
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index 449a99a..b944865 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -16,6 +16,7 @@
 
 use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::ISecretkeeper;
 use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::SecretId::SecretId;
+use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::PublicKey::PublicKey;
 use authgraph_vts_test as ag_vts;
 use authgraph_boringssl as boring;
 use authgraph_core::key;
@@ -70,20 +71,32 @@
     0x06, 0xAC, 0x36, 0x8B, 0x3C, 0x95, 0x50, 0x16, 0x67, 0x71, 0x65, 0x26, 0xEB, 0xD0, 0xC3, 0x98,
 ]);
 
-// Android expects the public key of Secretkeeper instance to be present in the Linux device tree.
+// Android expects the public key of Secretkeeper instance to be available either
+// a) by being present in the Linux device tree (prior to version 2 of the secretkeeper HAL), or
+// b) via the `getSecretKeeperIdentity` operation from v2 onwards.
 // This allows clients to (cryptographically) verify that they are indeed talking to the real
 // secretkeeper.
 // Note that this is the identity of the `default` instance (and not `nonsecure`)!
-fn get_secretkeeper_identity() -> Option<CoseKey> {
-    let path = Path::new(SECRETKEEPER_KEY_HOST_DT);
-    if path.exists() {
-        let key = fs::read(path).unwrap();
-        let mut key = CoseKey::from_slice(&key).unwrap();
-        key.canonicalize(CborOrdering::Lexicographic);
-        Some(key)
+fn get_secretkeeper_identity(instance: &str) -> Option<CoseKey> {
+    let sk = get_connection(instance);
+    let key_material = if sk.getInterfaceVersion().expect("Error getting sk interface version") >= 2 {
+        let PublicKey { keyMaterial } = sk.getSecretkeeperIdentity().expect("Error calling getSecretkeeperIdentity");
+        Some(keyMaterial)
     } else {
-        None
-    }
+        let path = Path::new(SECRETKEEPER_KEY_HOST_DT);
+        if path.exists() {
+            let key_material = fs::read(path).unwrap();
+            Some(key_material)
+        } else {
+            None
+        }
+    };
+
+    key_material.map(|km| {
+        let mut cose_key = CoseKey::from_slice(&km).expect("Error deserializing CoseKey from key material");
+        cose_key.canonicalize(CborOrdering::Lexicographic);
+        cose_key
+    })
 }
 
 fn get_instances() -> Vec<(String, String)> {
@@ -760,12 +773,12 @@
 }
 
 // This test checks that the identity of Secretkeeper (in context of AuthGraph key exchange) is
-// same as the one advertized in Linux device tree. This is only expected from `default` instance.
+// same as the one either a) advertized in Linux device tree or b) retrieved from SK itself
+// from (HAL v2 onwards). This is only expected from `default` instance.
 #[rdroidtest(get_instances())]
-#[ignore_if(|p| p != "default")]
 fn secretkeeper_check_identity(instance: String) {
-    let sk_key = get_secretkeeper_identity()
-        .expect("Failed to extract identity of default instance from device tree");
+    let sk_key = get_secretkeeper_identity(&instance)
+        .expect("Failed to extract identity of default instance");
     // Create a session with this expected identity. This succeeds only if the identity used by
     // Secretkeeper is sk_key.
     let _ = SkClient::with_expected_sk_identity(&instance, sk_key).unwrap();
diff --git a/security/secretkeeper/default/Android.bp b/security/secretkeeper/default/Android.bp
index 799188f..134afc9 100644
--- a/security/secretkeeper/default/Android.bp
+++ b/security/secretkeeper/default/Android.bp
@@ -28,9 +28,9 @@
     vendor_available: true,
     defaults: [
         "authgraph_use_latest_hal_aidl_rust",
+        "secretkeeper_use_latest_hal_aidl_rust",
     ],
     rustlibs: [
-        "android.hardware.security.secretkeeper-V1-rust",
         "libauthgraph_boringssl",
         "libauthgraph_core",
         "libauthgraph_hal",
@@ -50,9 +50,9 @@
     prefer_rlib: true,
     defaults: [
         "authgraph_use_latest_hal_aidl_rust",
+        "secretkeeper_use_latest_hal_aidl_rust",
     ],
     rustlibs: [
-        "android.hardware.security.secretkeeper-V1-rust",
         "libandroid_logger",
         "libbinder_rs",
         "liblog_rust",
diff --git a/security/secretkeeper/default/secretkeeper.xml b/security/secretkeeper/default/secretkeeper.xml
index 40aebe0..699fff0 100644
--- a/security/secretkeeper/default/secretkeeper.xml
+++ b/security/secretkeeper/default/secretkeeper.xml
@@ -19,7 +19,7 @@
 
     <hal format="aidl">
         <name>android.hardware.security.secretkeeper</name>
-        <version>1</version>
+        <version>2</version>
         <interface>
             <name>ISecretkeeper</name>
             <instance>nonsecure</instance>