blob: 234bd568e9e869b214c43bce683dfbfe662b1fcb [file] [log] [blame]
Orlando Arbildoe2000712022-11-24 00:21:21 +00001/*
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 Arbildof0d2d822022-12-13 00:44:14 +000017use crate::secure_storage_manager;
Orlando Arbildoe2000712022-11-24 00:21:21 +000018use alloc::{rc::Rc, vec::Vec};
19use core::{cell::RefCell, mem};
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +000020use keymint_access_policy::{
21 keymint_check_secure_target_access_policy_provisioning, keymint_check_target_access_policy,
22};
Orlando Arbildoe2000712022-11-24 00:21:21 +000023use kmr_common::{
David Drysdale64702102022-12-14 12:23:16 +000024 crypto, km_err,
Orlando Arbildoe2000712022-11-24 00:21:21 +000025 wire::legacy::{
Orlando Arbildo1090e1e2023-02-16 20:48:13 +000026 self, AppendAttestationCertChainResponse, ClearAttestationCertChainResponse,
27 ConfigureBootPatchlevelResponse, GetAuthTokenKeyResponse, GetDeviceInfoResponse,
28 GetVersion2Response, GetVersionResponse, SetAttestationIdsKM3Response,
29 SetAttestationIdsResponse, SetAttestationKeyResponse, SetBootParamsResponse,
Orlando Arbildoede91282023-02-18 01:14:02 +000030 SetWrappedAttestationKeyResponse, TrustyMessageId, TrustyPerformOpReq, TrustyPerformOpRsp,
31 TrustyPerformSecureOpReq, TrustyPerformSecureOpRsp,
Orlando Arbildoe2000712022-11-24 00:21:21 +000032 },
33 Error,
34};
Orlando Arbildof0d2d822022-12-13 00:44:14 +000035use kmr_ta::{self, device::SigningAlgorithm, split_rsp, HardwareInfo, KeyMintTa, RpcInfo};
36use kmr_wire::keymint::{Algorithm, BootInfo};
Orlando Arbildoe2000712022-11-24 00:21:21 +000037use log::{debug, error, info};
Orlando Arbildod3e50642022-12-09 00:56:30 +000038use system_state::{ProvisioningAllowedFlagValues, SystemState, SystemStateFlag};
Orlando Arbildoe2000712022-11-24 00:21:21 +000039use tipc::{
Weston Carvalhob021dc92023-02-27 16:02:21 -060040 service_dispatcher, ConnectResult, Deserialize, Handle, Manager, MessageResult, PortCfg,
41 Serialize, Serializer, Service, TipcError, Uuid,
Orlando Arbildoe2000712022-11-24 00:21:21 +000042};
Orlando Arbildoe2000712022-11-24 00:21:21 +000043use trusty_std::alloc::TryAllocFrom;
44
Orlando Arbildo26583f02023-01-03 19:16:07 +000045/// Port that handles new style keymint messages from non-secure world
Orlando Arbildoe2000712022-11-24 00:21:21 +000046const KM_NS_TIPC_SRV_PORT: &str = "com.android.trusty.keymint";
Orlando Arbildo26583f02023-01-03 19:16:07 +000047/// Port that handles secure world messages
Orlando Arbildoe2000712022-11-24 00:21:21 +000048const KM_SEC_TIPC_SRV_PORT: &str = "com.android.trusty.keymaster.secure";
Orlando Arbildo26583f02023-01-03 19:16:07 +000049/// Port that handles legacy style keymint/keymaster messages
Orlando Arbildod3e50642022-12-09 00:56:30 +000050const KM_NS_LEGACY_TIPC_SRV_PORT: &str = "com.android.trusty.keymaster";
David Drysdaled1d71c62023-03-27 18:48:51 +010051/// Port count for this TA (as above).
52const PORT_COUNT: usize = 3;
53/// Maximum connection count for this TA:
54/// - Gatekeeper
55/// - Fingerprint
56/// - FaceAuth
57/// - Widevine
58/// - Non-secure world.
59const MAX_CONNECTION_COUNT: usize = 5;
Orlando Arbildod3e50642022-12-09 00:56:30 +000060
Orlando Arbildoe2000712022-11-24 00:21:21 +000061const KEYMINT_MAX_BUFFER_LENGTH: usize = 4096;
Hasini Gunasinghe85edc4d2022-10-14 02:09:32 +000062const KEYMINT_MAX_MESSAGE_CONTENT_SIZE: usize = 4000;
Orlando Arbildoe2000712022-11-24 00:21:21 +000063
David Drysdale64702102022-12-14 12:23:16 +000064/// TIPC connection context information.
Orlando Arbildoe2000712022-11-24 00:21:21 +000065struct Context {
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +000066 uuid: Uuid,
Orlando Arbildoe2000712022-11-24 00:21:21 +000067}
68
David Drysdale64702102022-12-14 12:23:16 +000069/// Newtype wrapper for opaque messages.
Orlando Arbildoe2000712022-11-24 00:21:21 +000070struct KMMessage(Vec<u8>);
71
72impl Deserialize for KMMessage {
73 type Error = TipcError;
74 const MAX_SERIALIZED_SIZE: usize = KEYMINT_MAX_BUFFER_LENGTH;
75
Weston Carvalhob021dc92023-02-27 16:02:21 -060076 fn deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> tipc::Result<Self> {
Orlando Arbildoe2000712022-11-24 00:21:21 +000077 Ok(KMMessage(Vec::try_alloc_from(bytes)?))
78 }
79}
80
81impl<'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 Drysdale64702102022-12-14 12:23:16 +000090/// Convert KeyMint [`Algorithm`] to [`SigningAlgorithm`].
Orlando Arbildof0d2d822022-12-13 00:44:14 +000091fn 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 Drysdale64702102022-12-14 12:23:16 +0000105/// TIPC service implementation for communication with the HAL service in Android.
David Drysdale7df0ce22023-05-11 17:21:35 +0100106struct KMService {
107 km_ta: Rc<RefCell<KeyMintTa>>,
Orlando Arbildoe2000712022-11-24 00:21:21 +0000108}
109
David Drysdale7df0ce22023-05-11 17:21:35 +0100110impl KMService {
David Drysdale64702102022-12-14 12:23:16 +0000111 /// Create a service implementation.
David Drysdale7df0ce22023-05-11 17:21:35 +0100112 fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self {
Orlando Arbildoe2000712022-11-24 00:21:21 +0000113 KMService { km_ta }
114 }
115
David Drysdale64702102022-12-14 12:23:16 +0000116 /// 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 Gunasinghe85edc4d2022-10-14 02:09:32 +0000118 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 Arbildoe2000712022-11-24 00:21:21 +0000121 }
122}
123
David Drysdale7df0ce22023-05-11 17:21:35 +0100124impl Service for KMService {
Orlando Arbildoe2000712022-11-24 00:21:21 +0000125 type Connection = Context;
126 type Message = KMMessage;
127
128 fn on_connect(
129 &self,
130 _port: &PortCfg,
131 _handle: &Handle,
132 peer: &Uuid,
Weston Carvalhob021dc92023-02-27 16:02:21 -0600133 ) -> tipc::Result<ConnectResult<Self::Connection>> {
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000134 info!("Accepted connection from uuid {:?}.", peer);
Weston Carvalhob021dc92023-02-27 16:02:21 -0600135 Ok(ConnectResult::Accept(Context { uuid: peer.clone() }))
Orlando Arbildoe2000712022-11-24 00:21:21 +0000136 }
137
138 fn on_message(
139 &self,
140 _connection: &Self::Connection,
141 handle: &Handle,
142 msg: Self::Message,
Weston Carvalhob021dc92023-02-27 16:02:21 -0600143 ) -> tipc::Result<MessageResult> {
Orlando Arbildofcce5502023-01-19 01:05:01 +0000144 debug!("Received a message.");
Hasini Gunasinghe85edc4d2022-10-14 02:09:32 +0000145 let resp_vec = self.handle_message(&msg.0).map_err(|e| match e {
146 Error::Hal(_, err_msg) => {
Orlando Arbildofcce5502023-01-19 01:05:01 +0000147 error!("Error: {} in handling the message.", err_msg);
Hasini Gunasinghe85edc4d2022-10-14 02:09:32 +0000148 TipcError::InvalidData
149 }
150 Error::Alloc(err_msg) => {
Orlando Arbildofcce5502023-01-19 01:05:01 +0000151 error!("Error: {} in handling the message.", err_msg);
Hasini Gunasinghe85edc4d2022-10-14 02:09:32 +0000152 TipcError::AllocError
153 }
154 _ => TipcError::UnknownError,
155 })?;
156 for resp in resp_vec {
157 handle.send(&KMMessage(resp))?;
158 }
Weston Carvalhob021dc92023-02-27 16:02:21 -0600159 Ok(MessageResult::MaintainConnection)
Orlando Arbildoe2000712022-11-24 00:21:21 +0000160 }
161}
162
David Drysdale64702102022-12-14 12:23:16 +0000163/// Retrieve the system state flag controlling provisioning.
164fn 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.
187fn 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.
195fn 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 Drysdale7df0ce22023-05-11 17:21:35 +0100205struct KMLegacyService {
206 km_ta: Rc<RefCell<KeyMintTa>>,
Orlando Arbildod3e50642022-12-09 00:56:30 +0000207 boot_info: RefCell<Option<BootInfo>>,
208 boot_patchlevel: RefCell<Option<u32>>,
209}
210
David Drysdale7df0ce22023-05-11 17:21:35 +0100211impl KMLegacyService {
David Drysdale64702102022-12-14 12:23:16 +0000212 /// Create a service implementation.
David Drysdale7df0ce22023-05-11 17:21:35 +0100213 fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self {
Orlando Arbildod3e50642022-12-09 00:56:30 +0000214 KMLegacyService {
215 km_ta,
216 boot_info: RefCell::new(None),
217 boot_patchlevel: RefCell::new(None),
218 }
219 }
220
David Drysdale64702102022-12-14 12:23:16 +0000221 /// Indicate whether the boot process is complete.
Orlando Arbildod3e50642022-12-09 00:56:30 +0000222 fn boot_done(&self) -> bool {
223 self.km_ta.borrow().is_hal_info_set()
224 }
225
David Drysdale64702102022-12-14 12:23:16 +0000226 /// Indicate whether provisioning operations are allowed.
Orlando Arbildod3e50642022-12-09 00:56:30 +0000227 fn can_provision(&self) -> Result<bool, Error> {
228 if self.boot_done() {
David Drysdale64702102022-12-14 12:23:16 +0000229 provisioning_allowed()
Orlando Arbildod3e50642022-12-09 00:56:30 +0000230 } else {
David Drysdale64702102022-12-14 12:23:16 +0000231 provisioning_allowed_at_boot()
Orlando Arbildod3e50642022-12-09 00:56:30 +0000232 }
233 }
234
David Drysdale64702102022-12-14 12:23:16 +0000235 /// Set the boot information for the TA if possible (i.e. if all parts of the required
236 /// information are available).
Orlando Arbildod3e50642022-12-09 00:56:30 +0000237 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 Drysdale64702102022-12-14 12:23:16 +0000257 /// Process an incoming request message, returning the corresponding response.
Orlando Arbildod3e50642022-12-09 00:56:30 +0000258 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 Drysdale5450c6d2022-12-15 09:25:15 +0000276 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 Arbildod3e50642022-12-09 00:56:30 +0000295 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 Arbildof0d2d822022-12-13 00:44:14 +0000333 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 Arbildoce0d5362023-02-16 00:58:07 +0000338 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 Arbildo1090e1e2023-02-16 20:48:13 +0000345 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 Arbildoede91282023-02-18 01:14:02 +0000352 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 Arbildof0d2d822022-12-13 00:44:14 +0000359 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 Pollitzc4a529d2023-02-10 14:05:30 +0100369 None,
Orlando Arbildof0d2d822022-12-13 00:44:14 +0000370 )?;
371 Ok(TrustyPerformOpRsp::SetAttestationIds(SetAttestationIdsResponse {}))
372 }
Donnie Pollitzc4a529d2023-02-10 14:05:30 +0100373 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 Arbildod3e50642022-12-09 00:56:30 +0000387 }
388 }
389}
390
David Drysdale7df0ce22023-05-11 17:21:35 +0100391impl Service for KMLegacyService {
Orlando Arbildod3e50642022-12-09 00:56:30 +0000392 type Connection = Context;
393 type Message = KMMessage;
394
395 fn on_connect(
396 &self,
397 _port: &PortCfg,
398 _handle: &Handle,
399 peer: &Uuid,
Weston Carvalhob021dc92023-02-27 16:02:21 -0600400 ) -> tipc::Result<ConnectResult<Self::Connection>> {
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000401 info!("Accepted connection from uuid {:?}.", peer);
Weston Carvalhob021dc92023-02-27 16:02:21 -0600402 Ok(ConnectResult::Accept(Context { uuid: peer.clone() }))
Orlando Arbildod3e50642022-12-09 00:56:30 +0000403 }
404
405 fn on_message(
406 &self,
407 _connection: &Self::Connection,
408 handle: &Handle,
409 msg: Self::Message,
Weston Carvalhob021dc92023-02-27 16:02:21 -0600410 ) -> tipc::Result<MessageResult> {
Orlando Arbildofcce5502023-01-19 01:05:01 +0000411 debug!("Received legacy message.");
Orlando Arbildod3e50642022-12-09 00:56:30 +0000412 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 Drysdale5450c6d2022-12-15 09:25:15 +0000416 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 Arbildod3e50642022-12-09 00:56:30 +0000435 handle.send(&KMMessage(resp))?;
Weston Carvalhob021dc92023-02-27 16:02:21 -0600436 Ok(MessageResult::MaintainConnection)
Orlando Arbildod3e50642022-12-09 00:56:30 +0000437 }
438}
439
David Drysdale64702102022-12-14 12:23:16 +0000440/// TIPC service implementation for secure communication with other components in Trusty
441/// (e.g. Gatekeeper, ConfirmationUI), using legacy (C++) message formats.
David Drysdale7df0ce22023-05-11 17:21:35 +0100442struct KMSecureService {
443 km_ta: Rc<RefCell<KeyMintTa>>,
Orlando Arbildoe2000712022-11-24 00:21:21 +0000444}
445
David Drysdale7df0ce22023-05-11 17:21:35 +0100446impl KMSecureService {
David Drysdale64702102022-12-14 12:23:16 +0000447 /// Create a service implementation.
David Drysdale7df0ce22023-05-11 17:21:35 +0100448 fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self {
Orlando Arbildoe2000712022-11-24 00:21:21 +0000449 KMSecureService { km_ta }
450 }
David Drysdale5450c6d2022-12-15 09:25:15 +0000451 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 Drysdale532beee2022-12-21 17:47:16 +0000466 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 Pollitzc4a529d2023-02-10 14:05:30 +0100481 None,
David Drysdale532beee2022-12-21 17:47:16 +0000482 )?;
483 Ok(TrustyPerformSecureOpRsp::SetAttestationIds(SetAttestationIdsResponse {}))
484 }
David Drysdale5450c6d2022-12-15 09:25:15 +0000485 }
486 }
Orlando Arbildoe2000712022-11-24 00:21:21 +0000487}
488
David Drysdale7df0ce22023-05-11 17:21:35 +0100489impl Service for KMSecureService {
Orlando Arbildoe2000712022-11-24 00:21:21 +0000490 type Connection = Context;
491 type Message = KMMessage;
492
493 fn on_connect(
494 &self,
495 _port: &PortCfg,
496 _handle: &Handle,
497 peer: &Uuid,
Weston Carvalhob021dc92023-02-27 16:02:21 -0600498 ) -> tipc::Result<ConnectResult<Self::Connection>> {
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000499 if !keymint_check_target_access_policy(peer) {
500 error!("access policy rejected the uuid: {:?}", peer);
Weston Carvalhob021dc92023-02-27 16:02:21 -0600501 return Ok(ConnectResult::CloseConnection);
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000502 }
503 info!("Accepted connection from uuid {:?}.", peer);
Weston Carvalhob021dc92023-02-27 16:02:21 -0600504 Ok(ConnectResult::Accept(Context { uuid: peer.clone() }))
Orlando Arbildoe2000712022-11-24 00:21:21 +0000505 }
506
507 fn on_message(
508 &self,
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000509 connection: &Self::Connection,
Orlando Arbildoe2000712022-11-24 00:21:21 +0000510 handle: &Handle,
511 msg: Self::Message,
Weston Carvalhob021dc92023-02-27 16:02:21 -0600512 ) -> tipc::Result<MessageResult> {
Orlando Arbildofcce5502023-01-19 01:05:01 +0000513 debug!("Received secure message.");
Orlando Arbildoe2000712022-11-24 00:21:21 +0000514
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 Drysdale5450c6d2022-12-15 09:25:15 +0000519 let op = req_msg.code();
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000520 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 Carvalhob021dc92023-02-27 16:02:21 -0600524 return Ok(MessageResult::CloseConnection);
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000525 }
David Drysdale5450c6d2022-12-15 09:25:15 +0000526
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 Arbildoe2000712022-11-24 00:21:21 +0000539 TipcError::InvalidData
David Drysdale5450c6d2022-12-15 09:25:15 +0000540 })?
Orlando Arbildoe2000712022-11-24 00:21:21 +0000541 }
David Drysdale5450c6d2022-12-15 09:25:15 +0000542 Err(e) => {
543 error!("error handling secure legacy message: {:?}", e);
544 return Err(TipcError::UnknownError);
545 }
546 };
547 handle.send(&KMMessage(resp))?;
Weston Carvalhob021dc92023-02-27 16:02:21 -0600548 Ok(MessageResult::MaintainConnection)
Orlando Arbildoe2000712022-11-24 00:21:21 +0000549 }
550}
551
552service_dispatcher! {
David Drysdale7df0ce22023-05-11 17:21:35 +0100553 enum KMServiceDispatcher {
554 KMService,
555 KMSecureService,
556 KMLegacyService,
Orlando Arbildoe2000712022-11-24 00:21:21 +0000557 }
558}
559
David Drysdale64702102022-12-14 12:23:16 +0000560/// Main loop handler for the KeyMint TA.
David Drysdale7df0ce22023-05-11 17:21:35 +0100561pub fn handle_port_connections(
Orlando Arbildoe2000712022-11-24 00:21:21 +0000562 hw_info: HardwareInfo,
563 rpc_info: RpcInfo,
David Drysdale7df0ce22023-05-11 17:21:35 +0100564 imp: crypto::Implementation,
565 dev: kmr_ta::device::Implementation,
Orlando Arbildoe2000712022-11-24 00:21:21 +0000566) -> 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 Arbildod3e50642022-12-09 00:56:30 +0000569 let legacy_service = KMLegacyService::new(Rc::clone(&km_ta));
Orlando Arbildoe2000712022-11-24 00:21:21 +0000570 let sec_service = KMSecureService::new(km_ta);
571
David Drysdale64702102022-12-14 12:23:16 +0000572 let mut dispatcher = KMServiceDispatcher::<3>::new()
573 .map_err(|e| km_err!(UnknownError, "could not create multi-service dispatcher: {:?}", e))?;
Orlando Arbildoe2000712022-11-24 00:21:21 +0000574 let cfg = PortCfg::new(KM_NS_TIPC_SRV_PORT)
575 .map_err(|e| {
576 km_err!(
577 UnknownError,
David Drysdale64702102022-12-14 12:23:16 +0000578 "could not create port config for {}: {:?}",
Orlando Arbildoe2000712022-11-24 00:21:21 +0000579 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 Drysdale64702102022-12-14 12:23:16 +0000586 km_err!(UnknownError, "could not add non-secure service to dispatcher: {:?}", e)
Orlando Arbildoe2000712022-11-24 00:21:21 +0000587 })?;
588 let cfg = PortCfg::new(KM_SEC_TIPC_SRV_PORT)
589 .map_err(|e| {
590 km_err!(
591 UnknownError,
David Drysdale64702102022-12-14 12:23:16 +0000592 "could not create port config for {}: {:?}",
Orlando Arbildoe2000712022-11-24 00:21:21 +0000593 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 Drysdale64702102022-12-14 12:23:16 +0000599 km_err!(UnknownError, "could not add secure service to dispatcher: {:?}", e)
Orlando Arbildoe2000712022-11-24 00:21:21 +0000600 })?;
Orlando Arbildod3e50642022-12-09 00:56:30 +0000601 let cfg = PortCfg::new(KM_NS_LEGACY_TIPC_SRV_PORT)
602 .map_err(|e| {
603 km_err!(
604 UnknownError,
David Drysdale64702102022-12-14 12:23:16 +0000605 "could not create port config for {}: {:?}",
Orlando Arbildod3e50642022-12-09 00:56:30 +0000606 KM_NS_LEGACY_TIPC_SRV_PORT,
607 e
608 )
609 })?
David Drysdale5450c6d2022-12-15 09:25:15 +0000610 .allow_ta_connect()
611 .allow_ns_connect();
Orlando Arbildod3e50642022-12-09 00:56:30 +0000612 dispatcher.add_service(Rc::new(legacy_service), cfg).map_err(|e| {
David Drysdale64702102022-12-14 12:23:16 +0000613 km_err!(UnknownError, "could not add secure service to dispatcher: {:?}", e)
Orlando Arbildod3e50642022-12-09 00:56:30 +0000614 })?;
Orlando Arbildoe2000712022-11-24 00:21:21 +0000615 let buffer = [0u8; 4096];
David Drysdaled1d71c62023-03-27 18:48:51 +0100616 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 Arbildoe2000712022-11-24 00:21:21 +0000619 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 Drysdale64702102022-12-14 12:23:16 +0000625// TODO: remove when tests reinstated
626#[allow(dead_code)]
Orlando Arbildoe2000712022-11-24 00:21:21 +0000627#[cfg(test)]
628mod tests {
629 use super::*;
Orlando Arbildod3e50642022-12-09 00:56:30 +0000630 use kmr_wire::{
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000631 keymint::{ErrorCode, VerifiedBootState},
Orlando Arbildod3e50642022-12-09 00:56:30 +0000632 legacy::{self, InnerSerialize},
633 };
David Drysdalef2e821c2024-02-12 15:49:29 +0000634 use test::{expect, skip};
Nicole LeGare67849672023-01-26 23:43:43 +0000635 use trusty_std::ffi::{CString, FallibleCString};
Orlando Arbildoe2000712022-11-24 00:21:21 +0000636
Orlando Arbildod3e50642022-12-09 00:56:30 +0000637 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 Arbildof0d2d822022-12-13 00:44:14 +0000640 const SET_ATTESTATION_IDS_CMD: u32 = legacy::TrustyKeymasterOperation::SetAttestationIds as u32;
641 const SET_ATTESTATION_KEY_CMD: u32 = legacy::TrustyKeymasterOperation::SetAttestationKey as u32;
Orlando Arbildod3e50642022-12-09 00:56:30 +0000642
David Drysdalef2e821c2024-02-12 15:49:29 +0000643 #[test]
Orlando Arbildoe2000712022-11-24 00:21:21 +0000644 fn connection_test() {
David Drysdalef2e821c2024-02-12 15:49:29 +0000645 if !cfg!(kmr_enabled) {
646 skip!("KeyMint Rust TA not configured");
647 }
648
Orlando Arbildoe2000712022-11-24 00:21:21 +0000649 // 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 Drysdale64702102022-12-14 12:23:16 +0000651 let _session1 = Handle::connect(port1.as_c_str()).unwrap();
Orlando Arbildoe2000712022-11-24 00:21:21 +0000652 let port2 = CString::try_new(KM_SEC_TIPC_SRV_PORT).unwrap();
David Drysdale64702102022-12-14 12:23:16 +0000653 let _session2 = Handle::connect(port2.as_c_str()).unwrap();
Orlando Arbildod3e50642022-12-09 00:56:30 +0000654 let port3 = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap();
David Drysdale64702102022-12-14 12:23:16 +0000655 let _session3 = Handle::connect(port3.as_c_str()).unwrap();
Orlando Arbildod3e50642022-12-09 00:56:30 +0000656 }
657
David Drysdalef2e821c2024-02-12 15:49:29 +0000658 #[test]
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000659 fn test_access_policy() {
David Drysdalef2e821c2024-02-12 15:49:29 +0000660 if !cfg!(kmr_enabled) {
661 skip!("KeyMint Rust TA not configured");
662 }
663
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000664 // 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 Arbildo892d38d2022-12-19 19:40:14 +0000678 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 Arbildod3e50642022-12-09 00:56:30 +0000699 fn get_configure_boot_patchlevel_message(
700 boot_patchlevel: u32,
701 ) -> Result<Vec<u8>, legacy::Error> {
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000702 let mut req = get_message_request(CONFIGURE_BOOT_PATCHLEVEL_CMD);
Orlando Arbildod3e50642022-12-09 00:56:30 +0000703 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 Arbildo892d38d2022-12-19 19:40:14 +0000715 let mut req = get_message_request(SET_BOOT_PARAMS_CMD);
Orlando Arbildod3e50642022-12-09 00:56:30 +0000716 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 Arbildof0d2d822022-12-13 00:44:14 +0000725 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 Drysdale415c0d62024-03-15 06:40:43 +0000758 // This test should only be run manually as it writes to the secure storage
759 // of the device under test.
760 // #[test]
Orlando Arbildof0d2d822022-12-13 00:44:14 +0000761 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 Drysdale64702102022-12-14 12:23:16 +0000769 session.send(&set_attestation_key_req).unwrap();
Orlando Arbildof0d2d822022-12-13 00:44:14 +0000770 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 Carvalhob021dc92023-02-27 16:02:21 -0600776 fn set_attestation_ids_secure() -> tipc::Result<()> {
Hasini Gunasinghee3bc7002023-01-25 00:48:04 +0000777 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 Drysdale415c0d62024-03-15 06:40:43 +0000808 // This test should only be run manually as it writes to the secure storage
809 // of the device under test.
810 // #[test]
Orlando Arbildof0d2d822022-12-13 00:44:14 +0000811 fn set_attestation_ids() {
David Drysdalef2e821c2024-02-12 15:49:29 +0000812 if !cfg!(kmr_enabled) {
813 skip!("KeyMint Rust TA not configured");
814 }
815
Orlando Arbildof0d2d822022-12-13 00:44:14 +0000816 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 Drysdale64702102022-12-14 12:23:16 +0000842 session.send(&set_attestation_ids_req).unwrap();
Orlando Arbildof0d2d822022-12-13 00:44:14 +0000843 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 Drysdalef2e821c2024-02-12 15:49:29 +0000849 // 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 Arbildod3e50642022-12-09 00:56:30 +0000853 fn send_setbootparams_configure_setbootparams_configure() {
David Drysdalef2e821c2024-02-12 15:49:29 +0000854 if true {
855 skip!("SetBootParams cannot be performed more than once");
856 }
857
Orlando Arbildod3e50642022-12-09 00:56:30 +0000858 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 Drysdale64702102022-12-14 12:23:16 +0000880 session.send(&set_boot_param_req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000881 let km_error_code = get_response_status(&session);
882 expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");
Orlando Arbildod3e50642022-12-09 00:56:30 +0000883
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 Drysdale64702102022-12-14 12:23:16 +0000891 session.send(&configure_bootpatchlevel_req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000892 let km_error_code = get_response_status(&session);
893 expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");
Orlando Arbildod3e50642022-12-09 00:56:30 +0000894
895 // Checking that sending the message a second time fails
David Drysdale64702102022-12-14 12:23:16 +0000896 session.send(&set_boot_param_req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000897 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 Arbildod3e50642022-12-09 00:56:30 +0000899
900 // Checking that sending the message a second time fails
David Drysdale64702102022-12-14 12:23:16 +0000901 session.send(&configure_bootpatchlevel_req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000902 let km_error_code = get_response_status(&session);
Orlando Arbildod3e50642022-12-09 00:56:30 +0000903 expect!(
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000904 km_error_code.is_err(),
Orlando Arbildod3e50642022-12-09 00:56:30 +0000905 "Shouldn't be able to call ConfigureBootPatchlevel a second time"
906 );
907 }
908
David Drysdalef2e821c2024-02-12 15:49:29 +0000909 #[test]
Orlando Arbildod3e50642022-12-09 00:56:30 +0000910 fn send_configure_configure_setbootparams_setbootparams() {
David Drysdalef2e821c2024-02-12 15:49:29 +0000911 if true {
912 skip!("SetBootParams cannot be performed more than once");
913 }
914
Orlando Arbildod3e50642022-12-09 00:56:30 +0000915 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 Drysdale64702102022-12-14 12:23:16 +0000925 session.send(&req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000926 let km_error_code = get_response_status(&session);
927 expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");
Orlando Arbildod3e50642022-12-09 00:56:30 +0000928
929 // Checking that sending the message a second time fails
David Drysdale64702102022-12-14 12:23:16 +0000930 session.send(&req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000931 let km_error_code = get_response_status(&session);
Orlando Arbildod3e50642022-12-09 00:56:30 +0000932 expect!(
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000933 km_error_code.is_err(),
Orlando Arbildod3e50642022-12-09 00:56:30 +0000934 "Shouldn't be able to call ConfigureBootPatchlevel a second time"
935 );
936
Orlando Arbildod3e50642022-12-09 00:56:30 +0000937 // 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 Drysdale64702102022-12-14 12:23:16 +0000956 session.send(&req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000957 let km_error_code = get_response_status(&session);
958 expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");
Orlando Arbildod3e50642022-12-09 00:56:30 +0000959
960 // Checking that sending the message a second time fails
David Drysdale64702102022-12-14 12:23:16 +0000961 session.send(&req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000962 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 Arbildod3e50642022-12-09 00:56:30 +0000964 }
965
David Drysdalef2e821c2024-02-12 15:49:29 +0000966 #[test]
Orlando Arbildod3e50642022-12-09 00:56:30 +0000967 fn send_setbootparams_setbootparams_configure_configure() {
David Drysdalef2e821c2024-02-12 15:49:29 +0000968 if true {
969 skip!("SetBootParams cannot be performed more than once");
970 }
971
Orlando Arbildod3e50642022-12-09 00:56:30 +0000972 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 Drysdale64702102022-12-14 12:23:16 +0000994 session.send(&req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +0000995 let km_error_code = get_response_status(&session);
996 expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");
Orlando Arbildod3e50642022-12-09 00:56:30 +0000997
998 // Checking that sending the message a second time fails
David Drysdale64702102022-12-14 12:23:16 +0000999 session.send(&req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +00001000 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 Arbildod3e50642022-12-09 00:56:30 +00001002
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 Drysdale64702102022-12-14 12:23:16 +00001010 session.send(&req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +00001011 let km_error_code = get_response_status(&session);
1012 expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");
Orlando Arbildod3e50642022-12-09 00:56:30 +00001013
1014 // Checking that sending the message a second time fails
David Drysdale64702102022-12-14 12:23:16 +00001015 session.send(&req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +00001016 let km_error_code = get_response_status(&session);
Orlando Arbildod3e50642022-12-09 00:56:30 +00001017 expect!(
Orlando Arbildo892d38d2022-12-19 19:40:14 +00001018 km_error_code.is_err(),
Orlando Arbildod3e50642022-12-09 00:56:30 +00001019 "Shouldn't be able to call ConfigureBootPatchlevel a second time"
1020 );
1021 }
1022
David Drysdalef2e821c2024-02-12 15:49:29 +00001023 #[test]
Orlando Arbildod3e50642022-12-09 00:56:30 +00001024 fn send_configure_setbootparams_setbootparams_configure() {
David Drysdalef2e821c2024-02-12 15:49:29 +00001025 if true {
1026 skip!("SetBootParams cannot be performed more than once");
1027 }
1028
Orlando Arbildod3e50642022-12-09 00:56:30 +00001029 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 Drysdale64702102022-12-14 12:23:16 +00001039 session.send(&configure_bootpatchlevel_req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +00001040 let km_error_code = get_response_status(&session);
1041 expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");
Orlando Arbildod3e50642022-12-09 00:56:30 +00001042
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 Drysdale64702102022-12-14 12:23:16 +00001062 session.send(&set_boot_param_req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +00001063 let km_error_code = get_response_status(&session);
1064 expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");
Orlando Arbildod3e50642022-12-09 00:56:30 +00001065
1066 // Checking that sending the message a second time fails
David Drysdale64702102022-12-14 12:23:16 +00001067 session.send(&set_boot_param_req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +00001068 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 Arbildod3e50642022-12-09 00:56:30 +00001070
1071 // Checking that sending the message a second time fails
David Drysdale64702102022-12-14 12:23:16 +00001072 session.send(&configure_bootpatchlevel_req).unwrap();
Orlando Arbildo892d38d2022-12-19 19:40:14 +00001073 let km_error_code = get_response_status(&session);
Orlando Arbildod3e50642022-12-09 00:56:30 +00001074 expect!(
Orlando Arbildo892d38d2022-12-19 19:40:14 +00001075 km_error_code.is_err(),
Orlando Arbildod3e50642022-12-09 00:56:30 +00001076 "Shouldn't be able to call ConfigureBootPatchlevel a second time"
1077 );
Orlando Arbildoe2000712022-11-24 00:21:21 +00001078 }
1079}