Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2022 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | //! Trusty handler for IPC connections. It handles both secure and non-secure world ports. |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 17 | use crate::secure_storage_manager; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 18 | use alloc::{rc::Rc, vec::Vec}; |
| 19 | use core::{cell::RefCell, mem}; |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 20 | use keymint_access_policy::{ |
| 21 | keymint_check_secure_target_access_policy_provisioning, keymint_check_target_access_policy, |
| 22 | }; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 23 | use kmr_common::{ |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 24 | crypto, km_err, |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 25 | wire::legacy::{ |
Orlando Arbildo | 1090e1e | 2023-02-16 20:48:13 +0000 | [diff] [blame] | 26 | self, AppendAttestationCertChainResponse, ClearAttestationCertChainResponse, |
| 27 | ConfigureBootPatchlevelResponse, GetAuthTokenKeyResponse, GetDeviceInfoResponse, |
| 28 | GetVersion2Response, GetVersionResponse, SetAttestationIdsKM3Response, |
| 29 | SetAttestationIdsResponse, SetAttestationKeyResponse, SetBootParamsResponse, |
Orlando Arbildo | ede9128 | 2023-02-18 01:14:02 +0000 | [diff] [blame] | 30 | SetWrappedAttestationKeyResponse, TrustyMessageId, TrustyPerformOpReq, TrustyPerformOpRsp, |
| 31 | TrustyPerformSecureOpReq, TrustyPerformSecureOpRsp, |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 32 | }, |
| 33 | Error, |
| 34 | }; |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 35 | use kmr_ta::{self, device::SigningAlgorithm, split_rsp, HardwareInfo, KeyMintTa, RpcInfo}; |
| 36 | use kmr_wire::keymint::{Algorithm, BootInfo}; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 37 | use log::{debug, error, info}; |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 38 | use system_state::{ProvisioningAllowedFlagValues, SystemState, SystemStateFlag}; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 39 | use tipc::{ |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 40 | service_dispatcher, ConnectResult, Deserialize, Handle, Manager, MessageResult, PortCfg, |
| 41 | Serialize, Serializer, Service, TipcError, Uuid, |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 42 | }; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 43 | use trusty_std::alloc::TryAllocFrom; |
| 44 | |
Orlando Arbildo | 26583f0 | 2023-01-03 19:16:07 +0000 | [diff] [blame] | 45 | /// Port that handles new style keymint messages from non-secure world |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 46 | const KM_NS_TIPC_SRV_PORT: &str = "com.android.trusty.keymint"; |
Orlando Arbildo | 26583f0 | 2023-01-03 19:16:07 +0000 | [diff] [blame] | 47 | /// Port that handles secure world messages |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 48 | const KM_SEC_TIPC_SRV_PORT: &str = "com.android.trusty.keymaster.secure"; |
Orlando Arbildo | 26583f0 | 2023-01-03 19:16:07 +0000 | [diff] [blame] | 49 | /// Port that handles legacy style keymint/keymaster messages |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 50 | const KM_NS_LEGACY_TIPC_SRV_PORT: &str = "com.android.trusty.keymaster"; |
David Drysdale | d1d71c6 | 2023-03-27 18:48:51 +0100 | [diff] [blame] | 51 | /// Port count for this TA (as above). |
| 52 | const PORT_COUNT: usize = 3; |
| 53 | /// Maximum connection count for this TA: |
| 54 | /// - Gatekeeper |
| 55 | /// - Fingerprint |
| 56 | /// - FaceAuth |
| 57 | /// - Widevine |
| 58 | /// - Non-secure world. |
| 59 | const MAX_CONNECTION_COUNT: usize = 5; |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 60 | |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 61 | const KEYMINT_MAX_BUFFER_LENGTH: usize = 4096; |
Hasini Gunasinghe | 85edc4d | 2022-10-14 02:09:32 +0000 | [diff] [blame] | 62 | const KEYMINT_MAX_MESSAGE_CONTENT_SIZE: usize = 4000; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 63 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 64 | /// TIPC connection context information. |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 65 | struct Context { |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 66 | uuid: Uuid, |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 67 | } |
| 68 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 69 | /// Newtype wrapper for opaque messages. |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 70 | struct KMMessage(Vec<u8>); |
| 71 | |
| 72 | impl Deserialize for KMMessage { |
| 73 | type Error = TipcError; |
| 74 | const MAX_SERIALIZED_SIZE: usize = KEYMINT_MAX_BUFFER_LENGTH; |
| 75 | |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 76 | fn deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> tipc::Result<Self> { |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 77 | Ok(KMMessage(Vec::try_alloc_from(bytes)?)) |
| 78 | } |
| 79 | } |
| 80 | |
| 81 | impl<'s> Serialize<'s> for KMMessage { |
| 82 | fn serialize<'a: 's, S: Serializer<'s>>( |
| 83 | &'a self, |
| 84 | serializer: &mut S, |
| 85 | ) -> Result<S::Ok, S::Error> { |
| 86 | serializer.serialize_bytes(&self.0.as_slice()) |
| 87 | } |
| 88 | } |
| 89 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 90 | /// Convert KeyMint [`Algorithm`] to [`SigningAlgorithm`]. |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 91 | fn keymaster_algorithm_to_signing_algorithm( |
| 92 | algorithm: Algorithm, |
| 93 | ) -> Result<SigningAlgorithm, Error> { |
| 94 | match algorithm { |
| 95 | Algorithm::Rsa => Ok(SigningAlgorithm::Rsa), |
| 96 | Algorithm::Ec => Ok(SigningAlgorithm::Ec), |
| 97 | _ => Err(km_err!( |
| 98 | Unimplemented, |
| 99 | "only supported algorithms are RSA and EC. Got {}", |
| 100 | algorithm as u32 |
| 101 | )), |
| 102 | } |
| 103 | } |
| 104 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 105 | /// TIPC service implementation for communication with the HAL service in Android. |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 106 | struct KMService { |
| 107 | km_ta: Rc<RefCell<KeyMintTa>>, |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 108 | } |
| 109 | |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 110 | impl KMService { |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 111 | /// Create a service implementation. |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 112 | fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self { |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 113 | KMService { km_ta } |
| 114 | } |
| 115 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 116 | /// Process an incoming request message, returning the response as a collection of fragments |
| 117 | /// that are each small enough to send over the channel. |
Hasini Gunasinghe | 85edc4d | 2022-10-14 02:09:32 +0000 | [diff] [blame] | 118 | fn handle_message(&self, req_data: &[u8]) -> Result<Vec<Vec<u8>>, Error> { |
| 119 | let resp = self.km_ta.borrow_mut().process(req_data); |
| 120 | split_rsp(resp.as_slice(), KEYMINT_MAX_MESSAGE_CONTENT_SIZE) |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 121 | } |
| 122 | } |
| 123 | |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 124 | impl Service for KMService { |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 125 | type Connection = Context; |
| 126 | type Message = KMMessage; |
| 127 | |
| 128 | fn on_connect( |
| 129 | &self, |
| 130 | _port: &PortCfg, |
| 131 | _handle: &Handle, |
| 132 | peer: &Uuid, |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 133 | ) -> tipc::Result<ConnectResult<Self::Connection>> { |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 134 | info!("Accepted connection from uuid {:?}.", peer); |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 135 | Ok(ConnectResult::Accept(Context { uuid: peer.clone() })) |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 136 | } |
| 137 | |
| 138 | fn on_message( |
| 139 | &self, |
| 140 | _connection: &Self::Connection, |
| 141 | handle: &Handle, |
| 142 | msg: Self::Message, |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 143 | ) -> tipc::Result<MessageResult> { |
Orlando Arbildo | fcce550 | 2023-01-19 01:05:01 +0000 | [diff] [blame] | 144 | debug!("Received a message."); |
Hasini Gunasinghe | 85edc4d | 2022-10-14 02:09:32 +0000 | [diff] [blame] | 145 | let resp_vec = self.handle_message(&msg.0).map_err(|e| match e { |
| 146 | Error::Hal(_, err_msg) => { |
Orlando Arbildo | fcce550 | 2023-01-19 01:05:01 +0000 | [diff] [blame] | 147 | error!("Error: {} in handling the message.", err_msg); |
Hasini Gunasinghe | 85edc4d | 2022-10-14 02:09:32 +0000 | [diff] [blame] | 148 | TipcError::InvalidData |
| 149 | } |
| 150 | Error::Alloc(err_msg) => { |
Orlando Arbildo | fcce550 | 2023-01-19 01:05:01 +0000 | [diff] [blame] | 151 | error!("Error: {} in handling the message.", err_msg); |
Hasini Gunasinghe | 85edc4d | 2022-10-14 02:09:32 +0000 | [diff] [blame] | 152 | TipcError::AllocError |
| 153 | } |
| 154 | _ => TipcError::UnknownError, |
| 155 | })?; |
| 156 | for resp in resp_vec { |
| 157 | handle.send(&KMMessage(resp))?; |
| 158 | } |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 159 | Ok(MessageResult::MaintainConnection) |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 160 | } |
| 161 | } |
| 162 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 163 | /// Retrieve the system state flag controlling provisioning. |
| 164 | fn get_system_state_provisioning_flag() -> Result<ProvisioningAllowedFlagValues, Error> { |
| 165 | let system_state_session = SystemState::try_connect().map_err(|e| { |
| 166 | km_err!(SecureHwCommunicationFailed, "couldn't connect to system state provider: {:?}", e) |
| 167 | })?; |
| 168 | let flag = |
| 169 | system_state_session.get_flag(SystemStateFlag::ProvisioningAllowed).map_err(|e| { |
| 170 | km_err!( |
| 171 | SecureHwCommunicationFailed, |
| 172 | "couldn't get ProvisioningAllowed system state flag: {:?}", |
| 173 | e |
| 174 | ) |
| 175 | })?; |
| 176 | ProvisioningAllowedFlagValues::try_from(flag).map_err(|e| { |
| 177 | km_err!( |
| 178 | SecureHwCommunicationFailed, |
| 179 | "couldn't parse ProvisioningAllowed system state flag from value {}: {:?}", |
| 180 | flag, |
| 181 | e |
| 182 | ) |
| 183 | }) |
| 184 | } |
| 185 | |
| 186 | /// Indicate whether provisioning is allowed. |
| 187 | fn provisioning_allowed() -> Result<bool, Error> { |
| 188 | Ok(match get_system_state_provisioning_flag()? { |
| 189 | ProvisioningAllowedFlagValues::ProvisioningAllowed => true, |
| 190 | _ => false, |
| 191 | }) |
| 192 | } |
| 193 | |
| 194 | /// Indicate whether provisioning is allowed during boot. |
| 195 | fn provisioning_allowed_at_boot() -> Result<bool, Error> { |
| 196 | Ok(match get_system_state_provisioning_flag()? { |
| 197 | ProvisioningAllowedFlagValues::ProvisioningAllowed => true, |
| 198 | ProvisioningAllowedFlagValues::ProvisioningAllowedAtBoot => true, |
| 199 | _ => false, |
| 200 | }) |
| 201 | } |
| 202 | |
| 203 | /// TIPC service implementation for communication with components outside Trusty (notably the |
| 204 | /// bootloader and provisioning tools), using legacy (C++) message formats. |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 205 | struct KMLegacyService { |
| 206 | km_ta: Rc<RefCell<KeyMintTa>>, |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 207 | boot_info: RefCell<Option<BootInfo>>, |
| 208 | boot_patchlevel: RefCell<Option<u32>>, |
| 209 | } |
| 210 | |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 211 | impl KMLegacyService { |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 212 | /// Create a service implementation. |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 213 | fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self { |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 214 | KMLegacyService { |
| 215 | km_ta, |
| 216 | boot_info: RefCell::new(None), |
| 217 | boot_patchlevel: RefCell::new(None), |
| 218 | } |
| 219 | } |
| 220 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 221 | /// Indicate whether the boot process is complete. |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 222 | fn boot_done(&self) -> bool { |
| 223 | self.km_ta.borrow().is_hal_info_set() |
| 224 | } |
| 225 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 226 | /// Indicate whether provisioning operations are allowed. |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 227 | fn can_provision(&self) -> Result<bool, Error> { |
| 228 | if self.boot_done() { |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 229 | provisioning_allowed() |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 230 | } else { |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 231 | provisioning_allowed_at_boot() |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 232 | } |
| 233 | } |
| 234 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 235 | /// Set the boot information for the TA if possible (i.e. if all parts of the required |
| 236 | /// information are available). |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 237 | fn maybe_set_boot_info(&self) { |
| 238 | match (self.boot_info.borrow().as_ref(), self.boot_patchlevel.borrow().as_ref()) { |
| 239 | (Some(info), Some(boot_patchlevel)) => { |
| 240 | // All the information is available to set the boot info, so combine it and pass to |
| 241 | // the TA. |
| 242 | let boot_info = BootInfo { |
| 243 | verified_boot_key: info.verified_boot_key.clone(), |
| 244 | device_boot_locked: info.device_boot_locked, |
| 245 | verified_boot_state: info.verified_boot_state, |
| 246 | verified_boot_hash: info.verified_boot_hash.clone(), |
| 247 | boot_patchlevel: *boot_patchlevel, |
| 248 | }; |
| 249 | if let Err(e) = self.km_ta.borrow_mut().set_boot_info(boot_info) { |
| 250 | error!("failed to set boot info: {:?}", e); |
| 251 | } |
| 252 | } |
| 253 | _ => info!("not all boot information available yet"), |
| 254 | } |
| 255 | } |
| 256 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 257 | /// Process an incoming request message, returning the corresponding response. |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 258 | fn handle_message(&self, req_msg: TrustyPerformOpReq) -> Result<TrustyPerformOpRsp, Error> { |
| 259 | let cmd_code = req_msg.code(); |
| 260 | // Checking that if we received a bootloader message we are at a stage when we can process |
| 261 | // it |
| 262 | if self.boot_done() && legacy::is_trusty_bootloader_req(&req_msg) { |
| 263 | return Err(km_err!( |
| 264 | Unimplemented, |
| 265 | "bootloader command {:?} not allowed after configure command", |
| 266 | cmd_code |
| 267 | )); |
| 268 | } |
| 269 | |
| 270 | if legacy::is_trusty_provisioning_req(&req_msg) && !(self.can_provision()?) { |
| 271 | return Err(km_err!(Unimplemented, "provisioning command {:?} not allowed", cmd_code)); |
| 272 | } |
| 273 | |
| 274 | // Handling received message |
| 275 | match req_msg { |
David Drysdale | 5450c6d | 2022-12-15 09:25:15 +0000 | [diff] [blame] | 276 | TrustyPerformOpReq::GetVersion(_req) => { |
| 277 | // Match the values returned by C++ KeyMint (from `AndroidKeymaster::GetVersion`). |
| 278 | Ok(TrustyPerformOpRsp::GetVersion(GetVersionResponse { |
| 279 | major_ver: 2, |
| 280 | minor_ver: 0, |
| 281 | subminor_ver: 0, |
| 282 | })) |
| 283 | } |
| 284 | TrustyPerformOpReq::GetVersion2(req) => { |
| 285 | // Match the values returned by C++ KeyMint (from `AndroidKeymaster::GetVersion2`). |
| 286 | let km_version = legacy::KmVersion::KeyMint3; |
| 287 | let message_version = km_version.message_version(); |
| 288 | let max_message_version = core::cmp::min(req.max_message_version, message_version); |
| 289 | Ok(TrustyPerformOpRsp::GetVersion2(GetVersion2Response { |
| 290 | max_message_version, |
| 291 | km_version, |
| 292 | km_date: legacy::KM_DATE, |
| 293 | })) |
| 294 | } |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 295 | TrustyPerformOpReq::SetBootParams(req) => { |
| 296 | // Check if this is the first time we receive a SetBootParams cmd |
| 297 | if self.boot_info.borrow().is_some() { |
| 298 | return Err(km_err!(Unimplemented, "command SetBootParams only allowed once")); |
| 299 | } |
| 300 | |
| 301 | // Saving boot_info so command won't be accepted a second time |
| 302 | let boot_info = BootInfo { |
| 303 | verified_boot_key: req.verified_boot_key, |
| 304 | device_boot_locked: req.device_locked, |
| 305 | verified_boot_state: req.verified_boot_state, |
| 306 | verified_boot_hash: req.verified_boot_hash, |
| 307 | boot_patchlevel: 0, // boot_patchlevel is received on ConfigureBootPatchlevel |
| 308 | }; |
| 309 | self.boot_info.borrow_mut().replace(boot_info); |
| 310 | |
| 311 | // Checking if we can send set boot info with the info we currently have |
| 312 | self.maybe_set_boot_info(); |
| 313 | |
| 314 | Ok(TrustyPerformOpRsp::SetBootParams(SetBootParamsResponse {})) |
| 315 | } |
| 316 | TrustyPerformOpReq::ConfigureBootPatchlevel(req) => { |
| 317 | // Check if this is the first time we receive a ConfigureBootPatchlevel cmd |
| 318 | if self.boot_patchlevel.borrow().is_some() { |
| 319 | return Err(km_err!( |
| 320 | Unimplemented, |
| 321 | "command ConfigureBootPatchlevel only allowed once" |
| 322 | )); |
| 323 | } |
| 324 | |
| 325 | // Saving boot_patchlevel so command won't be accepted a second time |
| 326 | self.boot_patchlevel.borrow_mut().replace(req.boot_patchlevel); |
| 327 | |
| 328 | // Checking if we can send set boot info with the info we currently have |
| 329 | self.maybe_set_boot_info(); |
| 330 | |
| 331 | Ok(TrustyPerformOpRsp::ConfigureBootPatchlevel(ConfigureBootPatchlevelResponse {})) |
| 332 | } |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 333 | TrustyPerformOpReq::SetAttestationKey(req) => { |
| 334 | let algorithm = keymaster_algorithm_to_signing_algorithm(req.algorithm)?; |
| 335 | secure_storage_manager::provision_attestation_key_file(algorithm, &req.key_data)?; |
| 336 | Ok(TrustyPerformOpRsp::SetAttestationKey(SetAttestationKeyResponse {})) |
| 337 | } |
Orlando Arbildo | ce0d536 | 2023-02-16 00:58:07 +0000 | [diff] [blame] | 338 | TrustyPerformOpReq::AppendAttestationCertChain(req) => { |
| 339 | let algorithm = keymaster_algorithm_to_signing_algorithm(req.algorithm)?; |
| 340 | secure_storage_manager::append_attestation_cert_chain(algorithm, &req.cert_data)?; |
| 341 | Ok(TrustyPerformOpRsp::AppendAttestationCertChain( |
| 342 | AppendAttestationCertChainResponse {}, |
| 343 | )) |
| 344 | } |
Orlando Arbildo | 1090e1e | 2023-02-16 20:48:13 +0000 | [diff] [blame] | 345 | TrustyPerformOpReq::ClearAttestationCertChain(req) => { |
| 346 | let algorithm = keymaster_algorithm_to_signing_algorithm(req.algorithm)?; |
| 347 | secure_storage_manager::clear_attestation_cert_chain(algorithm)?; |
| 348 | Ok(TrustyPerformOpRsp::ClearAttestationCertChain( |
| 349 | ClearAttestationCertChainResponse {}, |
| 350 | )) |
| 351 | } |
Orlando Arbildo | ede9128 | 2023-02-18 01:14:02 +0000 | [diff] [blame] | 352 | TrustyPerformOpReq::SetWrappedAttestationKey(req) => { |
| 353 | let algorithm = keymaster_algorithm_to_signing_algorithm(req.algorithm)?; |
| 354 | secure_storage_manager::set_wrapped_attestation_key(algorithm, &req.key_data)?; |
| 355 | Ok(TrustyPerformOpRsp::SetWrappedAttestationKey( |
| 356 | SetWrappedAttestationKeyResponse {}, |
| 357 | )) |
| 358 | } |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 359 | TrustyPerformOpReq::SetAttestationIds(req) => { |
| 360 | secure_storage_manager::provision_attestation_id_file( |
| 361 | &req.brand, |
| 362 | &req.product, |
| 363 | &req.device, |
| 364 | &req.serial, |
| 365 | &req.imei, |
| 366 | &req.meid, |
| 367 | &req.manufacturer, |
| 368 | &req.model, |
Donnie Pollitz | c4a529d | 2023-02-10 14:05:30 +0100 | [diff] [blame] | 369 | None, |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 370 | )?; |
| 371 | Ok(TrustyPerformOpRsp::SetAttestationIds(SetAttestationIdsResponse {})) |
| 372 | } |
Donnie Pollitz | c4a529d | 2023-02-10 14:05:30 +0100 | [diff] [blame] | 373 | TrustyPerformOpReq::SetAttestationIdsKM3(req) => { |
| 374 | secure_storage_manager::provision_attestation_id_file( |
| 375 | &req.base.brand, |
| 376 | &req.base.product, |
| 377 | &req.base.device, |
| 378 | &req.base.serial, |
| 379 | &req.base.imei, |
| 380 | &req.base.meid, |
| 381 | &req.base.manufacturer, |
| 382 | &req.base.model, |
| 383 | Some(&req.second_imei), |
| 384 | )?; |
| 385 | Ok(TrustyPerformOpRsp::SetAttestationIdsKM3(SetAttestationIdsKM3Response {})) |
| 386 | } |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 387 | } |
| 388 | } |
| 389 | } |
| 390 | |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 391 | impl Service for KMLegacyService { |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 392 | type Connection = Context; |
| 393 | type Message = KMMessage; |
| 394 | |
| 395 | fn on_connect( |
| 396 | &self, |
| 397 | _port: &PortCfg, |
| 398 | _handle: &Handle, |
| 399 | peer: &Uuid, |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 400 | ) -> tipc::Result<ConnectResult<Self::Connection>> { |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 401 | info!("Accepted connection from uuid {:?}.", peer); |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 402 | Ok(ConnectResult::Accept(Context { uuid: peer.clone() })) |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 403 | } |
| 404 | |
| 405 | fn on_message( |
| 406 | &self, |
| 407 | _connection: &Self::Connection, |
| 408 | handle: &Handle, |
| 409 | msg: Self::Message, |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 410 | ) -> tipc::Result<MessageResult> { |
Orlando Arbildo | fcce550 | 2023-01-19 01:05:01 +0000 | [diff] [blame] | 411 | debug!("Received legacy message."); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 412 | let req_msg = legacy::deserialize_trusty_req(&msg.0).map_err(|e| { |
| 413 | error!("Received error when parsing legacy message: {:?}", e); |
| 414 | TipcError::InvalidData |
| 415 | })?; |
David Drysdale | 5450c6d | 2022-12-15 09:25:15 +0000 | [diff] [blame] | 416 | let op = req_msg.code(); |
| 417 | |
| 418 | let resp = match self.handle_message(req_msg) { |
| 419 | Ok(resp_msg) => legacy::serialize_trusty_rsp(resp_msg).map_err(|e| { |
| 420 | error!("failed to serialize legacy response message: {:?}", e); |
| 421 | TipcError::InvalidData |
| 422 | })?, |
| 423 | Err(Error::Hal(rc, msg)) => { |
| 424 | error!("operation {:?} failed: {:?} {}", op, rc, msg); |
| 425 | legacy::serialize_trusty_error_rsp(op, rc).map_err(|e| { |
| 426 | error!("failed to serialize legacy error {:?} response message: {:?}", rc, e); |
| 427 | TipcError::InvalidData |
| 428 | })? |
| 429 | } |
| 430 | Err(e) => { |
| 431 | error!("error handling legacy message: {:?}", e); |
| 432 | return Err(TipcError::UnknownError); |
| 433 | } |
| 434 | }; |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 435 | handle.send(&KMMessage(resp))?; |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 436 | Ok(MessageResult::MaintainConnection) |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 437 | } |
| 438 | } |
| 439 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 440 | /// TIPC service implementation for secure communication with other components in Trusty |
| 441 | /// (e.g. Gatekeeper, ConfirmationUI), using legacy (C++) message formats. |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 442 | struct KMSecureService { |
| 443 | km_ta: Rc<RefCell<KeyMintTa>>, |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 444 | } |
| 445 | |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 446 | impl KMSecureService { |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 447 | /// Create a service implementation. |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 448 | fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self { |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 449 | KMSecureService { km_ta } |
| 450 | } |
David Drysdale | 5450c6d | 2022-12-15 09:25:15 +0000 | [diff] [blame] | 451 | fn handle_message( |
| 452 | &self, |
| 453 | req_msg: TrustyPerformSecureOpReq, |
| 454 | ) -> Result<TrustyPerformSecureOpRsp, Error> { |
| 455 | match req_msg { |
| 456 | TrustyPerformSecureOpReq::GetAuthTokenKey(_) => { |
| 457 | match self.km_ta.borrow().get_hmac_key() { |
| 458 | Some(mut payload) => { |
| 459 | Ok(TrustyPerformSecureOpRsp::GetAuthTokenKey(GetAuthTokenKeyResponse { |
| 460 | key_material: mem::take(&mut payload.0), |
| 461 | })) |
| 462 | } |
| 463 | None => Err(km_err!(UnknownError, "hmac_key is not available")), |
| 464 | } |
| 465 | } |
David Drysdale | 532beee | 2022-12-21 17:47:16 +0000 | [diff] [blame] | 466 | TrustyPerformSecureOpReq::GetDeviceInfo(_) => { |
| 467 | Ok(TrustyPerformSecureOpRsp::GetDeviceInfo(GetDeviceInfoResponse { |
| 468 | device_ids: self.km_ta.borrow().rpc_device_info()?, |
| 469 | })) |
| 470 | } |
| 471 | TrustyPerformSecureOpReq::SetAttestationIds(req) => { |
| 472 | secure_storage_manager::provision_attestation_id_file( |
| 473 | &req.brand, |
| 474 | &req.product, |
| 475 | &req.device, |
| 476 | &req.serial, |
| 477 | &req.imei, |
| 478 | &req.meid, |
| 479 | &req.manufacturer, |
| 480 | &req.model, |
Donnie Pollitz | c4a529d | 2023-02-10 14:05:30 +0100 | [diff] [blame] | 481 | None, |
David Drysdale | 532beee | 2022-12-21 17:47:16 +0000 | [diff] [blame] | 482 | )?; |
| 483 | Ok(TrustyPerformSecureOpRsp::SetAttestationIds(SetAttestationIdsResponse {})) |
| 484 | } |
David Drysdale | 5450c6d | 2022-12-15 09:25:15 +0000 | [diff] [blame] | 485 | } |
| 486 | } |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 487 | } |
| 488 | |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 489 | impl Service for KMSecureService { |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 490 | type Connection = Context; |
| 491 | type Message = KMMessage; |
| 492 | |
| 493 | fn on_connect( |
| 494 | &self, |
| 495 | _port: &PortCfg, |
| 496 | _handle: &Handle, |
| 497 | peer: &Uuid, |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 498 | ) -> tipc::Result<ConnectResult<Self::Connection>> { |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 499 | if !keymint_check_target_access_policy(peer) { |
| 500 | error!("access policy rejected the uuid: {:?}", peer); |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 501 | return Ok(ConnectResult::CloseConnection); |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 502 | } |
| 503 | info!("Accepted connection from uuid {:?}.", peer); |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 504 | Ok(ConnectResult::Accept(Context { uuid: peer.clone() })) |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 505 | } |
| 506 | |
| 507 | fn on_message( |
| 508 | &self, |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 509 | connection: &Self::Connection, |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 510 | handle: &Handle, |
| 511 | msg: Self::Message, |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 512 | ) -> tipc::Result<MessageResult> { |
Orlando Arbildo | fcce550 | 2023-01-19 01:05:01 +0000 | [diff] [blame] | 513 | debug!("Received secure message."); |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 514 | |
| 515 | let req_msg = legacy::deserialize_trusty_secure_req(&msg.0).map_err(|e| { |
| 516 | error!("Received error when parsing message: {:?}", e); |
| 517 | TipcError::InvalidData |
| 518 | })?; |
David Drysdale | 5450c6d | 2022-12-15 09:25:15 +0000 | [diff] [blame] | 519 | let op = req_msg.code(); |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 520 | if matches!(&req_msg, TrustyPerformSecureOpReq::SetAttestationIds(_)) |
| 521 | && !keymint_check_secure_target_access_policy_provisioning(&connection.uuid) |
| 522 | { |
| 523 | error!("access policy rejected the uuid: {:?}", &connection.uuid); |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 524 | return Ok(MessageResult::CloseConnection); |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 525 | } |
David Drysdale | 5450c6d | 2022-12-15 09:25:15 +0000 | [diff] [blame] | 526 | |
| 527 | let resp = match self.handle_message(req_msg) { |
| 528 | Ok(resp_msg) => legacy::serialize_trusty_secure_rsp(resp_msg).map_err(|e| { |
| 529 | error!("failed to serialize legacy response secure message: {:?}", e); |
| 530 | TipcError::InvalidData |
| 531 | })?, |
| 532 | Err(Error::Hal(rc, msg)) => { |
| 533 | error!("operation {:?} failed: {:?} {}", op, rc, msg); |
| 534 | legacy::serialize_trusty_secure_error_rsp(op, rc).map_err(|e| { |
| 535 | error!( |
| 536 | "failed to serialize legacy error {:?} response secure message: {:?}", |
| 537 | rc, e |
| 538 | ); |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 539 | TipcError::InvalidData |
David Drysdale | 5450c6d | 2022-12-15 09:25:15 +0000 | [diff] [blame] | 540 | })? |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 541 | } |
David Drysdale | 5450c6d | 2022-12-15 09:25:15 +0000 | [diff] [blame] | 542 | Err(e) => { |
| 543 | error!("error handling secure legacy message: {:?}", e); |
| 544 | return Err(TipcError::UnknownError); |
| 545 | } |
| 546 | }; |
| 547 | handle.send(&KMMessage(resp))?; |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 548 | Ok(MessageResult::MaintainConnection) |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 549 | } |
| 550 | } |
| 551 | |
| 552 | service_dispatcher! { |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 553 | enum KMServiceDispatcher { |
| 554 | KMService, |
| 555 | KMSecureService, |
| 556 | KMLegacyService, |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 557 | } |
| 558 | } |
| 559 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 560 | /// Main loop handler for the KeyMint TA. |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 561 | pub fn handle_port_connections( |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 562 | hw_info: HardwareInfo, |
| 563 | rpc_info: RpcInfo, |
David Drysdale | 7df0ce2 | 2023-05-11 17:21:35 +0100 | [diff] [blame] | 564 | imp: crypto::Implementation, |
| 565 | dev: kmr_ta::device::Implementation, |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 566 | ) -> Result<(), Error> { |
| 567 | let km_ta = Rc::new(RefCell::new(KeyMintTa::new(hw_info, rpc_info, imp, dev))); |
| 568 | let ns_service = KMService::new(Rc::clone(&km_ta)); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 569 | let legacy_service = KMLegacyService::new(Rc::clone(&km_ta)); |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 570 | let sec_service = KMSecureService::new(km_ta); |
| 571 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 572 | let mut dispatcher = KMServiceDispatcher::<3>::new() |
| 573 | .map_err(|e| km_err!(UnknownError, "could not create multi-service dispatcher: {:?}", e))?; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 574 | let cfg = PortCfg::new(KM_NS_TIPC_SRV_PORT) |
| 575 | .map_err(|e| { |
| 576 | km_err!( |
| 577 | UnknownError, |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 578 | "could not create port config for {}: {:?}", |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 579 | KM_NS_TIPC_SRV_PORT, |
| 580 | e |
| 581 | ) |
| 582 | })? |
| 583 | .allow_ta_connect() |
| 584 | .allow_ns_connect(); |
| 585 | dispatcher.add_service(Rc::new(ns_service), cfg).map_err(|e| { |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 586 | km_err!(UnknownError, "could not add non-secure service to dispatcher: {:?}", e) |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 587 | })?; |
| 588 | let cfg = PortCfg::new(KM_SEC_TIPC_SRV_PORT) |
| 589 | .map_err(|e| { |
| 590 | km_err!( |
| 591 | UnknownError, |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 592 | "could not create port config for {}: {:?}", |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 593 | KM_SEC_TIPC_SRV_PORT, |
| 594 | e |
| 595 | ) |
| 596 | })? |
| 597 | .allow_ta_connect(); |
| 598 | dispatcher.add_service(Rc::new(sec_service), cfg).map_err(|e| { |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 599 | km_err!(UnknownError, "could not add secure service to dispatcher: {:?}", e) |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 600 | })?; |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 601 | let cfg = PortCfg::new(KM_NS_LEGACY_TIPC_SRV_PORT) |
| 602 | .map_err(|e| { |
| 603 | km_err!( |
| 604 | UnknownError, |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 605 | "could not create port config for {}: {:?}", |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 606 | KM_NS_LEGACY_TIPC_SRV_PORT, |
| 607 | e |
| 608 | ) |
| 609 | })? |
David Drysdale | 5450c6d | 2022-12-15 09:25:15 +0000 | [diff] [blame] | 610 | .allow_ta_connect() |
| 611 | .allow_ns_connect(); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 612 | dispatcher.add_service(Rc::new(legacy_service), cfg).map_err(|e| { |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 613 | km_err!(UnknownError, "could not add secure service to dispatcher: {:?}", e) |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 614 | })?; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 615 | let buffer = [0u8; 4096]; |
David Drysdale | d1d71c6 | 2023-03-27 18:48:51 +0100 | [diff] [blame] | 616 | let manager = |
| 617 | Manager::<_, _, PORT_COUNT, MAX_CONNECTION_COUNT>::new_with_dispatcher(dispatcher, buffer) |
| 618 | .map_err(|e| km_err!(UnknownError, "could not create service manager: {:?}", e))?; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 619 | manager |
| 620 | .run_event_loop() |
| 621 | .map_err(|e| km_err!(UnknownError, "service manager received error: {:?}", e))?; |
| 622 | Err(km_err!(SecureHwCommunicationFailed, "KeyMint TA handler terminated unexpectedly.")) |
| 623 | } |
| 624 | |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 625 | // TODO: remove when tests reinstated |
| 626 | #[allow(dead_code)] |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 627 | #[cfg(test)] |
| 628 | mod tests { |
| 629 | use super::*; |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 630 | use kmr_wire::{ |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 631 | keymint::{ErrorCode, VerifiedBootState}, |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 632 | legacy::{self, InnerSerialize}, |
| 633 | }; |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 634 | use test::{expect, skip}; |
Nicole LeGare | 6784967 | 2023-01-26 23:43:43 +0000 | [diff] [blame] | 635 | use trusty_std::ffi::{CString, FallibleCString}; |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 636 | |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 637 | const CONFIGURE_BOOT_PATCHLEVEL_CMD: u32 = |
| 638 | legacy::TrustyKeymasterOperation::ConfigureBootPatchlevel as u32; |
| 639 | const SET_BOOT_PARAMS_CMD: u32 = legacy::TrustyKeymasterOperation::SetBootParams as u32; |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 640 | const SET_ATTESTATION_IDS_CMD: u32 = legacy::TrustyKeymasterOperation::SetAttestationIds as u32; |
| 641 | const SET_ATTESTATION_KEY_CMD: u32 = legacy::TrustyKeymasterOperation::SetAttestationKey as u32; |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 642 | |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 643 | #[test] |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 644 | fn connection_test() { |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 645 | if !cfg!(kmr_enabled) { |
| 646 | skip!("KeyMint Rust TA not configured"); |
| 647 | } |
| 648 | |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 649 | // Only doing a connection test because the auth token key is not available for unittests. |
| 650 | let port1 = CString::try_new(KM_NS_TIPC_SRV_PORT).unwrap(); |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 651 | let _session1 = Handle::connect(port1.as_c_str()).unwrap(); |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 652 | let port2 = CString::try_new(KM_SEC_TIPC_SRV_PORT).unwrap(); |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 653 | let _session2 = Handle::connect(port2.as_c_str()).unwrap(); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 654 | let port3 = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap(); |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 655 | let _session3 = Handle::connect(port3.as_c_str()).unwrap(); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 656 | } |
| 657 | |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 658 | #[test] |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 659 | fn test_access_policy() { |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 660 | if !cfg!(kmr_enabled) { |
| 661 | skip!("KeyMint Rust TA not configured"); |
| 662 | } |
| 663 | |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 664 | // Test whether the access policy is in action. |
| 665 | // Keymint unit test app should be able to connect to the KM secure service. |
| 666 | let port = CString::try_new(KM_SEC_TIPC_SRV_PORT).unwrap(); |
| 667 | Handle::connect(port.as_c_str()) |
| 668 | .expect("Keymint unit test app should be able to connect to the KM secure service"); |
| 669 | |
| 670 | // Keymint unit test app should not be able to call the attestation id provisioning API |
| 671 | // in the KM secure service. |
| 672 | let err = set_attestation_ids_secure().expect_err( |
| 673 | "An error is expected. Keymint unit test app shouldn't be able to provision", |
| 674 | ); |
| 675 | assert_eq!(err, TipcError::SystemError(trusty_sys::Error::NoMsg)); |
| 676 | } |
| 677 | |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 678 | fn check_response_status(rsp: &KMMessage) -> Result<(), ErrorCode> { |
| 679 | let error_code = legacy::deserialize_trusty_rsp_error_code(&rsp.0) |
| 680 | .expect("Couldn't retrieve error code"); |
| 681 | if error_code == ErrorCode::Ok { |
| 682 | Ok(()) |
| 683 | } else { |
| 684 | Err(error_code) |
| 685 | } |
| 686 | } |
| 687 | |
| 688 | fn get_message_request(cmd: u32) -> Vec<u8> { |
| 689 | (cmd << legacy::TRUSTY_CMD_SHIFT).to_ne_bytes().to_vec() |
| 690 | } |
| 691 | |
| 692 | fn get_response_status(session: &Handle) -> Result<(), ErrorCode> { |
| 693 | let mut buf = [0; KEYMINT_MAX_BUFFER_LENGTH as usize]; |
| 694 | let response: KMMessage = |
| 695 | session.recv(&mut buf).map_err(|_| ErrorCode::SecureHwCommunicationFailed)?; |
| 696 | check_response_status(&response) |
| 697 | } |
| 698 | |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 699 | fn get_configure_boot_patchlevel_message( |
| 700 | boot_patchlevel: u32, |
| 701 | ) -> Result<Vec<u8>, legacy::Error> { |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 702 | let mut req = get_message_request(CONFIGURE_BOOT_PATCHLEVEL_CMD); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 703 | boot_patchlevel.serialize_into(&mut req)?; |
| 704 | Ok(req) |
| 705 | } |
| 706 | |
| 707 | fn get_set_boot_params_message( |
| 708 | os_version: u32, |
| 709 | os_patchlevel: u32, |
| 710 | device_locked: bool, |
| 711 | verified_boot_state: VerifiedBootState, |
| 712 | verified_boot_key: Vec<u8>, |
| 713 | verified_boot_hash: Vec<u8>, |
| 714 | ) -> Result<Vec<u8>, legacy::Error> { |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 715 | let mut req = get_message_request(SET_BOOT_PARAMS_CMD); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 716 | os_version.serialize_into(&mut req)?; |
| 717 | os_patchlevel.serialize_into(&mut req)?; |
| 718 | device_locked.serialize_into(&mut req)?; |
| 719 | verified_boot_state.serialize_into(&mut req)?; |
| 720 | verified_boot_key.serialize_into(&mut req)?; |
| 721 | verified_boot_hash.serialize_into(&mut req)?; |
| 722 | Ok(req) |
| 723 | } |
| 724 | |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 725 | fn get_set_attestation_ids_message( |
| 726 | brand: &Vec<u8>, |
| 727 | product: &Vec<u8>, |
| 728 | device: &Vec<u8>, |
| 729 | serial: &Vec<u8>, |
| 730 | imei: &Vec<u8>, |
| 731 | meid: &Vec<u8>, |
| 732 | manufacturer: &Vec<u8>, |
| 733 | model: &Vec<u8>, |
| 734 | ) -> Result<Vec<u8>, legacy::Error> { |
| 735 | let mut req = get_message_request(SET_ATTESTATION_IDS_CMD); |
| 736 | brand.serialize_into(&mut req)?; |
| 737 | product.serialize_into(&mut req)?; |
| 738 | device.serialize_into(&mut req)?; |
| 739 | serial.serialize_into(&mut req)?; |
| 740 | imei.serialize_into(&mut req)?; |
| 741 | meid.serialize_into(&mut req)?; |
| 742 | manufacturer.serialize_into(&mut req)?; |
| 743 | model.serialize_into(&mut req)?; |
| 744 | Ok(req) |
| 745 | } |
| 746 | |
| 747 | fn get_set_attestation_key_message( |
| 748 | algorithm: Algorithm, |
| 749 | content: &[u8], |
| 750 | ) -> Result<Vec<u8>, legacy::Error> { |
| 751 | let mut req = get_message_request(SET_ATTESTATION_KEY_CMD); |
| 752 | (algorithm as u32).serialize_into(&mut req)?; |
| 753 | (content.len() as u32).serialize_into(&mut req)?; |
| 754 | req.extend_from_slice(content); |
| 755 | Ok(req) |
| 756 | } |
| 757 | |
David Drysdale | 415c0d6 | 2024-03-15 06:40:43 +0000 | [diff] [blame^] | 758 | // This test should only be run manually as it writes to the secure storage |
| 759 | // of the device under test. |
| 760 | // #[test] |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 761 | fn set_attestation_keys_certs() { |
| 762 | let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap(); |
| 763 | let session = Handle::connect(port.as_c_str()).unwrap(); |
| 764 | |
| 765 | let req = get_set_attestation_key_message(Algorithm::Ec, &[0; 1024]) |
| 766 | .expect("couldn't construct SetAttestatonKey request"); |
| 767 | let set_attestation_key_req = KMMessage(req); |
| 768 | // Sending `SetAttestationKey` request and processing response |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 769 | session.send(&set_attestation_key_req).unwrap(); |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 770 | let buf = &mut [0; KEYMINT_MAX_BUFFER_LENGTH as usize]; |
| 771 | let response: KMMessage = session.recv(buf).expect("Didn't get response"); |
| 772 | let km_error_code = check_response_status(&response); |
| 773 | expect!(km_error_code.is_ok(), "Should be able to call SetAttestatonKeys"); |
| 774 | } |
| 775 | |
Weston Carvalho | b021dc9 | 2023-02-27 16:02:21 -0600 | [diff] [blame] | 776 | fn set_attestation_ids_secure() -> tipc::Result<()> { |
Hasini Gunasinghe | e3bc700 | 2023-01-25 00:48:04 +0000 | [diff] [blame] | 777 | let port = CString::try_new(KM_SEC_TIPC_SRV_PORT).unwrap(); |
| 778 | let session = Handle::connect(port.as_c_str()).unwrap(); |
| 779 | |
| 780 | // Creating a SetAttestationIds message |
| 781 | let brand = b"no brand".to_vec(); |
| 782 | let device = b"a new device".to_vec(); |
| 783 | let product = b"p1".to_vec(); |
| 784 | let serial = vec![b'5'; 64]; |
| 785 | let imei = b"7654321".to_vec(); |
| 786 | let meid = b"1234567".to_vec(); |
| 787 | let manufacturer = b"a manufacturer".to_vec(); |
| 788 | let model = b"the new one".to_vec(); |
| 789 | let req = get_set_attestation_ids_message( |
| 790 | &brand, |
| 791 | &device, |
| 792 | &product, |
| 793 | &serial, |
| 794 | &imei, |
| 795 | &meid, |
| 796 | &manufacturer, |
| 797 | &model, |
| 798 | ) |
| 799 | .expect("couldn't construct SetAttestatonIds request"); |
| 800 | let set_attestation_ids_req = KMMessage(req); |
| 801 | |
| 802 | // Sending SetAttestationIds |
| 803 | session.send(&set_attestation_ids_req).unwrap(); |
| 804 | let buf = &mut [0; KEYMINT_MAX_BUFFER_LENGTH as usize]; |
| 805 | session.recv(buf) |
| 806 | } |
| 807 | |
David Drysdale | 415c0d6 | 2024-03-15 06:40:43 +0000 | [diff] [blame^] | 808 | // This test should only be run manually as it writes to the secure storage |
| 809 | // of the device under test. |
| 810 | // #[test] |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 811 | fn set_attestation_ids() { |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 812 | if !cfg!(kmr_enabled) { |
| 813 | skip!("KeyMint Rust TA not configured"); |
| 814 | } |
| 815 | |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 816 | let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap(); |
| 817 | let session = Handle::connect(port.as_c_str()).unwrap(); |
| 818 | |
| 819 | // Creating a SetAttestationIds message |
| 820 | let brand = b"no brand".to_vec(); |
| 821 | let device = b"a new device".to_vec(); |
| 822 | let product = b"p1".to_vec(); |
| 823 | let serial = vec![b'5'; 64]; |
| 824 | let imei = b"7654321".to_vec(); |
| 825 | let meid = b"1234567".to_vec(); |
| 826 | let manufacturer = b"a manufacturer".to_vec(); |
| 827 | let model = b"the new one".to_vec(); |
| 828 | let req = get_set_attestation_ids_message( |
| 829 | &brand, |
| 830 | &device, |
| 831 | &product, |
| 832 | &serial, |
| 833 | &imei, |
| 834 | &meid, |
| 835 | &manufacturer, |
| 836 | &model, |
| 837 | ) |
| 838 | .expect("couldn't construct SetAttestatonIds request"); |
| 839 | let set_attestation_ids_req = KMMessage(req); |
| 840 | |
| 841 | // Sending SetAttestationIds |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 842 | session.send(&set_attestation_ids_req).unwrap(); |
Orlando Arbildo | f0d2d82 | 2022-12-13 00:44:14 +0000 | [diff] [blame] | 843 | let buf = &mut [0; KEYMINT_MAX_BUFFER_LENGTH as usize]; |
| 844 | let response: KMMessage = session.recv(buf).expect("Didn't get response"); |
| 845 | let km_error_code = check_response_status(&response); |
| 846 | expect!(km_error_code.is_ok(), "Should be able to call SetAttestationIds"); |
| 847 | } |
| 848 | |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 849 | // The following tests are all skipped because they try to SetBootParams more than once |
| 850 | // which isn't allowed. However, the code is preserved to allow for future manual testing. |
| 851 | |
| 852 | #[test] |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 853 | fn send_setbootparams_configure_setbootparams_configure() { |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 854 | if true { |
| 855 | skip!("SetBootParams cannot be performed more than once"); |
| 856 | } |
| 857 | |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 858 | let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap(); |
| 859 | let session = Handle::connect(port.as_c_str()).unwrap(); |
| 860 | |
| 861 | // Creating a SetBootParams message |
| 862 | let os_version = 1; |
| 863 | let os_patchlevel = 0x202010; |
| 864 | let device_locked = true; |
| 865 | let verified_boot_state = VerifiedBootState::Unverified; |
| 866 | let verified_boot_key = [0u8; 32]; |
| 867 | let verified_boot_hash = [0u8; 32]; |
| 868 | let req = get_set_boot_params_message( |
| 869 | os_version, |
| 870 | os_patchlevel, |
| 871 | device_locked, |
| 872 | verified_boot_state, |
| 873 | verified_boot_key.to_vec(), |
| 874 | verified_boot_hash.to_vec(), |
| 875 | ) |
| 876 | .expect("couldn't construct SetBootParams request"); |
| 877 | let set_boot_param_req = KMMessage(req); |
| 878 | |
| 879 | // Sending SetBootParamsRequest |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 880 | session.send(&set_boot_param_req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 881 | let km_error_code = get_response_status(&session); |
| 882 | expect!(km_error_code.is_ok(), "Should be able to call SetBootParams"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 883 | |
| 884 | // Creating a ConfigureBootPatchlevelRequest message |
| 885 | let boot_patchlevel = 0x20201010; |
| 886 | let req = |
| 887 | get_configure_boot_patchlevel_message(boot_patchlevel).expect("Couldn't construct msg"); |
| 888 | let configure_bootpatchlevel_req = KMMessage(req); |
| 889 | |
| 890 | // Sending ConfigureBootPatchlevelRequest |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 891 | session.send(&configure_bootpatchlevel_req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 892 | let km_error_code = get_response_status(&session); |
| 893 | expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 894 | |
| 895 | // Checking that sending the message a second time fails |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 896 | session.send(&set_boot_param_req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 897 | let km_error_code = get_response_status(&session); |
| 898 | expect!(km_error_code.is_err(), "Shouldn't be able to call SetBootParams a second time"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 899 | |
| 900 | // Checking that sending the message a second time fails |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 901 | session.send(&configure_bootpatchlevel_req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 902 | let km_error_code = get_response_status(&session); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 903 | expect!( |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 904 | km_error_code.is_err(), |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 905 | "Shouldn't be able to call ConfigureBootPatchlevel a second time" |
| 906 | ); |
| 907 | } |
| 908 | |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 909 | #[test] |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 910 | fn send_configure_configure_setbootparams_setbootparams() { |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 911 | if true { |
| 912 | skip!("SetBootParams cannot be performed more than once"); |
| 913 | } |
| 914 | |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 915 | let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap(); |
| 916 | let session = Handle::connect(port.as_c_str()).unwrap(); |
| 917 | |
| 918 | // Creating a ConfigureBootPatchlevelRequest message |
| 919 | let boot_patchlevel = 0x20201010; |
| 920 | let req = |
| 921 | get_configure_boot_patchlevel_message(boot_patchlevel).expect("Couldn't construct msg"); |
| 922 | let req = KMMessage(req); |
| 923 | |
| 924 | // Sending ConfigureBootPatchlevelRequest |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 925 | session.send(&req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 926 | let km_error_code = get_response_status(&session); |
| 927 | expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 928 | |
| 929 | // Checking that sending the message a second time fails |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 930 | session.send(&req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 931 | let km_error_code = get_response_status(&session); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 932 | expect!( |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 933 | km_error_code.is_err(), |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 934 | "Shouldn't be able to call ConfigureBootPatchlevel a second time" |
| 935 | ); |
| 936 | |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 937 | // Creating a SetBootParams message |
| 938 | let os_version = 1; |
| 939 | let os_patchlevel = 0x202010; |
| 940 | let device_locked = true; |
| 941 | let verified_boot_state = VerifiedBootState::Unverified; |
| 942 | let verified_boot_key = [0u8; 32]; |
| 943 | let verified_boot_hash = [0u8; 32]; |
| 944 | let req = get_set_boot_params_message( |
| 945 | os_version, |
| 946 | os_patchlevel, |
| 947 | device_locked, |
| 948 | verified_boot_state, |
| 949 | verified_boot_key.to_vec(), |
| 950 | verified_boot_hash.to_vec(), |
| 951 | ) |
| 952 | .expect("couldn't construct SetBootParams request"); |
| 953 | let req = KMMessage(req); |
| 954 | |
| 955 | // Sending SetBootParamsRequest |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 956 | session.send(&req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 957 | let km_error_code = get_response_status(&session); |
| 958 | expect!(km_error_code.is_ok(), "Should be able to call SetBootParams"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 959 | |
| 960 | // Checking that sending the message a second time fails |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 961 | session.send(&req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 962 | let km_error_code = get_response_status(&session); |
| 963 | expect!(km_error_code.is_err(), "Shouldn't be able to call SetBootParams a second time"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 964 | } |
| 965 | |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 966 | #[test] |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 967 | fn send_setbootparams_setbootparams_configure_configure() { |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 968 | if true { |
| 969 | skip!("SetBootParams cannot be performed more than once"); |
| 970 | } |
| 971 | |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 972 | let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap(); |
| 973 | let session = Handle::connect(port.as_c_str()).unwrap(); |
| 974 | |
| 975 | // Creating a SetBootParams message |
| 976 | let os_version = 1; |
| 977 | let os_patchlevel = 0x202010; |
| 978 | let device_locked = true; |
| 979 | let verified_boot_state = VerifiedBootState::Unverified; |
| 980 | let verified_boot_key = [0u8; 32]; |
| 981 | let verified_boot_hash = [0u8; 32]; |
| 982 | let req = get_set_boot_params_message( |
| 983 | os_version, |
| 984 | os_patchlevel, |
| 985 | device_locked, |
| 986 | verified_boot_state, |
| 987 | verified_boot_key.to_vec(), |
| 988 | verified_boot_hash.to_vec(), |
| 989 | ) |
| 990 | .expect("couldn't construct SetBootParams request"); |
| 991 | let req = KMMessage(req); |
| 992 | |
| 993 | // Sending SetBootParamsRequest |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 994 | session.send(&req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 995 | let km_error_code = get_response_status(&session); |
| 996 | expect!(km_error_code.is_ok(), "Should be able to call SetBootParams"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 997 | |
| 998 | // Checking that sending the message a second time fails |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 999 | session.send(&req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 1000 | let km_error_code = get_response_status(&session); |
| 1001 | expect!(km_error_code.is_err(), "Shouldn't be able to call SetBootParams a second time"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1002 | |
| 1003 | // Creating a ConfigureBootPatchlevelRequest message |
| 1004 | let boot_patchlevel = 0x20201010; |
| 1005 | let req = |
| 1006 | get_configure_boot_patchlevel_message(boot_patchlevel).expect("Couldn't construct msg"); |
| 1007 | let req = KMMessage(req); |
| 1008 | |
| 1009 | // Sending ConfigureBootPatchlevelRequest |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 1010 | session.send(&req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 1011 | let km_error_code = get_response_status(&session); |
| 1012 | expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1013 | |
| 1014 | // Checking that sending the message a second time fails |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 1015 | session.send(&req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 1016 | let km_error_code = get_response_status(&session); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1017 | expect!( |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 1018 | km_error_code.is_err(), |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1019 | "Shouldn't be able to call ConfigureBootPatchlevel a second time" |
| 1020 | ); |
| 1021 | } |
| 1022 | |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 1023 | #[test] |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1024 | fn send_configure_setbootparams_setbootparams_configure() { |
David Drysdale | f2e821c | 2024-02-12 15:49:29 +0000 | [diff] [blame] | 1025 | if true { |
| 1026 | skip!("SetBootParams cannot be performed more than once"); |
| 1027 | } |
| 1028 | |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1029 | let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap(); |
| 1030 | let session = Handle::connect(port.as_c_str()).unwrap(); |
| 1031 | |
| 1032 | // Creating a ConfigureBootPatchlevelRequest message |
| 1033 | let boot_patchlevel = 0x20201010; |
| 1034 | let req = |
| 1035 | get_configure_boot_patchlevel_message(boot_patchlevel).expect("Couldn't construct msg"); |
| 1036 | let configure_bootpatchlevel_req = KMMessage(req); |
| 1037 | |
| 1038 | // Sending ConfigureBootPatchlevelRequest |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 1039 | session.send(&configure_bootpatchlevel_req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 1040 | let km_error_code = get_response_status(&session); |
| 1041 | expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1042 | |
| 1043 | // Creating a SetBootParams message |
| 1044 | let os_version = 1; |
| 1045 | let os_patchlevel = 0x202010; |
| 1046 | let device_locked = true; |
| 1047 | let verified_boot_state = VerifiedBootState::Unverified; |
| 1048 | let verified_boot_key = [0u8; 32]; |
| 1049 | let verified_boot_hash = [0u8; 32]; |
| 1050 | let req = get_set_boot_params_message( |
| 1051 | os_version, |
| 1052 | os_patchlevel, |
| 1053 | device_locked, |
| 1054 | verified_boot_state, |
| 1055 | verified_boot_key.to_vec(), |
| 1056 | verified_boot_hash.to_vec(), |
| 1057 | ) |
| 1058 | .expect("couldn't construct SetBootParams request"); |
| 1059 | let set_boot_param_req = KMMessage(req); |
| 1060 | |
| 1061 | // Sending SetBootParamsRequest |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 1062 | session.send(&set_boot_param_req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 1063 | let km_error_code = get_response_status(&session); |
| 1064 | expect!(km_error_code.is_ok(), "Should be able to call SetBootParams"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1065 | |
| 1066 | // Checking that sending the message a second time fails |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 1067 | session.send(&set_boot_param_req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 1068 | let km_error_code = get_response_status(&session); |
| 1069 | expect!(km_error_code.is_err(), "Shouldn't be able to call SetBootParams a second time"); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1070 | |
| 1071 | // Checking that sending the message a second time fails |
David Drysdale | 6470210 | 2022-12-14 12:23:16 +0000 | [diff] [blame] | 1072 | session.send(&configure_bootpatchlevel_req).unwrap(); |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 1073 | let km_error_code = get_response_status(&session); |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1074 | expect!( |
Orlando Arbildo | 892d38d | 2022-12-19 19:40:14 +0000 | [diff] [blame] | 1075 | km_error_code.is_err(), |
Orlando Arbildo | d3e5064 | 2022-12-09 00:56:30 +0000 | [diff] [blame] | 1076 | "Shouldn't be able to call ConfigureBootPatchlevel a second time" |
| 1077 | ); |
Orlando Arbildo | e200071 | 2022-11-24 00:21:21 +0000 | [diff] [blame] | 1078 | } |
| 1079 | } |