blob: c9d68eda43c69ac80e44b5b7b0fd7120356f032c [file] [log] [blame]
David Brazdil66fc1202022-07-04 21:48:45 +01001// Copyright 2022, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Integration test for Rialto.
16
17use android_system_virtualizationservice::{
18 aidl::android::system::virtualizationservice::{
Alice Wanga6357692023-09-07 14:59:37 +000019 VirtualMachineConfig::VirtualMachineConfig,
David Brazdil66fc1202022-07-04 21:48:45 +010020 VirtualMachineRawConfig::VirtualMachineRawConfig,
21 },
22 binder::{ParcelFileDescriptor, ProcessState},
23};
Alice Wang9646fb32023-09-08 10:01:31 +000024use anyhow::{bail, Context, Result};
David Brazdil66fc1202022-07-04 21:48:45 +010025use log::info;
Alice Wang9646fb32023-09-08 10:01:31 +000026use service_vm_comm::{
27 EcdsaP256KeyPair, GenerateCertificateRequestParams, Request, Response, VmType,
28};
Alice Wang17dc76e2023-09-06 09:43:52 +000029use service_vm_manager::ServiceVm;
David Brazdil66fc1202022-07-04 21:48:45 +010030use std::fs::File;
David Brazdil66fc1202022-07-04 21:48:45 +010031use std::panic;
Alice Wang17dc76e2023-09-06 09:43:52 +000032use std::path::PathBuf;
Alice Wang17dc76e2023-09-06 09:43:52 +000033use vmclient::VmInstance;
Alice Wang4e082c32023-07-11 07:41:50 +000034
Alice Wang9a8b39f2023-04-12 15:31:48 +000035const UNSIGNED_RIALTO_PATH: &str = "/data/local/tmp/rialto_test/arm64/rialto_unsigned.bin";
36const INSTANCE_IMG_PATH: &str = "/data/local/tmp/rialto_test/arm64/instance.img";
David Brazdil66fc1202022-07-04 21:48:45 +010037
Alice Wang9a8b39f2023-04-12 15:31:48 +000038#[test]
Alice Wange910b902023-09-07 10:35:12 +000039fn process_requests_in_protected_vm() -> Result<()> {
Alice Wang9646fb32023-09-08 10:01:31 +000040 check_processing_requests(VmType::ProtectedVm)
Alice Wang9a8b39f2023-04-12 15:31:48 +000041}
42
Alice Wange910b902023-09-07 10:35:12 +000043#[test]
44fn process_requests_in_non_protected_vm() -> Result<()> {
Alice Wang9646fb32023-09-08 10:01:31 +000045 check_processing_requests(VmType::NonProtectedVm)
46}
47
48fn check_processing_requests(vm_type: VmType) -> Result<()> {
49 let mut vm = start_service_vm(vm_type)?;
Alice Wange910b902023-09-07 10:35:12 +000050
51 check_processing_reverse_request(&mut vm)?;
Alice Wangff5592d2023-09-13 15:27:39 +000052 let maced_public_key = check_processing_generating_key_pair_request(&mut vm)?;
53 check_processing_generating_certificate_request(&mut vm, maced_public_key)?;
Alice Wange910b902023-09-07 10:35:12 +000054 Ok(())
55}
56
57fn check_processing_reverse_request(vm: &mut ServiceVm) -> Result<()> {
58 // TODO(b/292080257): Test with message longer than the receiver's buffer capacity
59 // 1024 bytes once the guest virtio-vsock driver fixes the credit update in recv().
60 let message = "abc".repeat(166);
61 let request = Request::Reverse(message.as_bytes().to_vec());
62
Alice Wangfbdc85b2023-09-07 12:56:46 +000063 let response = vm.process_request(request)?;
64 info!("Received response: {response:?}.");
Alice Wange910b902023-09-07 10:35:12 +000065
66 let expected_response: Vec<u8> = message.as_bytes().iter().rev().cloned().collect();
67 assert_eq!(Response::Reverse(expected_response), response);
68 Ok(())
69}
70
Alice Wangff5592d2023-09-13 15:27:39 +000071fn check_processing_generating_key_pair_request(vm: &mut ServiceVm) -> Result<Vec<u8>> {
Alice Wang9646fb32023-09-08 10:01:31 +000072 let request = Request::GenerateEcdsaP256KeyPair;
73
74 let response = vm.process_request(request)?;
75 info!("Received response: {response:?}.");
76
77 match response {
Alice Wanga78d3f02023-09-13 12:39:16 +000078 Response::GenerateEcdsaP256KeyPair(EcdsaP256KeyPair { maced_public_key, .. }) => {
79 assert_array_has_nonzero(&maced_public_key[..]);
Alice Wangff5592d2023-09-13 15:27:39 +000080 Ok(maced_public_key)
Alice Wanga78d3f02023-09-13 12:39:16 +000081 }
Alice Wangff5592d2023-09-13 15:27:39 +000082 _ => bail!("Incorrect response type: {response:?}"),
Alice Wang9646fb32023-09-08 10:01:31 +000083 }
84}
85
Alice Wanga78d3f02023-09-13 12:39:16 +000086fn assert_array_has_nonzero(v: &[u8]) {
87 assert!(v.iter().any(|&x| x != 0))
88}
89
Alice Wangff5592d2023-09-13 15:27:39 +000090fn check_processing_generating_certificate_request(
91 vm: &mut ServiceVm,
92 maced_public_key: Vec<u8>,
93) -> Result<()> {
94 let params = GenerateCertificateRequestParams {
95 keys_to_sign: vec![maced_public_key],
96 challenge: vec![],
97 };
Alice Wang9646fb32023-09-08 10:01:31 +000098 let request = Request::GenerateCertificateRequest(params);
99
100 let response = vm.process_request(request)?;
101 info!("Received response: {response:?}.");
102
103 match response {
104 Response::GenerateCertificateRequest(_) => Ok(()),
Alice Wangff5592d2023-09-13 15:27:39 +0000105 _ => bail!("Incorrect response type: {response:?}"),
Alice Wang9646fb32023-09-08 10:01:31 +0000106 }
107}
108
Alice Wange910b902023-09-07 10:35:12 +0000109fn start_service_vm(vm_type: VmType) -> Result<ServiceVm> {
David Brazdil66fc1202022-07-04 21:48:45 +0100110 android_logger::init_once(
111 android_logger::Config::default().with_tag("rialto").with_min_level(log::Level::Debug),
112 );
David Brazdil66fc1202022-07-04 21:48:45 +0100113 // Redirect panic messages to logcat.
114 panic::set_hook(Box::new(|panic_info| {
115 log::error!("{}", panic_info);
116 }));
David Brazdil66fc1202022-07-04 21:48:45 +0100117 // We need to start the thread pool for Binder to work properly, especially link_to_death.
118 ProcessState::start_thread_pool();
Alice Wange910b902023-09-07 10:35:12 +0000119 ServiceVm::start_vm(vm_instance(vm_type)?, vm_type)
Alice Wang17dc76e2023-09-06 09:43:52 +0000120}
121
Alice Wange910b902023-09-07 10:35:12 +0000122fn vm_instance(vm_type: VmType) -> Result<VmInstance> {
Alice Wanga6357692023-09-07 14:59:37 +0000123 match vm_type {
Alice Wang1d9a5872023-09-06 14:32:36 +0000124 VmType::ProtectedVm => {
Alice Wanga6357692023-09-07 14:59:37 +0000125 service_vm_manager::protected_vm_instance(PathBuf::from(INSTANCE_IMG_PATH))
Alice Wang1d9a5872023-09-06 14:32:36 +0000126 }
Alice Wanga6357692023-09-07 14:59:37 +0000127 VmType::NonProtectedVm => nonprotected_vm_instance(),
128 }
129}
130
131fn nonprotected_vm_instance() -> Result<VmInstance> {
132 let rialto = File::open(UNSIGNED_RIALTO_PATH).context("Failed to open Rialto kernel binary")?;
David Brazdil66fc1202022-07-04 21:48:45 +0100133 let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig {
Alice Wanga6357692023-09-07 14:59:37 +0000134 name: String::from("Non protected rialto"),
David Brazdil66fc1202022-07-04 21:48:45 +0100135 bootloader: Some(ParcelFileDescriptor::new(rialto)),
Alice Wanga6357692023-09-07 14:59:37 +0000136 protectedVm: false,
David Brazdil66fc1202022-07-04 21:48:45 +0100137 memoryMib: 300,
David Brazdil66fc1202022-07-04 21:48:45 +0100138 platformVersion: "~1.0".to_string(),
Inseob Kim6ef80972023-07-20 17:23:36 +0900139 ..Default::default()
David Brazdil66fc1202022-07-04 21:48:45 +0100140 });
Alice Wanga6357692023-09-07 14:59:37 +0000141 let console = Some(service_vm_manager::android_log_fd()?);
142 let log = Some(service_vm_manager::android_log_fd()?);
143 let virtmgr = vmclient::VirtualizationService::new().context("Failed to spawn VirtMgr")?;
144 let service = virtmgr.connect().context("Failed to connect to VirtMgr")?;
145 info!("Connected to VirtMgr for service VM");
146 VmInstance::create(service.as_ref(), &config, console, /* consoleIn */ None, log, None)
147 .context("Failed to create VM")
David Brazdil66fc1202022-07-04 21:48:45 +0100148}