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>