David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 1 | // 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 | |
| 17 | use android_system_virtualizationservice::{ |
| 18 | aidl::android::system::virtualizationservice::{ |
Alice Wang | a635769 | 2023-09-07 14:59:37 +0000 | [diff] [blame] | 19 | VirtualMachineConfig::VirtualMachineConfig, |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 20 | VirtualMachineRawConfig::VirtualMachineRawConfig, |
| 21 | }, |
| 22 | binder::{ParcelFileDescriptor, ProcessState}, |
| 23 | }; |
Alice Wang | 9646fb3 | 2023-09-08 10:01:31 +0000 | [diff] [blame] | 24 | use anyhow::{bail, Context, Result}; |
Alice Wang | f7c0f94 | 2023-09-14 09:33:04 +0000 | [diff] [blame] | 25 | use ciborium::value::Value; |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 26 | use log::info; |
Alice Wang | 9646fb3 | 2023-09-08 10:01:31 +0000 | [diff] [blame] | 27 | use service_vm_comm::{ |
| 28 | EcdsaP256KeyPair, GenerateCertificateRequestParams, Request, Response, VmType, |
| 29 | }; |
Alice Wang | 17dc76e | 2023-09-06 09:43:52 +0000 | [diff] [blame] | 30 | use service_vm_manager::ServiceVm; |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 31 | use std::fs::File; |
Alice Wang | f7c0f94 | 2023-09-14 09:33:04 +0000 | [diff] [blame] | 32 | use std::io; |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 33 | use std::panic; |
Alice Wang | 17dc76e | 2023-09-06 09:43:52 +0000 | [diff] [blame] | 34 | use std::path::PathBuf; |
Alice Wang | 17dc76e | 2023-09-06 09:43:52 +0000 | [diff] [blame] | 35 | use vmclient::VmInstance; |
Alice Wang | 4e082c3 | 2023-07-11 07:41:50 +0000 | [diff] [blame] | 36 | |
Alice Wang | 9a8b39f | 2023-04-12 15:31:48 +0000 | [diff] [blame] | 37 | const UNSIGNED_RIALTO_PATH: &str = "/data/local/tmp/rialto_test/arm64/rialto_unsigned.bin"; |
| 38 | const INSTANCE_IMG_PATH: &str = "/data/local/tmp/rialto_test/arm64/instance.img"; |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 39 | |
Alice Wang | 9a8b39f | 2023-04-12 15:31:48 +0000 | [diff] [blame] | 40 | #[test] |
Alice Wang | e910b90 | 2023-09-07 10:35:12 +0000 | [diff] [blame] | 41 | fn process_requests_in_protected_vm() -> Result<()> { |
Alice Wang | 9646fb3 | 2023-09-08 10:01:31 +0000 | [diff] [blame] | 42 | check_processing_requests(VmType::ProtectedVm) |
Alice Wang | 9a8b39f | 2023-04-12 15:31:48 +0000 | [diff] [blame] | 43 | } |
| 44 | |
Alice Wang | e910b90 | 2023-09-07 10:35:12 +0000 | [diff] [blame] | 45 | #[test] |
| 46 | fn process_requests_in_non_protected_vm() -> Result<()> { |
Alice Wang | 9646fb3 | 2023-09-08 10:01:31 +0000 | [diff] [blame] | 47 | check_processing_requests(VmType::NonProtectedVm) |
| 48 | } |
| 49 | |
| 50 | fn check_processing_requests(vm_type: VmType) -> Result<()> { |
| 51 | let mut vm = start_service_vm(vm_type)?; |
Alice Wang | e910b90 | 2023-09-07 10:35:12 +0000 | [diff] [blame] | 52 | |
| 53 | check_processing_reverse_request(&mut vm)?; |
Alice Wang | ff5592d | 2023-09-13 15:27:39 +0000 | [diff] [blame] | 54 | let maced_public_key = check_processing_generating_key_pair_request(&mut vm)?; |
| 55 | check_processing_generating_certificate_request(&mut vm, maced_public_key)?; |
Alice Wang | e910b90 | 2023-09-07 10:35:12 +0000 | [diff] [blame] | 56 | Ok(()) |
| 57 | } |
| 58 | |
| 59 | fn check_processing_reverse_request(vm: &mut ServiceVm) -> Result<()> { |
| 60 | // TODO(b/292080257): Test with message longer than the receiver's buffer capacity |
| 61 | // 1024 bytes once the guest virtio-vsock driver fixes the credit update in recv(). |
| 62 | let message = "abc".repeat(166); |
| 63 | let request = Request::Reverse(message.as_bytes().to_vec()); |
| 64 | |
Alice Wang | fbdc85b | 2023-09-07 12:56:46 +0000 | [diff] [blame] | 65 | let response = vm.process_request(request)?; |
| 66 | info!("Received response: {response:?}."); |
Alice Wang | e910b90 | 2023-09-07 10:35:12 +0000 | [diff] [blame] | 67 | |
| 68 | let expected_response: Vec<u8> = message.as_bytes().iter().rev().cloned().collect(); |
| 69 | assert_eq!(Response::Reverse(expected_response), response); |
| 70 | Ok(()) |
| 71 | } |
| 72 | |
Alice Wang | ff5592d | 2023-09-13 15:27:39 +0000 | [diff] [blame] | 73 | fn check_processing_generating_key_pair_request(vm: &mut ServiceVm) -> Result<Vec<u8>> { |
Alice Wang | 9646fb3 | 2023-09-08 10:01:31 +0000 | [diff] [blame] | 74 | let request = Request::GenerateEcdsaP256KeyPair; |
| 75 | |
| 76 | let response = vm.process_request(request)?; |
| 77 | info!("Received response: {response:?}."); |
| 78 | |
| 79 | match response { |
Alice Wang | 8b8e6e6 | 2023-10-02 09:10:13 +0000 | [diff] [blame] | 80 | Response::GenerateEcdsaP256KeyPair(EcdsaP256KeyPair { maced_public_key, key_blob }) => { |
| 81 | assert_array_has_nonzero(&maced_public_key); |
| 82 | assert_array_has_nonzero(&key_blob); |
Alice Wang | ff5592d | 2023-09-13 15:27:39 +0000 | [diff] [blame] | 83 | Ok(maced_public_key) |
Alice Wang | a78d3f0 | 2023-09-13 12:39:16 +0000 | [diff] [blame] | 84 | } |
Alice Wang | ff5592d | 2023-09-13 15:27:39 +0000 | [diff] [blame] | 85 | _ => bail!("Incorrect response type: {response:?}"), |
Alice Wang | 9646fb3 | 2023-09-08 10:01:31 +0000 | [diff] [blame] | 86 | } |
| 87 | } |
| 88 | |
Alice Wang | a78d3f0 | 2023-09-13 12:39:16 +0000 | [diff] [blame] | 89 | fn assert_array_has_nonzero(v: &[u8]) { |
| 90 | assert!(v.iter().any(|&x| x != 0)) |
| 91 | } |
| 92 | |
Alice Wang | ff5592d | 2023-09-13 15:27:39 +0000 | [diff] [blame] | 93 | fn check_processing_generating_certificate_request( |
| 94 | vm: &mut ServiceVm, |
| 95 | maced_public_key: Vec<u8>, |
| 96 | ) -> Result<()> { |
| 97 | let params = GenerateCertificateRequestParams { |
| 98 | keys_to_sign: vec![maced_public_key], |
| 99 | challenge: vec![], |
| 100 | }; |
Alice Wang | 9646fb3 | 2023-09-08 10:01:31 +0000 | [diff] [blame] | 101 | let request = Request::GenerateCertificateRequest(params); |
| 102 | |
| 103 | let response = vm.process_request(request)?; |
| 104 | info!("Received response: {response:?}."); |
| 105 | |
| 106 | match response { |
Alice Wang | f7c0f94 | 2023-09-14 09:33:04 +0000 | [diff] [blame] | 107 | Response::GenerateCertificateRequest(csr) => check_csr(csr), |
Alice Wang | ff5592d | 2023-09-13 15:27:39 +0000 | [diff] [blame] | 108 | _ => bail!("Incorrect response type: {response:?}"), |
Alice Wang | 9646fb3 | 2023-09-08 10:01:31 +0000 | [diff] [blame] | 109 | } |
| 110 | } |
| 111 | |
Alice Wang | f7c0f94 | 2023-09-14 09:33:04 +0000 | [diff] [blame] | 112 | /// TODO(b/300625792): Check the CSR with libhwtrust once the CSR is complete. |
| 113 | fn check_csr(csr: Vec<u8>) -> Result<()> { |
| 114 | let mut reader = io::Cursor::new(csr); |
| 115 | let csr: Value = ciborium::from_reader(&mut reader)?; |
| 116 | match csr { |
| 117 | Value::Array(arr) => { |
| 118 | assert_eq!(4, arr.len()); |
| 119 | } |
| 120 | _ => bail!("Incorrect CSR format: {csr:?}"), |
| 121 | } |
| 122 | Ok(()) |
| 123 | } |
| 124 | |
Alice Wang | e910b90 | 2023-09-07 10:35:12 +0000 | [diff] [blame] | 125 | fn start_service_vm(vm_type: VmType) -> Result<ServiceVm> { |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 126 | android_logger::init_once( |
| 127 | android_logger::Config::default().with_tag("rialto").with_min_level(log::Level::Debug), |
| 128 | ); |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 129 | // Redirect panic messages to logcat. |
| 130 | panic::set_hook(Box::new(|panic_info| { |
| 131 | log::error!("{}", panic_info); |
| 132 | })); |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 133 | // We need to start the thread pool for Binder to work properly, especially link_to_death. |
| 134 | ProcessState::start_thread_pool(); |
Alice Wang | e910b90 | 2023-09-07 10:35:12 +0000 | [diff] [blame] | 135 | ServiceVm::start_vm(vm_instance(vm_type)?, vm_type) |
Alice Wang | 17dc76e | 2023-09-06 09:43:52 +0000 | [diff] [blame] | 136 | } |
| 137 | |
Alice Wang | e910b90 | 2023-09-07 10:35:12 +0000 | [diff] [blame] | 138 | fn vm_instance(vm_type: VmType) -> Result<VmInstance> { |
Alice Wang | a635769 | 2023-09-07 14:59:37 +0000 | [diff] [blame] | 139 | match vm_type { |
Alice Wang | 1d9a587 | 2023-09-06 14:32:36 +0000 | [diff] [blame] | 140 | VmType::ProtectedVm => { |
Alice Wang | a635769 | 2023-09-07 14:59:37 +0000 | [diff] [blame] | 141 | service_vm_manager::protected_vm_instance(PathBuf::from(INSTANCE_IMG_PATH)) |
Alice Wang | 1d9a587 | 2023-09-06 14:32:36 +0000 | [diff] [blame] | 142 | } |
Alice Wang | a635769 | 2023-09-07 14:59:37 +0000 | [diff] [blame] | 143 | VmType::NonProtectedVm => nonprotected_vm_instance(), |
| 144 | } |
| 145 | } |
| 146 | |
| 147 | fn nonprotected_vm_instance() -> Result<VmInstance> { |
| 148 | let rialto = File::open(UNSIGNED_RIALTO_PATH).context("Failed to open Rialto kernel binary")?; |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 149 | let config = VirtualMachineConfig::RawConfig(VirtualMachineRawConfig { |
Alice Wang | a635769 | 2023-09-07 14:59:37 +0000 | [diff] [blame] | 150 | name: String::from("Non protected rialto"), |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 151 | bootloader: Some(ParcelFileDescriptor::new(rialto)), |
Alice Wang | a635769 | 2023-09-07 14:59:37 +0000 | [diff] [blame] | 152 | protectedVm: false, |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 153 | memoryMib: 300, |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 154 | platformVersion: "~1.0".to_string(), |
Inseob Kim | 6ef8097 | 2023-07-20 17:23:36 +0900 | [diff] [blame] | 155 | ..Default::default() |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 156 | }); |
Alice Wang | a635769 | 2023-09-07 14:59:37 +0000 | [diff] [blame] | 157 | let console = Some(service_vm_manager::android_log_fd()?); |
| 158 | let log = Some(service_vm_manager::android_log_fd()?); |
| 159 | let virtmgr = vmclient::VirtualizationService::new().context("Failed to spawn VirtMgr")?; |
| 160 | let service = virtmgr.connect().context("Failed to connect to VirtMgr")?; |
| 161 | info!("Connected to VirtMgr for service VM"); |
| 162 | VmInstance::create(service.as_ref(), &config, console, /* consoleIn */ None, log, None) |
| 163 | .context("Failed to create VM") |
David Brazdil | 66fc120 | 2022-07-04 21:48:45 +0100 | [diff] [blame] | 164 | } |