security: see: hdcp: add HDCP Auth Control interface

Bug: 380193246
Test: atest VtsAidlHdcpNonExistentTest
Change-Id: I479621a51cd177e9bda0b551c5088f6c7e72e88f
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index 4995a72..57e039c 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -171,6 +171,7 @@
             "android.hardware.audio.core.sounddose@3",
             // This is only used by a trusty VM
             "android.hardware.security.see.authmgr@1",
+            "android.hardware.security.see.hdcp@1",
 
             // Deprecated HALs.
             "android.hardware.audio.sounddose@3",
diff --git a/drm/Android.bp b/drm/Android.bp
new file mode 100644
index 0000000..35c1b03
--- /dev/null
+++ b/drm/Android.bp
@@ -0,0 +1,5 @@
+dirgroup {
+    name: "trusty_dirgroup_hardware_interfaces_drm",
+    dirs: ["."],
+    visibility: ["//trusty/vendor/google/aosp/scripts"],
+}
diff --git a/drm/aidl/Android.bp b/drm/aidl/Android.bp
index 827621c..7ee8c34 100644
--- a/drm/aidl/Android.bp
+++ b/drm/aidl/Android.bp
@@ -27,6 +27,9 @@
         ndk: {
             min_sdk_version: "34",
         },
+        rust: {
+            enabled: true,
+        },
     },
     double_loadable: true,
     versions_with_info: [
diff --git a/security/see/hdcp/README.md b/security/see/hdcp/README.md
new file mode 100644
index 0000000..76b8670
--- /dev/null
+++ b/security/see/hdcp/README.md
@@ -0,0 +1,65 @@
+# IHDCPAuthControl as a Trusted HAL service
+
+IHDCPAuthControl is expected to be a service implemented in a TEE.
+We provide a default reference implementation and its integration in Trusty
+as an example.
+
+The VTS test for a Trusted HAL service ought to run in the VM.
+We provide an integration of the VTS test in a Trusty VM,
+and later in a Microdroid VM (b/380632474).
+
+This interface shall not be exposed to the host and thus shall be part of
+the list of excluded interfaces from
+[compatibility_matrices/exclude/fcm_exclude.cpp](../../../compatibility_matrices/exclude/fcm_exclude.cpp)
+
+## 1. Mock Implementation
+
+The mock implementation under default/src/lib.rs is expected to be integrated in a
+TEE. For AOSP testing we offer two virtual device testing options:
+
+- Cuttlefish AVD, where the reference implementation is integrated in an AVF VM, emulating a TEE.
+- Trusty QEMU AVD, where the reference implementation is integrated in a Trusty TEE image (executed in secure world)
+
+### 1.1. Cuttlefish: Integrate in an AVF HAL pVM (Trusty)
+
+In Cuttlefish, we emulate a TEE with an AVF Trusty pVM.
+The VM2TZ IPC is emulated with a vsock port forward utility (b/379582767).
+
+Until vsock port forwarding is supported, the trusty_test_vm is used temporarily.
+(VTS tests and HAL implementation will be in same pVM).
+
+TODO: complete when trusty_hal_vm is created
+
+In order to add the mock HdcpAuthControlService to the trusty_test_vm, make sure
+that `hardware/interfaces/security/see/hdcp/default` is added to the
+trusty_test_vm makefile, by adding it to
+[trusty/device/x86/generic-x86_64/project/generic-x86_64-inc.mk](../../../../../trusty/device/x86/generic-x86_64/project/generic-x86_64-inc.mk)
+
+### 1.2. Trusty QEMU AVD: Integrate as a TA in Trusty TEE
+
+In order to add the mock HdcpAuthControlService to the Trusty TEE, make sure
+that `hardware/interfaces/security/see/hdcp/default` is added to
+[trusty/device/arm/generic-arm64/project/generic-arm-inc.mk](../../../../../trusty/device/arm/generic-arm64/project/generic-arm-inc.mk)
+
+
+## 2. VTS Tests
+
+IHdcpAuthControl service is expected to only be exposed to AVF pVM.
+
+The VTS tests shall verify:
+
+- IHdcpAuthControl cannot be accessed from the Android Host:
+
+   see [aidl/vts/src/host_test.rs](aidl/vts/host_test.rs)
+
+- IHdcpAuthControl can be accessed from an AVF pVM:
+
+   see [aidl/vts/src/vm_test.rs](aidl/vts/src/vm_test.rs)
+   see [aidl/vts/AndroidTest.xml](aidl/vts/AndroidTest.xml)
+
+
+To integrate the VTS test in the trusty_test_vm:
+
+1.
+1. add the test to [hardware/interfaces/security/see/usertests-rust-inc.mk](../usertests-rust-inc.mk)
+
diff --git a/security/see/hdcp/aidl/Android.bp b/security/see/hdcp/aidl/Android.bp
new file mode 100644
index 0000000..ad1db37
--- /dev/null
+++ b/security/see/hdcp/aidl/Android.bp
@@ -0,0 +1,57 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    default_team: "trendy_team_trusty",
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+aidl_interface {
+    name: "android.hardware.security.see.hdcp",
+    vendor_available: true,
+    srcs: ["android/hardware/security/see/hdcp/*.aidl"],
+    imports: [
+        "android.hardware.drm.common-V1",
+    ],
+    stability: "vintf",
+    frozen: false,
+    backend: {
+        java: {
+            enabled: false,
+        },
+        cpp: {
+            enabled: false,
+        },
+        ndk: {
+            min_sdk_version: "34",
+        },
+        rust: {
+            enabled: true,
+            gen_mockall: true,
+            additional_rustlibs: [
+                "libmockall",
+            ],
+        },
+    },
+}
+
+// A rust_defaults that includes the latest hdcp AIDL library.
+// Modules that depend on hdcp directly can include this rust_defaults to avoid
+// managing dependency versions explicitly.
+rust_defaults {
+    name: "hdcp_use_latest_hal_aidl_rust",
+    rustlibs: [
+        "android.hardware.security.see.hdcp-V1-rust",
+    ],
+}
diff --git a/security/see/hdcp/aidl/aidl_api/android.hardware.security.see.hdcp/current/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl b/security/see/hdcp/aidl/aidl_api/android.hardware.security.see.hdcp/current/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl
new file mode 100644
index 0000000..b73d554
--- /dev/null
+++ b/security/see/hdcp/aidl/aidl_api/android.hardware.security.see.hdcp/current/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+//     the interface (from the latest frozen version), the build system will
+//     prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.security.see.hdcp;
+@VintfStability
+interface IHdcpAuthControl {
+  android.hardware.drm.HdcpLevels getHdcpLevels();
+  void trySetHdcpLevel(in android.hardware.drm.HdcpLevel level);
+  android.hardware.security.see.hdcp.IHdcpAuthControl.PendingHdcpLevelResult getPendingHdcpLevel();
+  parcelable HalErrorCode {
+    const int NO_ERROR = 0;
+    const int GENERIC_ERROR = (-1) /* -1 */;
+    const int BAD_STATE = (-2) /* -2 */;
+    const int UNSUPPORTED = (-3) /* -3 */;
+    const int SERIALIZATION_ERROR = (-4) /* -4 */;
+    const int ALLOCATION_ERROR = (-5) /* -5 */;
+    const int BAD_PARAMETER = (-7) /* -7 */;
+    const int UNAUTHORIZED = (-8) /* -8 */;
+  }
+  parcelable PendingHdcpLevelResult {
+    android.hardware.security.see.hdcp.IHdcpAuthControl.PendingHdcpLevelResult.Status status;
+    android.hardware.drm.HdcpLevel level;
+    enum Status {
+      NONE,
+      PENDING,
+    }
+  }
+}
diff --git a/security/see/hdcp/aidl/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl b/security/see/hdcp/aidl/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl
new file mode 100644
index 0000000..b9a1fe5
--- /dev/null
+++ b/security/see/hdcp/aidl/android/hardware/security/see/hdcp/IHdcpAuthControl.aidl
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.hardware.security.see.hdcp;
+
+/**
+ * IHdcpAuthControl is used by the OEMCrypto Trusted Application to interact
+ * with a HDCP Encryption Trusted Application in order to control the
+ * HDCP Authentication Levels.
+ */
+@VintfStability
+interface IHdcpAuthControl {
+    /*
+     * Service error codes. Will be returned as service specific errors.
+     */
+    parcelable HalErrorCode {
+        /* Success */
+        const int NO_ERROR = 0;
+
+        /* Generic error */
+        const int GENERIC_ERROR = -1;
+
+        /* Desired operation cannot be performed because of the server current state */
+        const int BAD_STATE = -2;
+
+        /* Operation or parameters are not supported by the server */
+        const int UNSUPPORTED = -3;
+
+        /* Error encountered when parsing parameters */
+        const int SERIALIZATION_ERROR = -4;
+
+        /* Server ran out of memory when performing operation */
+        const int ALLOCATION_ERROR = -5;
+
+        /* Bad parameter supplied for the desired operation */
+        const int BAD_PARAMETER = -7;
+
+        /* Caller is not authorized to make this call */
+        const int UNAUTHORIZED = -8;
+    }
+    /**
+     * Result returned from the getPendingHdcpLevelResult API.
+     */
+    parcelable PendingHdcpLevelResult {
+        enum Status {
+            /**
+             * No pending HdcpLevel request
+             */
+            NONE,
+            /**
+             * a HdcpLevel request is pending, its level is provided in the
+             * |level| attribute
+             */
+            PENDING,
+        }
+        Status status;
+        android.hardware.drm.HdcpLevel level;
+    }
+
+    /**
+     * Return the currently negotiated and max supported HDCP levels.
+     *
+     * The current level is based on the display(s) the device is connected to.
+     * If multiple HDCP-capable displays are simultaneously connected to
+     * separate interfaces, this method returns the lowest negotiated HDCP level
+     * of all interfaces.
+     *
+     * The maximum HDCP level is the highest level that can potentially be
+     * negotiated. It is a constant for any device, i.e. it does not depend on
+     * downstream receiving devices that could be connected. For example, if
+     * the device has HDCP 1.x keys and is capable of negotiating HDCP 1.x, but
+     * does not have HDCP 2.x keys, then the maximum HDCP capability would be
+     * reported as 1.x. If multiple HDCP-capable interfaces are present, it
+     * indicates the highest of the maximum HDCP levels of all interfaces.
+     *
+     * This method should only be used for informational purposes, not for
+     * enforcing compliance with HDCP requirements. Trusted enforcement of HDCP
+     * policies must be handled by the DRM system.
+     *
+     * @return HdcpLevels parcelable
+     */
+    android.hardware.drm.HdcpLevels getHdcpLevels();
+
+    /**
+     * Attempts to set the device's HDCP auth level to |level|.
+     *
+     * @param level: desired HDCP level
+     *
+     * @return:
+     *     a service specific error based on <code>HalErrorCode</code>,
+     *     specifically:
+     *       + BAD_PARAMETER: when HDCP_UNKNOWN is requested
+     *       + UNSUPPORTED: when |level| is greater than the MaxLevel supported
+     *       + BAD_STATE: when the HDCP's service currentLevel is HDCP_NO_OUTPUT
+     *
+     */
+    void trySetHdcpLevel(in android.hardware.drm.HdcpLevel level);
+
+    /**
+     * Retrieve the pending level currently being processed by the HDCP service.
+     * The pending HDCP protection level might be higher than the level initially
+     * requested. This can occur when multiple applications or services are
+     * using HDCP concurrently, and a higher level is needed to satisfy
+     * all requirements.
+     *
+     * @return:
+     *      PendingHdcpLevelResult on success, which contains a status
+     *      and an optional level; on error a service specific error based on
+     *      <code>HalErrorCode</code> otherwise.
+     *
+     */
+    PendingHdcpLevelResult getPendingHdcpLevel();
+}
diff --git a/security/see/hdcp/aidl/trusty/drm/rust/rules.mk b/security/see/hdcp/aidl/trusty/drm/rust/rules.mk
new file mode 100644
index 0000000..742b6ab
--- /dev/null
+++ b/security/see/hdcp/aidl/trusty/drm/rust/rules.mk
@@ -0,0 +1,39 @@
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+AIDL_DIR := hardware/interfaces/drm/aidl
+
+MODULE_AIDL_FLAGS := \
+	--stability=vintf \
+	--version=1 \
+
+MODULE_CRATE_NAME := android_hardware_drm
+
+MODULE_AIDL_LANGUAGE := rust
+
+MODULE_AIDL_PACKAGE := android/hardware/drm
+
+MODULE_AIDL_INCLUDES := \
+	-I $(AIDL_DIR) \
+
+MODULE_AIDLS := \
+    $(AIDL_DIR)/$(MODULE_AIDL_PACKAGE)/HdcpLevel.aidl   \
+    $(AIDL_DIR)/$(MODULE_AIDL_PACKAGE)/HdcpLevels.aidl   \
+
+include make/aidl.mk
diff --git a/security/see/hdcp/aidl/trusty/hdcp/rust/rules.mk b/security/see/hdcp/aidl/trusty/hdcp/rust/rules.mk
new file mode 100644
index 0000000..beab655
--- /dev/null
+++ b/security/see/hdcp/aidl/trusty/hdcp/rust/rules.mk
@@ -0,0 +1,47 @@
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+AIDL_DIR := hardware/interfaces/security/see/hdcp/aidl
+DRM_AIDL_DIR := hardware/interfaces/drm/aidl
+
+MODULE_AIDL_FLAGS := \
+	--mockall \
+	--version=1 \
+
+MODULE_CRATE_NAME := android_hardware_security_see_hdcp
+
+MODULE_AIDL_LANGUAGE := rust
+
+MODULE_AIDL_PACKAGE := android/hardware/security/see/hdcp
+
+MODULE_AIDL_INCLUDES := \
+	-I $(AIDL_DIR) \
+	-I $(DRM_AIDL_DIR) \
+
+MODULE_AIDLS := \
+    $(AIDL_DIR)/$(MODULE_AIDL_PACKAGE)/IHdcpAuthControl.aidl   \
+
+MODULE_AIDL_RUST_DEPS := \
+	android_hardware_drm
+
+MODULE_LIBRARY_DEPS := \
+	hardware/interfaces/security/see/hdcp/aidl/trusty/drm/rust \
+	$(call FIND_CRATE,mockall) \
+
+include make/aidl.mk
diff --git a/security/see/hdcp/aidl/vts/Android.bp b/security/see/hdcp/aidl/vts/Android.bp
new file mode 100644
index 0000000..eadb9cd
--- /dev/null
+++ b/security/see/hdcp/aidl/vts/Android.bp
@@ -0,0 +1,36 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // 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: ["Android-Apache-2.0"],
+    default_team: "trendy_team_trusty",
+}
+
+rust_test {
+    name: "VtsAidlHdcpNonExistentTest",
+    srcs: ["src/host_test.rs"],
+    require_root: true,
+    test_suites: [
+        "general-tests",
+        "vts",
+    ],
+    rustlibs: [
+        "libbinder_rs",
+    ],
+}
diff --git a/security/see/hdcp/aidl/vts/src/host_test.rs b/security/see/hdcp/aidl/vts/src/host_test.rs
new file mode 100644
index 0000000..f64de20
--- /dev/null
+++ b/security/see/hdcp/aidl/vts/src/host_test.rs
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Test for asserting the non-existence of an IHdcpAuthControl.aidl
+
+#![cfg(test)]
+
+use binder;
+
+const HDCP_INTERFACE_NAME: &str = "android.hardware.security.see.hdcp.IHdcpAuthControl";
+
+#[test]
+fn test_hdcp_auth_control_non_existence() {
+    let hdcp_instances =  match binder::get_declared_instances(HDCP_INTERFACE_NAME) {
+        Ok(vec) => vec,
+        Err(e) => {
+            panic!("failed to retrieve the declared interfaces for HdcpAuthControl: {:?}", e);
+        }
+    };
+    assert!(hdcp_instances.is_empty());
+}