Merge "[rkp] Add IRemotelyProvisionedComponent skeleton impl in host" into main
diff --git a/apex/virtualizationservice.xml b/apex/virtualizationservice.xml
new file mode 100644
index 0000000..0ce1e10
--- /dev/null
+++ b/apex/virtualizationservice.xml
@@ -0,0 +1,7 @@
+<manifest version="1.0" type="framework">
+    <hal format="aidl">
+        <name>android.system.virtualization</name>
+        <version>3</version>
+        <fqname>IRemotelyProvisionedComponent/avf</fqname>
+    </hal>
+</manifest>
diff --git a/virtualizationservice/Android.bp b/virtualizationservice/Android.bp
index 74f88c5..ac9c1df 100644
--- a/virtualizationservice/Android.bp
+++ b/virtualizationservice/Android.bp
@@ -21,6 +21,7 @@
     },
     prefer_rlib: true,
     rustlibs: [
+        "android.hardware.security.rkp-V3-rust",
         "android.system.virtualizationcommon-rust",
         "android.system.virtualizationservice-rust",
         "android.system.virtualizationservice_internal-rust",
diff --git a/virtualizationservice/src/main.rs b/virtualizationservice/src/main.rs
index 3af0d42..cdb3ac9 100644
--- a/virtualizationservice/src/main.rs
+++ b/virtualizationservice/src/main.rs
@@ -16,6 +16,7 @@
 
 mod aidl;
 mod atom;
+mod remote_provisioning;
 mod rkpvm;
 mod service_vm;
 
@@ -32,6 +33,8 @@
 use std::os::unix::raw::{pid_t, uid_t};
 
 const LOG_TAG: &str = "VirtualizationService";
+const _REMOTELY_PROVISIONED_COMPONENT_SERVICE_NAME: &str =
+    "android.system.virtualization.IRemotelyProvisionedComponent/avf";
 
 fn get_calling_pid() -> pid_t {
     ThreadState::get_calling_pid()
@@ -61,7 +64,13 @@
     let service = VirtualizationServiceInternal::init();
     let service = BnVirtualizationServiceInternal::new_binder(service, BinderFeatures::default());
     register_lazy_service(BINDER_SERVICE_IDENTIFIER, service.as_binder()).unwrap();
-    info!("Registered Binder service, joining threadpool.");
+    info!("Registered Binder service {}.", BINDER_SERVICE_IDENTIFIER);
+
+    // The IRemotelyProvisionedComponent service is only supposed to be triggered by rkpd for
+    // RKP VM attestation.
+    let _remote_provisioning_service = remote_provisioning::new_binder();
+    // TODO(b/274881098): Register the RKP service when the implementation is ready.
+
     ProcessState::join_thread_pool();
 }
 
diff --git a/virtualizationservice/src/remote_provisioning.rs b/virtualizationservice/src/remote_provisioning.rs
new file mode 100644
index 0000000..1acbcee
--- /dev/null
+++ b/virtualizationservice/src/remote_provisioning.rs
@@ -0,0 +1,86 @@
+// Copyright 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.
+
+//! IRemotelyProvisionedComponent HAL implementation.
+
+use android_hardware_security_rkp::aidl::android::hardware::security::keymint::{
+    DeviceInfo::DeviceInfo,
+    IRemotelyProvisionedComponent::{
+        BnRemotelyProvisionedComponent, IRemotelyProvisionedComponent, STATUS_REMOVED,
+    },
+    MacedPublicKey::MacedPublicKey,
+    ProtectedData::ProtectedData,
+    RpcHardwareInfo::{RpcHardwareInfo, CURVE_NONE, MIN_SUPPORTED_NUM_KEYS_IN_CSR},
+};
+use avflog::LogResult;
+use binder::{BinderFeatures, ExceptionCode, Interface, Result as BinderResult, Status, Strong};
+
+/// Constructs a binder object that implements `IRemotelyProvisionedComponent`.
+pub(crate) fn new_binder() -> Strong<dyn IRemotelyProvisionedComponent> {
+    BnRemotelyProvisionedComponent::new_binder(
+        AvfRemotelyProvisionedComponent {},
+        BinderFeatures::default(),
+    )
+}
+
+struct AvfRemotelyProvisionedComponent {}
+
+impl Interface for AvfRemotelyProvisionedComponent {}
+
+#[allow(non_snake_case)]
+impl IRemotelyProvisionedComponent for AvfRemotelyProvisionedComponent {
+    fn getHardwareInfo(&self) -> BinderResult<RpcHardwareInfo> {
+        Ok(RpcHardwareInfo {
+            versionNumber: 3,
+            rpcAuthorName: String::from("Android Virtualization Framework"),
+            supportedEekCurve: CURVE_NONE,
+            uniqueId: Some(String::from("Android Virtualization Framework 1")),
+            supportedNumKeysInCsr: MIN_SUPPORTED_NUM_KEYS_IN_CSR,
+        })
+    }
+
+    fn generateEcdsaP256KeyPair(
+        &self,
+        _testMode: bool,
+        _macedPublicKey: &mut MacedPublicKey,
+    ) -> BinderResult<Vec<u8>> {
+        // TODO(b/274881098): Implement this.
+        Err(Status::new_exception(ExceptionCode::UNSUPPORTED_OPERATION, None)).with_log()
+    }
+
+    fn generateCertificateRequest(
+        &self,
+        _testMode: bool,
+        _keysToSign: &[MacedPublicKey],
+        _endpointEncryptionCertChain: &[u8],
+        _challenge: &[u8],
+        _deviceInfo: &mut DeviceInfo,
+        _protectedData: &mut ProtectedData,
+    ) -> BinderResult<Vec<u8>> {
+        Err(Status::new_service_specific_error_str(
+            STATUS_REMOVED,
+            Some("This method was deprecated in v3 of the interface."),
+        ))
+        .with_log()
+    }
+
+    fn generateCertificateRequestV2(
+        &self,
+        _keysToSign: &[MacedPublicKey],
+        _challenge: &[u8],
+    ) -> BinderResult<Vec<u8>> {
+        // TODO(b/274881098): Implement this.
+        Err(Status::new_exception(ExceptionCode::UNSUPPORTED_OPERATION, None)).with_log()
+    }
+}