From 0e2495f107d3df9dc907f4e372d8d8e2c5405dbf Mon Sep 17 00:00:00 2001 From: Hasini Gunasinghe Date: Wed, 31 May 2023 01:41:26 +0000 Subject: [PATCH 1/4] Define the AIDL interface for AuthGraph key exchange. Introduce the AIDL methods for key exchange and the CDDLs for the relevant input/output types that are CBOR encoded. Use a standard comment format in CDDL files to indicate where additional structure definitions can be found, in the hope that one day tooling will be available to automatically check schema syntax. Add authgraph to compatibility matrix This CL merges the CLs: aosp/2750484, aosp/2750485, aosp/2750486 by drysdale@google.com Co-authored-by: David Drysdale Bug: 284470121 Test: validate schemas with https://cddl.anweiss.tech/ Test: VtsAidlAuthGraphSessionTest (with nonsecure default impl) Change-Id: I2793666ede028f8abe91569587c09dcac21c67e0 --- .../compatibility_matrix.9.xml | 8 + security/authgraph/aidl/Android.bp | 47 ++++ .../hardware/security/authgraph/Arc.aidl | 39 ++++ .../hardware/security/authgraph/Error.aidl | 50 ++++ .../authgraph/IAuthGraphKeyExchange.aidl | 42 ++++ .../hardware/security/authgraph/Identity.aidl | 38 +++ .../security/authgraph/KeInitResult.aidl | 39 ++++ .../hardware/security/authgraph/Key.aidl | 39 ++++ .../security/authgraph/PlainPubKey.aidl | 38 +++ .../hardware/security/authgraph/PubKey.aidl | 39 ++++ .../authgraph/SessionIdSignature.aidl | 38 +++ .../security/authgraph/SessionInfo.aidl | 40 ++++ .../authgraph/SessionInitiationInfo.aidl | 41 ++++ .../security/authgraph/SignedPubKey.aidl | 38 +++ .../hardware/security/authgraph/Arc.aidl | 34 +++ .../hardware/security/authgraph/Arc.cddl | 115 ++++++++++ .../security/authgraph/DicePolicy.cddl | 33 +++ .../hardware/security/authgraph/Error.aidl | 51 +++++ .../authgraph/ExplicitKeyDiceCertChain.cddl | 30 +++ .../authgraph/IAuthGraphKeyExchange.aidl | 216 ++++++++++++++++++ .../hardware/security/authgraph/Identity.aidl | 43 ++++ .../hardware/security/authgraph/Identity.cddl | 23 ++ .../security/authgraph/KeInitResult.aidl | 37 +++ .../hardware/security/authgraph/Key.aidl | 41 ++++ .../security/authgraph/PlainPubKey.aidl | 28 +++ .../security/authgraph/PlainPubKey.cddl | 24 ++ .../hardware/security/authgraph/PubKey.aidl | 37 +++ .../authgraph/SessionIdSignature.aidl | 28 +++ .../authgraph/SessionIdSignature.cddl | 33 +++ .../security/authgraph/SessionInfo.aidl | 50 ++++ .../authgraph/SessionInitiationInfo.aidl | 69 ++++++ .../security/authgraph/SignedPubKey.aidl | 28 +++ .../security/authgraph/SignedPubKey.cddl | 41 ++++ 33 files changed, 1497 insertions(+) create mode 100644 security/authgraph/aidl/Android.bp create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Arc.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Error.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Identity.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/KeInitResult.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Key.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/PlainPubKey.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/PubKey.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionIdSignature.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionInfo.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionInitiationInfo.aidl create mode 100644 security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SignedPubKey.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/Arc.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/Arc.cddl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/DicePolicy.cddl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/Error.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/Identity.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/Identity.cddl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/KeInitResult.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/Key.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/PlainPubKey.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/PlainPubKey.cddl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/PubKey.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/SessionIdSignature.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/SessionIdSignature.cddl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/SessionInfo.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/SessionInitiationInfo.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/SignedPubKey.aidl create mode 100644 security/authgraph/aidl/android/hardware/security/authgraph/SignedPubKey.cddl diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml index da318886a5..b348d350fd 100644 --- a/compatibility_matrices/compatibility_matrix.9.xml +++ b/compatibility_matrices/compatibility_matrix.9.xml @@ -508,6 +508,14 @@ SIM[1-9][0-9]* + + android.hardware.security.authgraph + 1 + + IAuthGraphKeyExchange + default + + android.hardware.security.secureclock 1 diff --git a/security/authgraph/aidl/Android.bp b/security/authgraph/aidl/Android.bp new file mode 100644 index 0000000000..373d0c4be8 --- /dev/null +++ b/security/authgraph/aidl/Android.bp @@ -0,0 +1,47 @@ +// Copyright (C) 2023 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +aidl_interface { + name: "android.hardware.security.authgraph", + vendor_available: true, + srcs: [ + "android/hardware/security/authgraph/*.aidl", + ], + stability: "vintf", + frozen: false, + backend: { + java: { + platform_apis: true, + }, + ndk: { + apps_enabled: false, + }, + rust: { + enabled: true, + apex_available: [ + "//apex_available:platform", + "com.android.virt", + ], + }, + }, +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Arc.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Arc.aidl new file mode 100644 index 0000000000..dc86fbd5b8 --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Arc.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +/* @hide */ +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +parcelable Arc { + byte[] arc; +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Error.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Error.aidl new file mode 100644 index 0000000000..1a78b54550 --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Error.aidl @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +/* @hide */ +@Backing(type="int") @VintfStability +enum Error { + OK = 0, + INVALID_PEER_NONCE = (-1) /* -1 */, + INVALID_PEER_KE_KEY = (-2) /* -2 */, + INVALID_IDENTITY = (-3) /* -3 */, + INVALID_CERT_CHAIN = (-4) /* -4 */, + INVALID_SIGNATURE = (-5) /* -5 */, + INVALID_KE_KEY = (-6) /* -6 */, + INVALID_PUB_KEY_IN_KEY = (-7) /* -7 */, + INVALID_PRIV_KEY_ARC_IN_KEY = (-8) /* -8 */, + INVALID_SHARED_KEY_ARCS = (-9) /* -9 */, + MEMORY_ALLOCATION_FAILED = (-10) /* -10 */, + INCOMPATIBLE_PROTOCOL_VERSION = (-11) /* -11 */, +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl new file mode 100644 index 0000000000..2c56f339dd --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +/* @hide */ +@VintfStability +interface IAuthGraphKeyExchange { + android.hardware.security.authgraph.SessionInitiationInfo create(); + android.hardware.security.authgraph.KeInitResult init(in android.hardware.security.authgraph.PubKey peerPubKey, in android.hardware.security.authgraph.Identity peerId, in byte[] peerNonce, in int peerVersion); + android.hardware.security.authgraph.SessionInfo finish(in android.hardware.security.authgraph.PubKey peerPubKey, in android.hardware.security.authgraph.Identity peerId, in android.hardware.security.authgraph.SessionIdSignature peerSignature, in byte[] peerNonce, in int peerVersion, in android.hardware.security.authgraph.Key ownKey); + android.hardware.security.authgraph.Arc[2] authenticationComplete(in android.hardware.security.authgraph.SessionIdSignature peerSignature, in android.hardware.security.authgraph.Arc[2] sharedKeys); +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Identity.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Identity.aidl new file mode 100644 index 0000000000..bd5453ee82 --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Identity.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +parcelable Identity { + byte[] identity; +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/KeInitResult.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/KeInitResult.aidl new file mode 100644 index 0000000000..8c91523784 --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/KeInitResult.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +parcelable KeInitResult { + android.hardware.security.authgraph.SessionInitiationInfo sessionInitiationInfo; + android.hardware.security.authgraph.SessionInfo sessionInfo; +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Key.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Key.aidl new file mode 100644 index 0000000000..5b4ebbf923 --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/Key.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +parcelable Key { + @nullable android.hardware.security.authgraph.PubKey pubKey; + @nullable android.hardware.security.authgraph.Arc arcFromPBK; +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/PlainPubKey.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/PlainPubKey.aidl new file mode 100644 index 0000000000..f070bfaef4 --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/PlainPubKey.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +parcelable PlainPubKey { + byte[] plainPubKey; +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/PubKey.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/PubKey.aidl new file mode 100644 index 0000000000..4c3376eb4d --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/PubKey.aidl @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +union PubKey { + android.hardware.security.authgraph.PlainPubKey plainKey; + android.hardware.security.authgraph.SignedPubKey signedKey; +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionIdSignature.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionIdSignature.aidl new file mode 100644 index 0000000000..6dabc0a080 --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionIdSignature.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +parcelable SessionIdSignature { + byte[] signature; +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionInfo.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionInfo.aidl new file mode 100644 index 0000000000..427962b5b2 --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionInfo.aidl @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +parcelable SessionInfo { + android.hardware.security.authgraph.Arc[2] sharedKeys; + byte[] sessionId; + android.hardware.security.authgraph.SessionIdSignature signature; +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionInitiationInfo.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionInitiationInfo.aidl new file mode 100644 index 0000000000..bf55e74a2a --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SessionInitiationInfo.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +parcelable SessionInitiationInfo { + android.hardware.security.authgraph.Key key; + android.hardware.security.authgraph.Identity identity; + byte[] nonce; + int version; +} diff --git a/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SignedPubKey.aidl b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SignedPubKey.aidl new file mode 100644 index 0000000000..3dbaed81b8 --- /dev/null +++ b/security/authgraph/aidl/aidl_api/android.hardware.security.authgraph/current/android/hardware/security/authgraph/SignedPubKey.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 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 -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.authgraph; +@RustDerive(Clone=true, Eq=true, PartialEq=true) @VintfStability +parcelable SignedPubKey { + byte[] signedPubKey; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/Arc.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/Arc.aidl new file mode 100644 index 0000000000..855ce5c5c4 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/Arc.aidl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 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.authgraph; + +/** + * This is the definition of the data format of an Arc. + * @hide + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +parcelable Arc { + /** + * The messages exchanged between the domains in the AuthGraph protocol are called Arcs. + * An arc is simply AES-GCM. Encryption of a payload P with a key K and additional + * authentication data (AAD) D: (i.e. Arc = Enc(K, P, D)). + * + * Data is CBOR-encoded according to the `Arc` CDDL definition in Arc.cddl. + */ + byte[] arc; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/Arc.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/Arc.cddl new file mode 100644 index 0000000000..4c1b965ab1 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/Arc.cddl @@ -0,0 +1,115 @@ +; +; Copyright (C) 2023 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. +; +Arc = [ ; COSE_Encrypt0 [RFC9052 s5.2] + protected : bstr .cbor ArcProtectedHeaders, + unprotected : { + 5 : bstr .size 12 ; IV + }, + ciphertext : bstr ; Enc(K, bstr .cbor Payload, encoded ArcEncStruct) +] + +ArcProtectedHeaders = { + 1 : 3, ; Algorithm: AES-GCM mode w/ 256-bit key, 128-bit tag + ? -70001 : { + Permission }, ; One or more Permissions + ? -70002 : { + Limitation }, ; One or more Limitations + ? -70003 : int, ; Timestamp in milliseconds since some starting point (generally + ; the most recent device boot) which all of the applications within + ; the secure domain must agree upon + ? -70004 : bstr .size 16, ; Nonce used in key exchange methods + ? -70005 : PayloadType, ; Payload type, if needed to disambiguate, when processing an arc + ? -70006 : int, ; Version of the payload structure (if applicable) + ? -70007 : int, ; Sequence number (if needed to prevent replay attacks) + ? -70008 : Direction ; Direction of the encryption key (i.e. whether it is used to + ; encrypt incoming messages or outgoing messages) + ? -70009 : bool, ; "authentication_completed" - this is used during authenticated + ; key exchange indicate whether signature verification is done + ? -70010 : bstr .size 32 ; "session_id" computed during key exchange protocol +} + +; Permissions indicate what an arc can be used with. Permissions are added to an arc during the +; `create()` primitive operation and are propagated during `mint` and `snap` primitive operations. +Permission = &( + -4770552 : IdentityEncoded, ; "source_id" - in the operations performed by a source, the + ; source adds its own identity to the permissions of an arc. + -4770553 : IdentityEncoded, ; "sink_id" - in the operations performed by a sink, the sink + ; adds its own identity to the permissions of an arc. + -4770555 : [ +IdentityEncoded ] ; "minting_allowed" - defines the set of TA identities + ; to whom the payload key is allowed to be minted. + -4770556 : bool ; "deleted_on_biometric_change" - A Boolean value that + ; indicates whether an auth key issued from a biometric TA is + ; invalidated on new biometric enrollment or removal of all + ; biometrics. +) + +; Limitations indicate what restrictions are applied on the usage of an arc. Permissions are added +; to an arc during the `create` primitive operation and are propagated during `snap` primitive +; operation. +Limitation = &( + -4770554 : bstr, ; "challenge" - is added to an arc that transfers an auth key to a channel + ; key, in order to ensure the freshness of the authentication. + ; A challenge is issued by a sink (e.g. Keymint TA, Biometric TAs). +) + +; INCLUDE Identity.cddl for: Identity +IdentityEncoded = bstr .cbor Identity + +Direction = &( + In: 1, + Out: 2, +) + +PayloadType = &( + SecretKey: 1, + Arc: 2, + ; Any other payload types should also be defined here +) + +Payload = &( + SecretKey, + Arc, + ; Any other payload formats should also be defined here +) + +SecretKey = &( ; One of the payload types of an Arc is a secret key + SymmetricKey, + ECPrivateKey, ; Private key of a key pair generated for key exchange +) + +ECPrivateKey = { ; COSE_Key [RFC9052 s7] + 1 : 2, ; Key type : EC2 + 3 : -25, ; Algorithm: ECDH ES w/ HKDF 256 - generate key directly + ? 4 : [7], ; Key_ops: [derive key] + -1 : 1, ; Curve: P-256 + ? -2 : bstr, ; x coordinate + ? -3 : bstr, ; y coordinate + -4 : bstr, ; private key (d) +} + +SymmetricKey = { ; COSE_Key [RFC9052 s7] - For symmetric key encryption + 1 : 4, ; Key type : Symmetric + 3 : 3, ; Algorithm : AES-GCM mode w/ 256-bit key, 128-bit tag + 4 : [ 4 ], ; Key_ops: [decrypt] + -1 : bstr .size 32, ; Key value (k) +} + +ArcEncStruct = [ ; COSE_Enc_structure [RFC9052 s5.3] + context : "Encrypt0", + protected : bstr .cbor ArcProtectedHeaders, + external_aad : bstr .size 0, +] + +; INCLUDE generateCertificateRequestV2.cddl for: PubKeyEd25519, PubKeyECDSA256, PubKeyECDSA384 +; from hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/ diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/DicePolicy.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/DicePolicy.cddl new file mode 100644 index 0000000000..a7dcbc6ca0 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/DicePolicy.cddl @@ -0,0 +1,33 @@ +; +; Copyright (C) 2023 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. +; +DicePolicy = [ + 1, ; dice policy version + + nodeConstraintList ; for each entry in dice chain +] + +nodeConstraintList = [ + * nodeConstraint +] + +; We may add a hashConstraint item later +nodeConstraint = exactMatchConstraint / geConstraint + +exactMatchConstraint = [1, keySpec, value] +geConstraint = [2, keySpec, int] + +keySpec = [value+] + +value = bool / int / tstr / bstr \ No newline at end of file diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/Error.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/Error.aidl new file mode 100644 index 0000000000..1ad6054636 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/Error.aidl @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 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.authgraph; + +/** + * AuthGraph error codes. Aidl will return these error codes as service specific errors in + * EX_SERVICE_SPECIFIC. + * @hide + */ +@VintfStability +@Backing(type="int") +enum Error { + /* Success */ + OK = 0, + /* Invalid peer nonce for key exchange */ + INVALID_PEER_NONCE = -1, + /* Invalid key exchange public key by the peer */ + INVALID_PEER_KE_KEY = -2, + /* Invalid identity of the peer */ + INVALID_IDENTITY = -3, + /* Invalid certificate chain in the identity of the peer */ + INVALID_CERT_CHAIN = -4, + /* Invalid signature by the peer */ + INVALID_SIGNATURE = -5, + /* Invalid key exchange key created by a particular party themselves to be used as a handle */ + INVALID_KE_KEY = -6, + /* Invalid public key in the `Key` struct */ + INVALID_PUB_KEY_IN_KEY = -7, + /* Invalid private key arc in the `Key` struct */ + INVALID_PRIV_KEY_ARC_IN_KEY = -8, + /* Invalid shared key arcs */ + INVALID_SHARED_KEY_ARCS = -9, + /* Memory allocation failed */ + MEMORY_ALLOCATION_FAILED = -10, + /* The protocol version negotiated with the sink is incompatible */ + INCOMPATIBLE_PROTOCOL_VERSION = -11, +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl new file mode 100644 index 0000000000..3de5617028 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/ExplicitKeyDiceCertChain.cddl @@ -0,0 +1,30 @@ +; +; Copyright (C) 2023 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. +; +ExplicitKeyDiceCertChain = [ + 1, ; version, hopefully will never change + DiceCertChainInitialPayload, + * DiceChainEntry +] + +DiceCertChainInitialPayload = { + -4670552 : bstr .cbor PubKeyEd25519 / + bstr .cbor PubKeyECDSA256 / + bstr .cbor PubKeyECDSA384 ; subjectPublicKey +} + +; INCLUDE generateCertificateRequestV2.cddl for: PubKeyEd25519, PubKeyECDSA256, PubKeyECDSA384, +; DiceChainEntry +; from hardware/interfaces/security/rkp/aidl/android/hardware/security/keymint/ diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl new file mode 100644 index 0000000000..6ceb09cd08 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2023 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.authgraph; + +import android.hardware.security.authgraph.Arc; +import android.hardware.security.authgraph.Identity; +import android.hardware.security.authgraph.KeInitResult; +import android.hardware.security.authgraph.Key; +import android.hardware.security.authgraph.PubKey; +import android.hardware.security.authgraph.SessionIdSignature; +import android.hardware.security.authgraph.SessionInfo; +import android.hardware.security.authgraph.SessionInitiationInfo; + +/** + * AuthGraph interface definition for authenticated key exchange between two parties: P1 (source) + * and P2 (sink). + * Pre-requisites: each participant should have a: + * 1. Persistent identity - e.g. a signing key pair with a self signed certificate or a DICE + * certificate chain. + * 2. A symmetric encryption key kept in memory with per-boot life time of the participant + * (a.k.a per-boot key) + * + * ErrorCodes are defined in android.hardware.security.authgraph.ErrorCode.aidl. + * @hide + */ +@VintfStability +interface IAuthGraphKeyExchange { + /** + * This method is invoked on P1 (source). + * Create an ephermeral EC key pair on NIST curve P-256 and a nonce (of 16 bytes) for + * key exchange. + * + * @return SessionInitiationInfo including the `Key` containing the public key of the created + * key pair and an arc from the per-boot key to the private key, the nonce, the persistent + * identity and the latest protocol version (i.e. AIDL version) supported. + * + * Note: The arc from the per-boot key to the private key in `Key` of the return type: + * `SessionInitiationInfo` serves two purposes: + * i. A mapping to correlate `create` and `finish` calls to P1 in a particular instance of the + * key exchange protocol. + * ii.A way to minimize the in-memory storage (P1 can include the nonce in the protected headers + * of the arc). + * However, P1 should maintain some form of in-memory record to be able to verify that the input + * `Key` sent to `finish` is from an unfinished instance of a key exchange protocol, to prevent + * any replay attacks in `finish`. + */ + SessionInitiationInfo create(); + + /** + * This method is invoked on P2 (sink). + * Perform the following steps for key exchange: + * 0. If either `peerPubKey`, `peerId`, `peerNonce` is not in the expected format, return + * errors: INVALID_PEER_KE_KEY, INVALID_IDENTITY, INVALID_PEER_NONCE respectively. + * 1. Create an ephemeral EC key pair on NIST curve P-256. + * 2. Create a nonce (of 16 bytes). + * 3. Compute the diffie-hellman shared secret: Z. + * 4. Compute a salt = bstr .cbor [ + * source_version: int, ; from input `peerVersion` + * sink_pub_key: bstr .cbor PlainPubKey, ; from step #1 + * source_pub_key: bstr .cbor PlainPubKey, ; from input `peerPubKey` + * sink_nonce: bstr .size 16, ; from step #2 + * source_nonce: bstr .size 16, ; from input `peerNonce` + * sink_cert_chain: bstr .cbor ExplicitKeyDiceCertChain, ; from own identity + * source_cert_chain: bstr .cbor ExplicitKeyDiceCertChain, ; from input `peerId` + * ] + * 5. Extract a cryptographic secret S from Z, using the salt from #4 above. + * 6. Derive two symmetric encryption keys of 256 bits with: + * i. b"KE_ENCRYPTION_KEY_SOURCE_TO_SINK" as context for the key used to encrypt incoming + * messages + * ii. b"KE_ENCRYPTION_KEY_SINK_TO_SOURCE" as context for the key used to encrypt outgoing + * messages + * 7. Create arcs from the per-boot key to each of the two shared keys from step #6 and + * mark authentication_complete = false in arcs' protected headers. + * 8. Derive a MAC key with b"KE_HMAC_KEY" as the context. + * 9. Compute session_id_input = bstr .cbor [ + * sink_nonce: bstr .size 16, + * source_nonce: bstr .size 16, + * ], + * 10.Compute a session_id as a 256 bits HMAC over the session_id_input from step#9 with + * the key from step #8. + * 11.Create a signature over the session_id from step #10, using the signing key which is + * part of the party's identity. + * + * @param peerPubKey - the public key of the key pair created by the peer (P1) for key exchange + * + * @param peerId - the persistent identity of the peer + * + * @param peerNonce - nonce created by the peer + * + * @param peerVersion - an integer representing the latest protocol version (i.e. AIDL version) + * supported by the peer + * + * @return KeInitResult including the `Key` containing the public key of the created key pair, + * the nonce, the persistent identity, two shared key arcs from step #7, session id, signature + * over the session id and the negotiated protocol version. The negotiated protocol version + * should be less than or equal to the peer's version. + * + * Note: The two shared key arcs in the return type: `KeInitResult` serves two purposes: + * i. A mapping to correlate `init` and `authenticationComplete` calls to P2 in a particular + * instance of the key exchange protocol. + * ii.A way to minimize the in-memory storage of P2 allocated for key exchange. + * However, P2 should maintain some in-memory record to be able to verify that the input + * `sharedkeys` sent to `authenticationComplete` and to any subsequent AuthGraph protocol + * methods are valid shared keys agreed with the party identified by `peerId`, to prevent + * any replay attacks in `authenticationComplete` and in any subsequent AuthGraph protocol + * methods which use the shared keys to encrypt the secret messages. + */ + KeInitResult init( + in PubKey peerPubKey, in Identity peerId, in byte[] peerNonce, in int peerVersion); + + /** + * This method is invoked on P1 (source). + * Perform the following steps: + * 0. If either `peerPubKey`, `peerId`, `peerNonce` is not in the expected format, return + * errors: INVALID_PEER_KE_KEY, INVALID_IDENTITY, INVALID_PEER_NONCE respectively. If + * `peerVersion` is greater than the version advertised in `create`, return error: + * INCOMPATIBLE_PROTOCOL_VERSION. + * If `ownKey` is not in the in-memory records for unfinished instances of a key + * exchange protocol, return error: INVALID_KE_KEY. Similarly, if the public key or the + * arc containing the private key in `ownKey` is invalid, return INVALID_PUB_KEY_IN_KEY + * and INVALID_PRIV_KEY_ARC_IN_KEY respectively. + * 1. Compute the diffie-hellman shared secret: Z. + * 2. Compute a salt = bstr .cbor [ + * source_version: int, ; the protocol version used in `create` + * sink_pub_key: bstr .cbor PlainPubKey, ; from input `peerPubKey` + * source_pub_key: bstr .cbor PlainPubKey, ; from the output of `create` + * sink_nonce: bstr .size 16, ; from input `peerNonce` + * source_nonce: bstr .size 16, ; from the output of `create` + * sink_cert_chain: bstr .cbor ExplicitKeyDiceCertChain, ; from input `peerId` + * source_cert_chain: bstr .cbor ExplicitKeyDiceCertChain, ; from own identity + * ] + * 3. Extract a cryptographic secret S from Z, using the salt from #2 above. + * 4. Derive two symmetric encryption keys of 256 bits with: + * i. b"KE_ENCRYPTION_KEY_SOURCE_TO_SINK" as context for the key used to encrypt outgoing + * messages + * ii. b"KE_ENCRYPTION_KEY_SINK_TO_SOURCE" as context for the key used to encrypt incoming + * messages + * 5. Derive a MAC key with b"KE_HMAC_KEY" as the context. + * 6. Compute session_id_input = bstr .cbor [ + * sink_nonce: bstr .size 16, + * source_nonce: bstr .size 16, + * ], + * 7. Compute a session_id as a 256 bits HMAC over the session_id_input from step #6 with + * the key from step #5. + * 8. Verify the peer's signature over the session_id from step #7. If successful, proceed, + * otherwise, return error: INVALID_SIGNATURE. + * 9. Create arcs from the per-boot key to each of the two shared keys from step #4 and + * mark authentication_complete = true in arcs' protected headers. + * 10.Create a signature over the session_id from step #7, using the signing key which is + * part of the party's identity. + * + * @param peerPubKey - the public key of the key pair created by the peer (P2) for key exchange + * + * @param peerId - the persistent identity of the peer + * + * @param peerSignature - the signature created by the peer over the session id computed by the + * peer + * + * @param peerNonce - nonce created by the peer + * + * @param peerVersion - an integer representing the protocol version (i.e. AIDL version) + * negotiated with the peer + * + * @param ownKey - the key created by P1 (source) in `create()` for key exchange + * + * @return SessionInfo including the two shared key arcs from step #9, session id and the + * signature over the session id. + * + * Note: The two shared key arcs in the return type: `SessionInfo` serves two purposes: + * i. A mapping to correlate the key exchange protocol taken place with a particular peer and + * subsequent AuthGraph protocols execued with the same peer. + * ii.A way to minimize the in-memory storage for shared keys. + * However, P1 should maintain some in-memory record to be able to verify that the shared key + * arcs sent to any subsequent AuthGraph protocol methods are valid shared keys agreed with the + * party identified by `peerId`, to prevent any replay attacks. + */ + SessionInfo finish(in PubKey peerPubKey, in Identity peerId, + in SessionIdSignature peerSignature, in byte[] peerNonce, in int peerVersion, + in Key ownKey); + + /** + * This method is invoked on P2 (sink). + * Perform the following steps: + * 0. If input `sharedKeys` is invalid (i.e. they cannot be decrypted with P2's per-boot key + * or they are not in P2's in-memory records as valid shared keys agreed with the party + * identified by `peerId`), return error: INVALID_SHARED_KEY_ARCS. + * 1. Verify that both shared key arcs have the same session id and peer identity. + * 2. Verify the peer's signature over the session id attached to the shared key arcs' + * headers. If successful, proceed, otherwise, return error: INVALID_SIGNATURE. + * 3. Mark authentication_complete = true in the shared key arcs' headers + * + * @param peerSignature - the signature created by the peer over the session id computed by the + * peer + * + * @param sharedKeys - two shared key arcs created by P2 in `init`. P2 obtains from the arcs' + * protected headers, the session id and the peer's identity to verify the + * peer's signature over the session id. + * + * @return Arc[] - an array of two updated shared key arcs + */ + Arc[2] authenticationComplete(in SessionIdSignature peerSignature, in Arc[2] sharedKeys); +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/Identity.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/Identity.aidl new file mode 100644 index 0000000000..9e350e8091 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/Identity.aidl @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 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.authgraph; + +/** + * Persistent (versioned) identity of a participant of Authgraph key exchange. + * Identity consists of two main parts: + * 1. a certificate chain (e.g. a DICE certificate chain) + * 2. (optional) a policy specifying how to verify the certificate chain - if a policy is not + * provided, a simple byte-to-byte comparison of the certificate chain is assumed. + * + * During identity verification, the certificate chain of the identity attached to the access + * request is compared against the policy of the identity attached to the persistent resources. + * + * The usage of policy based identity verification in Authgraph is three-fold: + * 1. Retain access to persistent resources for the newer versions of the party who + * created them, even when parts of the certificate chain are updated in the new version. + * 2. Deny access to the new persistent resources for the older versions of the party + * who created the new persistent resources. + * 3. Trigger rotation of critical keys encrypted in persistent arcs created by the previous + * version of the party, by including an updated policy in the identity attached to the + * access request. + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +parcelable Identity { + /* Data is CBOR-encoded according to the `Identity` CDDL definition in Identity.cddl */ + byte[] identity; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/Identity.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/Identity.cddl new file mode 100644 index 0000000000..0419421fa6 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/Identity.cddl @@ -0,0 +1,23 @@ +; +; Copyright (C) 2023 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. +; +Identity = [ + 1, ; Version + cert_chain: bstr .cbor ExplicitKeyDiceCertChain, + policy: bstr .cbor DicePolicy / nil, +] + +; INCLUDE ExplicitKeyDiceCertChain.cddl for: ExplicitKeyDiceCertChain +; INCLUDE DicePolicy.cddl for: DicePolicy diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/KeInitResult.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/KeInitResult.aidl new file mode 100644 index 0000000000..b4ae451cd1 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/KeInitResult.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 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.authgraph; + +import android.hardware.security.authgraph.SessionInfo; +import android.hardware.security.authgraph.SessionInitiationInfo; + +/** + * The return type for the init() step of authenticated key exchange. + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +parcelable KeInitResult { + /** + * Session initiation information. + */ + SessionInitiationInfo sessionInitiationInfo; + + /** + * Session information. + */ + SessionInfo sessionInfo; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/Key.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/Key.aidl new file mode 100644 index 0000000000..11fe174608 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/Key.aidl @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 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.authgraph; + +import android.hardware.security.authgraph.Arc; +import android.hardware.security.authgraph.PubKey; + +/** + * The type that encapsulates a key. Key can be either a symmetric key or an asymmetric key. + * If it is an asymmetric key, it is used for key exchange. + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +parcelable Key { + /** + * If the Key is an asymmetric key, public key should be present. + */ + @nullable PubKey pubKey; + + /** + * Arc from the per-boot key to the payload key. The payload key is either the symmetric key + * or the private key of an asymmetric key, based on the type of the key being created. + * This is marked as optional because there are instances where only the public key is returned, + * e.g. `init` method in the key exchange protocol. + */ + @nullable Arc arcFromPBK; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/PlainPubKey.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/PlainPubKey.aidl new file mode 100644 index 0000000000..5483ec5d7a --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/PlainPubKey.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2023 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.authgraph; + +/** + * One of the two enum variants of the enum type: `PubKey`. This represents the plain public key + * material encoded as a COSE_Key. + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +parcelable PlainPubKey { + /* Data is CBOR-encoded according to the `PlainPubKey` CDDL definition in PlainPubKey.cddl */ + byte[] plainPubKey; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/PlainPubKey.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/PlainPubKey.cddl new file mode 100644 index 0000000000..34b316b135 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/PlainPubKey.cddl @@ -0,0 +1,24 @@ +; +; Copyright (C) 2023 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. +; + +; P-256 public key for key exchange. +PlainPubKey = [ ; COSE_Key [RFC9052 s7] + 1 : 2, ; Key type : EC2 + 3 : -27, ; Algorithm : ECDH-SS + HKDF-256 + -1 : 1, ; Curve: P256 + -2 : bstr, ; X coordinate, big-endian + -3 : bstr ; Y coordinate, big-endian +] diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/PubKey.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/PubKey.aidl new file mode 100644 index 0000000000..864087178a --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/PubKey.aidl @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2023 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.authgraph; + +import android.hardware.security.authgraph.PlainPubKey; +import android.hardware.security.authgraph.SignedPubKey; + +/** + * The enum type representing the public key of an asymmetric key pair. + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +union PubKey { + /** + * Plain public key material encoded as a COSE_Key. + */ + PlainPubKey plainKey; + + /** + * Public key signed with the long term signing key of the party. + */ + SignedPubKey signedKey; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/SessionIdSignature.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/SessionIdSignature.aidl new file mode 100644 index 0000000000..2fa8b4c8b9 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/SessionIdSignature.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2023 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.authgraph; + +/** + * Signature computed by a party over the session id during authenticated key exchange. + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +parcelable SessionIdSignature { + /* Data is CBOR-encoded according to the `SessionIdSignature` CDDL definition in + * SessionIdSignature.cddl */ + byte[] signature; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/SessionIdSignature.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/SessionIdSignature.cddl new file mode 100644 index 0000000000..038a0f01f4 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/SessionIdSignature.cddl @@ -0,0 +1,33 @@ +; +; Copyright (C) 2023 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. +; +SessionIdSignature = [ ; COSE_Sign1 (untagged) [RFC9052 s4.2] + protected: bstr .cbor SessionIdSignatureProtected, + unprotected: {}, + payload: nil, ; session ID payload to be transported separately + signature: bstr ; PureEd25519(privateKey, SessionIdSignatureSigStruct) / + ; ECDSA(privateKey, SessionIdSignatureSigStruct) +] + +SessionIdSignatureProtected = { + 1 : AlgorithmEdDSA / AlgorithmES256, +} + +SessionIdSignatureSigStruct = [ ; Sig_structure for SessionIdSignature [ RFC9052 s4.4] + context: "Signature1", + protected: bstr SessionIdSignatureProtected, + external_aad: bstr .size 0, + payload: bstr, ; session ID payload provided separately +] diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/SessionInfo.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/SessionInfo.aidl new file mode 100644 index 0000000000..ef49a1a1c0 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/SessionInfo.aidl @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 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.authgraph; + +import android.hardware.security.authgraph.Arc; +import android.hardware.security.authgraph.SessionIdSignature; + +/** + * Session information returned as part of authenticated key exchange. + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +parcelable SessionInfo { + /** + * The arcs that encrypt the two derived symmetric encryption keys (for two-way communication) + * from the party's per-boot key. + */ + Arc[2] sharedKeys; + + /** + * The value of the session id computed by the two parties during the authenticate key + * exchange. Apart from the usage of the session id by the two peers, session id is also useful + * to verify (by a third party) that the key exchange was successful. + */ + byte[] sessionId; + + /** + * The signature over the session id, created by the party who computed the session id. + * + * If there is one or more `DiceChainEntry` in the `ExplicitKeyDiceCertChain` of the party's + * identity, the signature is verified with the public key in the leaf of the chain of + * DiceChainEntries (i.e the public key in the last of the array of DiceChainEntries). + * Otherwise, the signature is verified with the `DiceCertChainInitialPayload`. + */ + SessionIdSignature signature; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/SessionInitiationInfo.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/SessionInitiationInfo.aidl new file mode 100644 index 0000000000..c630d91907 --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/SessionInitiationInfo.aidl @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023 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.authgraph; + +import android.hardware.security.authgraph.Arc; +import android.hardware.security.authgraph.Identity; +import android.hardware.security.authgraph.Key; + +/** + * Session initiation information returned as part of authenticated key exchange. + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +parcelable SessionInitiationInfo { + /** + * An ephemeral EC key created for the ECDH process. + */ + Key key; + + /** + * The identity of the party who created the Diffie-Hellman key exchange key. + */ + Identity identity; + + /** + * Nonce value specific to this session. The nonce serves three purposes: + * 1. freshness of key exchange + * 2. creating a session id (a publicly known value related to the exchanged keys) + * 3. usage as salt into the HKDF-EXTRACT function during key derivation from the shared DH key + */ + byte[] nonce; + + /** + * The protocol version (i.e. AIDL version) - This is used to prevent version downgrade attacks + * as follows: + * 1. In `create`, the source advertises the latest protocol version supported by the source, + * which is given as input to the `init` call on the sink in the input parameter: + * `peerVersion`. + * 2. In `init`, the sink includes the `peerVersion` in the inputs to the derivation of the + * shared keys. Then the sink returns the latest protocol version supported by the sink, + * which is given as input to the `finish` call on the source in the input parameter: + * `peerVersion`. + * 3. In `finish`, the source first checks whether the sink's version is equal or less than the + * source's version and includes in the source's version in the inputs to the derivation of + * the shared keys. + * Analysis: if an attacker-in-the-middle wanted the two parties to use an older (vulnerable) + * version of the protocol, they can invoke `init` with a version that is lower than the version + * advertised by the source in `create`. However, since both parties include the source's + * version in the inputs to the derivation of the shared keys, the two parties won't end up with + * the same shared keys in the presence of such an attack. This is detected when checking the + * signature on the session id in `finish`, at which point the protocol aborts. Therefore, + * an attacker cannot successfully launch a version downgrade attack on this protocol. + */ + int version; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/SignedPubKey.aidl b/security/authgraph/aidl/android/hardware/security/authgraph/SignedPubKey.aidl new file mode 100644 index 0000000000..72ee219a9b --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/SignedPubKey.aidl @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2023 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.authgraph; + +/** + * One of the two enum variants of the enum type: `PubKey`. This represents the public key signed + * with the long term signing key of the party. + */ +@VintfStability +@RustDerive(Clone=true, Eq=true, PartialEq=true) +parcelable SignedPubKey { + /* Data is CBOR-encoded according to the `SignedPubKey` CDDL definition in SignedPubKey.cddl */ + byte[] signedPubKey; +} diff --git a/security/authgraph/aidl/android/hardware/security/authgraph/SignedPubKey.cddl b/security/authgraph/aidl/android/hardware/security/authgraph/SignedPubKey.cddl new file mode 100644 index 0000000000..f23a492e8b --- /dev/null +++ b/security/authgraph/aidl/android/hardware/security/authgraph/SignedPubKey.cddl @@ -0,0 +1,41 @@ +; +; Copyright (C) 2023 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. +; +SignedPubKey = [ ; COSE_Sign1 (untagged) [RFC9052 s4.2] + protected: bstr .cbor SignedPubKeyProtected, + unprotected: {}, + payload: bstr .cbor PlainPubKey, + signature: bstr ; PureEd25519(privateKey, SignedPubKeySigStruct) / + ; ECDSA(privateKey, SignedPubKeySigStruct) +] + +SignedPubKeyProtected = { + 1 : AlgorithmEdDSA / AlgorithmES256, + ? -70011 : Identity, ; the party who performs the signing operation adds its own + ; identity to the protected headers. +} + +SignedPubKeySigStruct = [ ; Sig_structure for SignedPubKey [ RFC9052 s4.4] + context: "Signature1", + protected: bstr SignedPubKeyProtected, + external_aad: bstr .size 0, + payload: bstr .cbor PlainPubKey, +] + +AlgorithmES256 = -7 ; [RFC9053 s2.1] +AlgorithmEdDSA = -8 ; [RFC9053 s2.2] + +; INCLUDE PlainPubKey.cddl for: PlainPubKey +; INCLUDE Identity.cddl for: Identity \ No newline at end of file From c8625a8963f01a629627b3a205c347470f7060fc Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Mon, 11 Sep 2023 13:10:48 +0100 Subject: [PATCH 2/4] authgraph: add placeholder VTS test Test: VtsAidlAuthGraphSessionTest (with nonsecure default impl) Change-Id: I1a94071da8de8d4934709fa7875f89a0bb00a142 --- security/authgraph/aidl/Android.bp | 41 ++++ .../authgraph/aidl/vts/functional/Android.bp | 48 ++++ .../vts/functional/AuthGraphSessionTest.cpp | 210 ++++++++++++++++++ 3 files changed, 299 insertions(+) create mode 100644 security/authgraph/aidl/vts/functional/Android.bp create mode 100644 security/authgraph/aidl/vts/functional/AuthGraphSessionTest.cpp diff --git a/security/authgraph/aidl/Android.bp b/security/authgraph/aidl/Android.bp index 373d0c4be8..d94f640570 100644 --- a/security/authgraph/aidl/Android.bp +++ b/security/authgraph/aidl/Android.bp @@ -45,3 +45,44 @@ aidl_interface { }, }, } + +// cc_defaults that includes the latest Authgraph AIDL library. +// Modules that depend on Authgraph directly can include this cc_defaults to avoid +// managing dependency versions explicitly. +cc_defaults { + name: "authgraph_use_latest_hal_aidl_ndk_static", + static_libs: [ + "android.hardware.security.authgraph-V1-ndk", + ], +} + +cc_defaults { + name: "authgraph_use_latest_hal_aidl_ndk_shared", + shared_libs: [ + "android.hardware.security.authgraph-V1-ndk", + ], +} + +cc_defaults { + name: "authgraph_use_latest_hal_aidl_cpp_static", + static_libs: [ + "android.hardware.security.authgraph-V1-cpp", + ], +} + +cc_defaults { + name: "authgraph_use_latest_hal_aidl_cpp_shared", + shared_libs: [ + "android.hardware.security.authgraph-V1-cpp", + ], +} + +// A rust_defaults that includes the latest Authgraph AIDL library. +// Modules that depend on Authgraph directly can include this rust_defaults to avoid +// managing dependency versions explicitly. +rust_defaults { + name: "authgraph_use_latest_hal_aidl_rust", + rustlibs: [ + "android.hardware.security.authgraph-V1-rust", + ], +} diff --git a/security/authgraph/aidl/vts/functional/Android.bp b/security/authgraph/aidl/vts/functional/Android.bp new file mode 100644 index 0000000000..fc13759021 --- /dev/null +++ b/security/authgraph/aidl/vts/functional/Android.bp @@ -0,0 +1,48 @@ +// +// Copyright (C) 2023 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +cc_test { + name: "VtsAidlAuthGraphSessionTest", + defaults: [ + "VtsHalTargetTestDefaults", + "authgraph_use_latest_hal_aidl_ndk_static", + "use_libaidlvintf_gtest_helper_static", + ], + cflags: [ + "-Wall", + "-Wextra", + ], + srcs: [ + "AuthGraphSessionTest.cpp", + ], + shared_libs: [ + "libbinder_ndk", + "libcrypto", + ], + test_suites: [ + "general-tests", + "vts", + ], +} diff --git a/security/authgraph/aidl/vts/functional/AuthGraphSessionTest.cpp b/security/authgraph/aidl/vts/functional/AuthGraphSessionTest.cpp new file mode 100644 index 0000000000..cab8074417 --- /dev/null +++ b/security/authgraph/aidl/vts/functional/AuthGraphSessionTest.cpp @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2023 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. + */ +#define LOG_TAG "authgraph_session_test" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace aidl::android::hardware::security::authgraph::test { +using ::aidl::android::hardware::security::authgraph::Error; + +namespace { + +// Check that the signature in the encoded COSE_Sign1 data is correct, and that the payload matches. +// TODO: maybe drop separate payload, and extract it from cose_sign1.payload (and return it). +void CheckSignature(std::vector& /*pub_cose_key*/, std::vector& /*payload*/, + std::vector& /*cose_sign1*/) { + // TODO: implement me +} + +void CheckSignature(std::vector& pub_cose_key, std::vector& payload, + SessionIdSignature& signature) { + return CheckSignature(pub_cose_key, payload, signature.signature); +} + +std::vector SigningKeyFromIdentity(const Identity& identity) { + // TODO: This is a CBOR-encoded `Identity` which currently happens to be a COSE_Key with the + // pubkey This will change in future. + return identity.identity; +} + +} // namespace + +class AuthGraphSessionTest : public ::testing::TestWithParam { + public: + enum ErrorType { AIDL_ERROR, BINDER_ERROR }; + + union ErrorValue { + Error aidl_error; + int32_t binder_error; + }; + + struct ReturnedError { + ErrorType err_type; + ErrorValue err_val; + + friend bool operator==(const ReturnedError& lhs, const ReturnedError& rhs) { + return lhs.err_type == rhs.err_type; + switch (lhs.err_type) { + case ErrorType::AIDL_ERROR: + return lhs.err_val.aidl_error == rhs.err_val.aidl_error; + case ErrorType::BINDER_ERROR: + return lhs.err_val.binder_error == rhs.err_val.binder_error; + } + } + }; + + const ReturnedError OK = {.err_type = ErrorType::AIDL_ERROR, .err_val.aidl_error = Error::OK}; + + ReturnedError GetReturnError(const ::ndk::ScopedAStatus& result) { + if (result.isOk()) { + return OK; + } + int32_t exception_code = result.getExceptionCode(); + int32_t error_code = result.getServiceSpecificError(); + if (exception_code == EX_SERVICE_SPECIFIC && error_code != 0) { + ReturnedError re = {.err_type = ErrorType::AIDL_ERROR, + .err_val.aidl_error = static_cast(error_code)}; + return re; + } + ReturnedError re = {.err_type = ErrorType::BINDER_ERROR, + .err_val.binder_error = exception_code}; + return re; + } + + // Build the parameters for the VTS test by enumerating the available HAL instances + static std::vector build_params() { + auto params = ::android::getAidlHalInstanceNames(IAuthGraphKeyExchange::descriptor); + return params; + } + + void SetUp() override { + ASSERT_TRUE(AServiceManager_isDeclared(GetParam().c_str())) + << "No instance declared for " << GetParam(); + ::ndk::SpAIBinder binder(AServiceManager_waitForService(GetParam().c_str())); + authNode_ = IAuthGraphKeyExchange::fromBinder(binder); + ASSERT_NE(authNode_, nullptr) << "Failed to get Binder reference for " << GetParam(); + } + + void TearDown() override {} + + protected: + std::shared_ptr authNode_; +}; + +TEST_P(AuthGraphSessionTest, Mainline) { + std::shared_ptr source = authNode_; + std::shared_ptr sink = authNode_; + + // Step 1: create an ephemeral ECDH key at the source. + SessionInitiationInfo source_init_info; + ASSERT_EQ(OK, GetReturnError(source->create(&source_init_info))); + ASSERT_TRUE(source_init_info.key.pubKey.has_value()); + ASSERT_TRUE(source_init_info.key.arcFromPBK.has_value()); + + // Step 2: pass the source's ECDH public key and other session info to the sink. + KeInitResult init_result; + ASSERT_EQ(OK, GetReturnError(sink->init(source_init_info.key.pubKey.value(), + source_init_info.identity, source_init_info.nonce, + source_init_info.version, &init_result))); + SessionInitiationInfo sink_init_info = init_result.sessionInitiationInfo; + ASSERT_TRUE(sink_init_info.key.pubKey.has_value()); + // The sink_init_info.arcFromPBK need not be populated, as the ephemeral key agreement + // key is no longer needed. + + SessionInfo sink_info = init_result.sessionInfo; + ASSERT_EQ((int)sink_info.sharedKeys.size(), 2) << "Expect two symmetric keys from init()"; + ASSERT_GT((int)sink_info.sessionId.size(), 0) << "Expect non-empty session ID from sink"; + std::vector sink_signing_key = SigningKeyFromIdentity(sink_init_info.identity); + CheckSignature(sink_signing_key, sink_info.sessionId, sink_info.signature); + + // Step 3: pass the sink's ECDH public key and other session info to the source, so it can + // calculate the same pair of symmetric keys. + SessionInfo source_info; + ASSERT_EQ(OK, GetReturnError(source->finish(sink_init_info.key.pubKey.value(), + sink_init_info.identity, sink_info.signature, + sink_init_info.nonce, sink_init_info.version, + source_init_info.key, &source_info))); + ASSERT_EQ((int)source_info.sharedKeys.size(), 2) << "Expect two symmetric keys from finsh()"; + ASSERT_GT((int)source_info.sessionId.size(), 0) << "Expect non-empty session ID from source"; + std::vector source_signing_key = SigningKeyFromIdentity(source_init_info.identity); + CheckSignature(source_signing_key, source_info.sessionId, source_info.signature); + + // Both ends should agree on the session ID. + ASSERT_EQ(source_info.sessionId, sink_info.sessionId); + + // Step 4: pass the source's session ID info back to the sink, so it can check it and + // update the symmetric keys so they're marked as authentication complete. + std::array auth_complete_result; + ASSERT_EQ(OK, GetReturnError(sink->authenticationComplete( + source_info.signature, sink_info.sharedKeys, &auth_complete_result))); + ASSERT_EQ((int)auth_complete_result.size(), 2) + << "Expect two symmetric keys from authComplete()"; + sink_info.sharedKeys = auth_complete_result; + + // At this point the sink and source have agreed on the same pair of symmetric keys, + // encoded as `sink_info.sharedKeys` and `source_info.sharedKeys`. +} + +TEST_P(AuthGraphSessionTest, FreshNonces) { + std::shared_ptr source = authNode_; + std::shared_ptr sink = authNode_; + + SessionInitiationInfo source_init_info1; + ASSERT_EQ(OK, GetReturnError(source->create(&source_init_info1))); + SessionInitiationInfo source_init_info2; + ASSERT_EQ(OK, GetReturnError(source->create(&source_init_info2))); + + // Two calls to create() should result in the same identity but different nonce values. + ASSERT_EQ(source_init_info1.identity, source_init_info2.identity); + ASSERT_NE(source_init_info1.nonce, source_init_info2.nonce); + ASSERT_NE(source_init_info1.key.pubKey, source_init_info2.key.pubKey); + ASSERT_NE(source_init_info1.key.arcFromPBK, source_init_info2.key.arcFromPBK); + + KeInitResult init_result1; + ASSERT_EQ(OK, GetReturnError(sink->init(source_init_info1.key.pubKey.value(), + source_init_info1.identity, source_init_info1.nonce, + source_init_info1.version, &init_result1))); + KeInitResult init_result2; + ASSERT_EQ(OK, GetReturnError(sink->init(source_init_info2.key.pubKey.value(), + source_init_info2.identity, source_init_info2.nonce, + source_init_info2.version, &init_result2))); + + // Two calls to init() should result in the same identity buf different nonces and session IDs. + ASSERT_EQ(init_result1.sessionInitiationInfo.identity, + init_result2.sessionInitiationInfo.identity); + ASSERT_NE(init_result1.sessionInitiationInfo.nonce, init_result2.sessionInitiationInfo.nonce); + ASSERT_NE(init_result1.sessionInfo.sessionId, init_result2.sessionInfo.sessionId); +} + +INSTANTIATE_TEST_SUITE_P(PerInstance, AuthGraphSessionTest, + testing::ValuesIn(AuthGraphSessionTest::build_params()), + ::android::PrintInstanceNameToString); +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(AuthGraphSessionTest); + +} // namespace aidl::android::hardware::security::authgraph::test + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} From d42cb6fa69c4c7d497dd30a9172b3cbd554a9719 Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Tue, 3 Oct 2023 15:58:13 +0100 Subject: [PATCH 3/4] authgraph: add parallel session VTS tests Test: VtsAidlAuthGraphSessionTest Change-Id: Idcf79afe838fdbfb88bd7f43fe758ac03d9ba0d1 --- .../vts/functional/AuthGraphSessionTest.cpp | 165 ++++++++++++++++++ 1 file changed, 165 insertions(+) diff --git a/security/authgraph/aidl/vts/functional/AuthGraphSessionTest.cpp b/security/authgraph/aidl/vts/functional/AuthGraphSessionTest.cpp index cab8074417..d9dea7735a 100644 --- a/security/authgraph/aidl/vts/functional/AuthGraphSessionTest.cpp +++ b/security/authgraph/aidl/vts/functional/AuthGraphSessionTest.cpp @@ -166,6 +166,171 @@ TEST_P(AuthGraphSessionTest, Mainline) { // encoded as `sink_info.sharedKeys` and `source_info.sharedKeys`. } +TEST_P(AuthGraphSessionTest, ParallelSink) { + std::shared_ptr source = authNode_; + std::shared_ptr sink1 = authNode_; + std::shared_ptr sink2 = authNode_; + + // Step 1: create ephemeral ECDH keys at the source. + SessionInitiationInfo source_init1_info; + ASSERT_EQ(OK, GetReturnError(source->create(&source_init1_info))); + ASSERT_TRUE(source_init1_info.key.pubKey.has_value()); + ASSERT_TRUE(source_init1_info.key.arcFromPBK.has_value()); + SessionInitiationInfo source_init2_info; + ASSERT_EQ(OK, GetReturnError(source->create(&source_init2_info))); + ASSERT_TRUE(source_init2_info.key.pubKey.has_value()); + ASSERT_TRUE(source_init2_info.key.arcFromPBK.has_value()); + + // Step 2: pass the source's ECDH public keys and other session info to the sinks. + KeInitResult init1_result; + ASSERT_EQ(OK, GetReturnError(sink1->init(source_init1_info.key.pubKey.value(), + source_init1_info.identity, source_init1_info.nonce, + source_init1_info.version, &init1_result))); + SessionInitiationInfo sink1_init_info = init1_result.sessionInitiationInfo; + ASSERT_TRUE(sink1_init_info.key.pubKey.has_value()); + + SessionInfo sink1_info = init1_result.sessionInfo; + ASSERT_EQ((int)sink1_info.sharedKeys.size(), 2) << "Expect two symmetric keys from init()"; + ASSERT_GT((int)sink1_info.sessionId.size(), 0) << "Expect non-empty session ID from sink"; + std::vector sink1_signing_key = SigningKeyFromIdentity(sink1_init_info.identity); + CheckSignature(sink1_signing_key, sink1_info.sessionId, sink1_info.signature); + KeInitResult init2_result; + ASSERT_EQ(OK, GetReturnError(sink2->init(source_init2_info.key.pubKey.value(), + source_init2_info.identity, source_init2_info.nonce, + source_init2_info.version, &init2_result))); + SessionInitiationInfo sink2_init_info = init2_result.sessionInitiationInfo; + ASSERT_TRUE(sink2_init_info.key.pubKey.has_value()); + + SessionInfo sink2_info = init2_result.sessionInfo; + ASSERT_EQ((int)sink2_info.sharedKeys.size(), 2) << "Expect two symmetric keys from init()"; + ASSERT_GT((int)sink2_info.sessionId.size(), 0) << "Expect non-empty session ID from sink"; + std::vector sink2_signing_key = SigningKeyFromIdentity(sink2_init_info.identity); + CheckSignature(sink2_signing_key, sink2_info.sessionId, sink2_info.signature); + + // Step 3: pass each sink's ECDH public key and other session info to the source, so it can + // calculate the same pair of symmetric keys. + SessionInfo source_info1; + ASSERT_EQ(OK, GetReturnError(source->finish(sink1_init_info.key.pubKey.value(), + sink1_init_info.identity, sink1_info.signature, + sink1_init_info.nonce, sink1_init_info.version, + source_init1_info.key, &source_info1))); + ASSERT_EQ((int)source_info1.sharedKeys.size(), 2) << "Expect two symmetric keys from finsh()"; + ASSERT_GT((int)source_info1.sessionId.size(), 0) << "Expect non-empty session ID from source"; + std::vector source_signing_key1 = SigningKeyFromIdentity(source_init1_info.identity); + CheckSignature(source_signing_key1, source_info1.sessionId, source_info1.signature); + SessionInfo source_info2; + ASSERT_EQ(OK, GetReturnError(source->finish(sink2_init_info.key.pubKey.value(), + sink2_init_info.identity, sink2_info.signature, + sink2_init_info.nonce, sink2_init_info.version, + source_init2_info.key, &source_info2))); + ASSERT_EQ((int)source_info2.sharedKeys.size(), 2) << "Expect two symmetric keys from finsh()"; + ASSERT_GT((int)source_info2.sessionId.size(), 0) << "Expect non-empty session ID from source"; + std::vector source_signing_key2 = SigningKeyFromIdentity(source_init2_info.identity); + CheckSignature(source_signing_key2, source_info2.sessionId, source_info2.signature); + + // Both ends should agree on the session ID. + ASSERT_EQ(source_info1.sessionId, sink1_info.sessionId); + ASSERT_EQ(source_info2.sessionId, sink2_info.sessionId); + + // Step 4: pass the source's session ID info back to the sink, so it can check it and + // update the symmetric keys so they're marked as authentication complete. + std::array auth_complete_result1; + ASSERT_EQ(OK, GetReturnError(sink1->authenticationComplete( + source_info1.signature, sink1_info.sharedKeys, &auth_complete_result1))); + ASSERT_EQ((int)auth_complete_result1.size(), 2) + << "Expect two symmetric keys from authComplete()"; + sink1_info.sharedKeys = auth_complete_result1; + std::array auth_complete_result2; + ASSERT_EQ(OK, GetReturnError(sink2->authenticationComplete( + source_info2.signature, sink2_info.sharedKeys, &auth_complete_result2))); + ASSERT_EQ((int)auth_complete_result2.size(), 2) + << "Expect two symmetric keys from authComplete()"; + sink2_info.sharedKeys = auth_complete_result2; +} + +TEST_P(AuthGraphSessionTest, ParallelSource) { + std::shared_ptr source1 = authNode_; + std::shared_ptr source2 = authNode_; + std::shared_ptr sink = authNode_; + + // Step 1: create an ephemeral ECDH key at each of the sources. + SessionInitiationInfo source1_init_info; + ASSERT_EQ(OK, GetReturnError(source1->create(&source1_init_info))); + ASSERT_TRUE(source1_init_info.key.pubKey.has_value()); + ASSERT_TRUE(source1_init_info.key.arcFromPBK.has_value()); + SessionInitiationInfo source2_init_info; + ASSERT_EQ(OK, GetReturnError(source1->create(&source2_init_info))); + ASSERT_TRUE(source2_init_info.key.pubKey.has_value()); + ASSERT_TRUE(source2_init_info.key.arcFromPBK.has_value()); + + // Step 2: pass each source's ECDH public key and other session info to the sink. + KeInitResult init1_result; + ASSERT_EQ(OK, GetReturnError(sink->init(source1_init_info.key.pubKey.value(), + source1_init_info.identity, source1_init_info.nonce, + source1_init_info.version, &init1_result))); + SessionInitiationInfo sink_init1_info = init1_result.sessionInitiationInfo; + ASSERT_TRUE(sink_init1_info.key.pubKey.has_value()); + + SessionInfo sink_info1 = init1_result.sessionInfo; + ASSERT_EQ((int)sink_info1.sharedKeys.size(), 2) << "Expect two symmetric keys from init()"; + ASSERT_GT((int)sink_info1.sessionId.size(), 0) << "Expect non-empty session ID from sink"; + std::vector sink_signing_key1 = SigningKeyFromIdentity(sink_init1_info.identity); + CheckSignature(sink_signing_key1, sink_info1.sessionId, sink_info1.signature); + + KeInitResult init2_result; + ASSERT_EQ(OK, GetReturnError(sink->init(source2_init_info.key.pubKey.value(), + source2_init_info.identity, source2_init_info.nonce, + source2_init_info.version, &init2_result))); + SessionInitiationInfo sink_init2_info = init2_result.sessionInitiationInfo; + ASSERT_TRUE(sink_init2_info.key.pubKey.has_value()); + + SessionInfo sink_info2 = init2_result.sessionInfo; + ASSERT_EQ((int)sink_info2.sharedKeys.size(), 2) << "Expect two symmetric keys from init()"; + ASSERT_GT((int)sink_info2.sessionId.size(), 0) << "Expect non-empty session ID from sink"; + std::vector sink_signing_key2 = SigningKeyFromIdentity(sink_init2_info.identity); + CheckSignature(sink_signing_key2, sink_info2.sessionId, sink_info2.signature); + + // Step 3: pass the sink's ECDH public keys and other session info to the each of the sources. + SessionInfo source1_info; + ASSERT_EQ(OK, GetReturnError(source1->finish(sink_init1_info.key.pubKey.value(), + sink_init1_info.identity, sink_info1.signature, + sink_init1_info.nonce, sink_init1_info.version, + source1_init_info.key, &source1_info))); + ASSERT_EQ((int)source1_info.sharedKeys.size(), 2) << "Expect two symmetric keys from finsh()"; + ASSERT_GT((int)source1_info.sessionId.size(), 0) << "Expect non-empty session ID from source"; + std::vector source1_signing_key = SigningKeyFromIdentity(source1_init_info.identity); + CheckSignature(source1_signing_key, source1_info.sessionId, source1_info.signature); + + SessionInfo source2_info; + ASSERT_EQ(OK, GetReturnError(source2->finish(sink_init2_info.key.pubKey.value(), + sink_init2_info.identity, sink_info2.signature, + sink_init2_info.nonce, sink_init2_info.version, + source2_init_info.key, &source2_info))); + ASSERT_EQ((int)source2_info.sharedKeys.size(), 2) << "Expect two symmetric keys from finsh()"; + ASSERT_GT((int)source2_info.sessionId.size(), 0) << "Expect non-empty session ID from source"; + std::vector source2_signing_key = SigningKeyFromIdentity(source2_init_info.identity); + CheckSignature(source2_signing_key, source2_info.sessionId, source2_info.signature); + + // Both ends should agree on the session ID. + ASSERT_EQ(source1_info.sessionId, sink_info1.sessionId); + ASSERT_EQ(source2_info.sessionId, sink_info2.sessionId); + + // Step 4: pass the each source's session ID info back to the sink, so it can check it and + // update the symmetric keys so they're marked as authentication complete. + std::array auth_complete_result1; + ASSERT_EQ(OK, GetReturnError(sink->authenticationComplete( + source1_info.signature, sink_info1.sharedKeys, &auth_complete_result1))); + ASSERT_EQ((int)auth_complete_result1.size(), 2) + << "Expect two symmetric keys from authComplete()"; + sink_info1.sharedKeys = auth_complete_result1; + std::array auth_complete_result2; + ASSERT_EQ(OK, GetReturnError(sink->authenticationComplete( + source2_info.signature, sink_info2.sharedKeys, &auth_complete_result2))); + ASSERT_EQ((int)auth_complete_result2.size(), 2) + << "Expect two symmetric keys from authComplete()"; + sink_info2.sharedKeys = auth_complete_result2; +} + TEST_P(AuthGraphSessionTest, FreshNonces) { std::shared_ptr source = authNode_; std::shared_ptr sink = authNode_; From 7fd838c0fe3d7a84c61a7c567ffb6b32b509579d Mon Sep 17 00:00:00 2001 From: David Drysdale Date: Thu, 5 Oct 2023 13:07:28 +0100 Subject: [PATCH 4/4] Add (nonsecure) default AuthGraph impl Add an implementation for the AuthGraph key exchange HAL, to allow testing and policy compliance. In real use, IAuthGraphKeyExchange instances are expected to be retrieved from some other HAL, allowing the AuthGraph instance to be specifically correlated with the component that uses it. Bug: 284470121 Bug: 291228560 Test: hal_implementation_test Test: VtsAidlAuthGraphSessionTest Change-Id: Ib064292d60bead663af7721fd1406f2a9b5d8ecd --- .../compatibility_matrix.9.xml | 2 +- security/authgraph/default/Android.bp | 46 ++++ security/authgraph/default/authgraph.rc | 5 + security/authgraph/default/authgraph.xml | 10 + security/authgraph/default/src/main.rs | 227 ++++++++++++++++++ 5 files changed, 289 insertions(+), 1 deletion(-) create mode 100644 security/authgraph/default/Android.bp create mode 100644 security/authgraph/default/authgraph.rc create mode 100644 security/authgraph/default/authgraph.xml create mode 100644 security/authgraph/default/src/main.rs diff --git a/compatibility_matrices/compatibility_matrix.9.xml b/compatibility_matrices/compatibility_matrix.9.xml index b348d350fd..6ed8e8f354 100644 --- a/compatibility_matrices/compatibility_matrix.9.xml +++ b/compatibility_matrices/compatibility_matrix.9.xml @@ -513,7 +513,7 @@ 1 IAuthGraphKeyExchange - default + nonsecure diff --git a/security/authgraph/default/Android.bp b/security/authgraph/default/Android.bp new file mode 100644 index 0000000000..9de3bc11da --- /dev/null +++ b/security/authgraph/default/Android.bp @@ -0,0 +1,46 @@ +// +// Copyright (C) 2023 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 { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "hardware_interfaces_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["hardware_interfaces_license"], +} + +rust_binary { + name: "android.hardware.security.authgraph-service.nonsecure", + relative_install_path: "hw", + vendor: true, + init_rc: ["authgraph.rc"], + vintf_fragments: ["authgraph.xml"], + defaults: [ + "authgraph_use_latest_hal_aidl_rust", + ], + rustlibs: [ + "libandroid_logger", + "libauthgraph_core", + "libauthgraph_boringssl", + "libauthgraph_hal", + "libbinder_rs", + "liblibc", + "liblog_rust", + ], + srcs: [ + "src/main.rs", + ], +} diff --git a/security/authgraph/default/authgraph.rc b/security/authgraph/default/authgraph.rc new file mode 100644 index 0000000000..022299404a --- /dev/null +++ b/security/authgraph/default/authgraph.rc @@ -0,0 +1,5 @@ +service vendor.authgraph /vendor/bin/hw/android.hardware.security.authgraph-service.nonsecure + interface aidl android.hardware.security.authgraph.IAuthGraph/nonsecure + class hal + user nobody + group nobody diff --git a/security/authgraph/default/authgraph.xml b/security/authgraph/default/authgraph.xml new file mode 100644 index 0000000000..9529a0afe5 --- /dev/null +++ b/security/authgraph/default/authgraph.xml @@ -0,0 +1,10 @@ + + + android.hardware.security.authgraph + 1 + + IAuthGraphKeyExchange + nonsecure + + + diff --git a/security/authgraph/default/src/main.rs b/security/authgraph/default/src/main.rs new file mode 100644 index 0000000000..2112e58176 --- /dev/null +++ b/security/authgraph/default/src/main.rs @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2023 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. + */ + +//! Default implementation of the AuthGraph key exchange HAL. +//! +//! This implementation of the HAL is only intended to allow testing and policy compliance. A real +//! implementation of the AuthGraph HAL would be implemented in a secure environment, and would not +//! be independently registered with service manager (a secure component that uses AuthGraph would +//! expose an entrypoint that allowed retrieval of the specific IAuthGraphKeyExchange instance that +//! is correlated with the component). + +use android_hardware_security_authgraph::aidl::android::hardware::security::authgraph::{ + Arc::Arc, IAuthGraphKeyExchange::BnAuthGraphKeyExchange, + IAuthGraphKeyExchange::IAuthGraphKeyExchange, Identity::Identity, KeInitResult::KeInitResult, + Key::Key, PubKey::PubKey, SessionIdSignature::SessionIdSignature, SessionInfo::SessionInfo, + SessionInitiationInfo::SessionInitiationInfo, +}; +use authgraph_boringssl as boring; +use authgraph_core::{key::MillisecondsSinceEpoch, keyexchange as ke, traits}; +use authgraph_hal::{err_to_binder, Innto, TryInnto}; +use log::{error, info}; +use std::ffi::CString; +use std::sync::Mutex; + +static SERVICE_NAME: &str = "android.hardware.security.authgraph.IAuthGraphKeyExchange"; +static SERVICE_INSTANCE: &str = "nonsecure"; + +/// Local error type for failures in the HAL service. +#[derive(Debug, Clone)] +struct HalServiceError(String); + +impl From for HalServiceError { + fn from(s: String) -> Self { + Self(s) + } +} + +fn main() { + if let Err(e) = inner_main() { + panic!("HAL service failed: {:?}", e); + } +} + +fn inner_main() -> Result<(), HalServiceError> { + // Initialize Android logging. + android_logger::init_once( + android_logger::Config::default() + .with_tag("authgraph-hal-nonsecure") + .with_min_level(log::Level::Info) + .with_log_id(android_logger::LogId::System), + ); + // Redirect panic messages to logcat. + std::panic::set_hook(Box::new(|panic_info| { + error!("{}", panic_info); + })); + + info!("Insecure AuthGraph key exchange HAL service is starting."); + + info!("Starting thread pool now."); + binder::ProcessState::start_thread_pool(); + + // Register the service + let service = AuthGraphService::new_as_binder(); + let service_name = format!("{}/{}", SERVICE_NAME, SERVICE_INSTANCE); + binder::add_service(&service_name, service.as_binder()).map_err(|e| { + format!( + "Failed to register service {} because of {:?}.", + service_name, e + ) + })?; + + info!("Successfully registered AuthGraph HAL services."); + binder::ProcessState::join_thread_pool(); + info!("AuthGraph HAL service is terminating."); // should not reach here + Ok(()) +} + +/// Non-secure implementation of the AuthGraph key exchange service. +struct AuthGraphService { + imp: Mutex, +} + +impl AuthGraphService { + /// Create a new instance. + fn new() -> Self { + Self { + imp: Mutex::new(traits::TraitImpl { + aes_gcm: Box::new(boring::BoringAes), + ecdh: Box::new(boring::BoringEcDh), + ecdsa: Box::new(boring::BoringEcDsa), + hmac: Box::new(boring::BoringHmac), + hkdf: Box::new(boring::BoringHkdf), + sha256: Box::new(boring::BoringSha256), + rng: Box::new(boring::BoringRng), + device: Box::::default(), + clock: Some(Box::new(StdClock)), + }), + } + } + + /// Create a new instance wrapped in a proxy object. + pub fn new_as_binder() -> binder::Strong { + BnAuthGraphKeyExchange::new_binder(Self::new(), binder::BinderFeatures::default()) + } +} + +impl binder::Interface for AuthGraphService {} + +/// Extract (and require) an unsigned public key as bytes from a [`PubKey`]. +fn unsigned_pub_key(pub_key: &PubKey) -> binder::Result<&[u8]> { + match pub_key { + PubKey::PlainKey(key) => Ok(&key.plainPubKey), + PubKey::SignedKey(_) => Err(binder::Status::new_exception( + binder::ExceptionCode::ILLEGAL_ARGUMENT, + Some(&CString::new("expected unsigned public key").unwrap()), + )), + } +} + +/// This nonsecure implementation of the AuthGraph HAL interface directly calls the AuthGraph +/// reference implementation library code; a real implementation requires the AuthGraph +/// code to run in a secure environment, not within Android. +impl IAuthGraphKeyExchange for AuthGraphService { + fn create(&self) -> binder::Result { + info!("create()"); + let mut imp = self.imp.lock().unwrap(); + let info = ke::create(&mut *imp).map_err(err_to_binder)?; + Ok(info.innto()) + } + fn init( + &self, + peer_pub_key: &PubKey, + peer_id: &Identity, + peer_nonce: &[u8], + peer_version: i32, + ) -> binder::Result { + info!("init(v={peer_version})"); + let mut imp = self.imp.lock().unwrap(); + let peer_pub_key = unsigned_pub_key(peer_pub_key)?; + let result = ke::init( + &mut *imp, + peer_pub_key, + &peer_id.identity, + &peer_nonce, + peer_version, + ) + .map_err(err_to_binder)?; + Ok(result.innto()) + } + + fn finish( + &self, + peer_pub_key: &PubKey, + peer_id: &Identity, + peer_signature: &SessionIdSignature, + peer_nonce: &[u8], + peer_version: i32, + own_key: &Key, + ) -> binder::Result { + info!("finish(v={peer_version})"); + let mut imp = self.imp.lock().unwrap(); + let peer_pub_key = unsigned_pub_key(peer_pub_key)?; + let own_key: Key = own_key.clone(); + let own_key: authgraph_core::key::Key = own_key.try_innto()?; + let session_info = ke::finish( + &mut *imp, + peer_pub_key, + &peer_id.identity, + &peer_signature.signature, + &peer_nonce, + peer_version, + own_key, + ) + .map_err(err_to_binder)?; + Ok(session_info.innto()) + } + + fn authenticationComplete( + &self, + peer_signature: &SessionIdSignature, + shared_keys: &[Arc; 2], + ) -> binder::Result<[Arc; 2]> { + info!("authComplete()"); + let mut imp = self.imp.lock().unwrap(); + let shared_keys = [shared_keys[0].arc.clone(), shared_keys[1].arc.clone()]; + let arcs = ke::authentication_complete(&mut *imp, &peer_signature.signature, shared_keys) + .map_err(err_to_binder)?; + Ok(arcs.map(|arc| Arc { arc })) + } +} + +/// Monotonic clock. +#[derive(Default)] +pub struct StdClock; + +impl traits::MonotonicClock for StdClock { + fn now(&self) -> authgraph_core::key::MillisecondsSinceEpoch { + let mut time = libc::timespec { + tv_sec: 0, // libc::time_t + tv_nsec: 0, // libc::c_long + }; + let rc = + // Safety: `time` is a valid structure. + unsafe { libc::clock_gettime(libc::CLOCK_BOOTTIME, &mut time as *mut libc::timespec) }; + if rc < 0 { + log::warn!("failed to get time!"); + return MillisecondsSinceEpoch(0); + } + // The types in `libc::timespec` may be different on different architectures, + // so allow conversion to `i64`. + #[allow(clippy::unnecessary_cast)] + MillisecondsSinceEpoch((time.tv_sec as i64 * 1000) + (time.tv_nsec as i64 / 1000 / 1000)) + } +}