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.
17 use crate::secure_storage_manager;
18 use alloc::{rc::Rc, vec::Vec};
19 use core::{cell::RefCell, mem};
20 use keymint_access_policy::{
21 keymint_check_secure_target_access_policy_provisioning, keymint_check_target_access_policy,
22 };
23 use kmr_common::{
24 crypto, km_err,
25 wire::legacy::{
26 self, AppendAttestationCertChainResponse, ClearAttestationCertChainResponse,
27 ConfigureBootPatchlevelResponse, GetAuthTokenKeyResponse, GetDeviceInfoResponse,
28 GetVersion2Response, GetVersionResponse, SetAttestationIdsKM3Response,
29 SetAttestationIdsResponse, SetAttestationKeyResponse, SetBootParamsResponse,
30 SetWrappedAttestationKeyResponse, TrustyMessageId, TrustyPerformOpReq, TrustyPerformOpRsp,
31 TrustyPerformSecureOpReq, TrustyPerformSecureOpRsp,
32 },
33 Error,
34 };
35 use kmr_ta::{self, device::SigningAlgorithm, split_rsp, HardwareInfo, KeyMintTa, RpcInfo};
36 use kmr_wire::keymint::{Algorithm, BootInfo};
37 use log::{debug, error, info};
38 use system_state::{ProvisioningAllowedFlagValues, SystemState, SystemStateFlag};
39 use tipc::{
40 service_dispatcher, ConnectResult, Deserialize, Handle, Manager, MessageResult, PortCfg,
41 Serialize, Serializer, Service, TipcError, Uuid,
42 };
43 use trusty_std::alloc::TryAllocFrom;
44
45 /// Port that handles new style keymint messages from non-secure world
46 const KM_NS_TIPC_SRV_PORT: &str = "com.android.trusty.keymint";
47 /// Port that handles secure world messages
48 const KM_SEC_TIPC_SRV_PORT: &str = "com.android.trusty.keymaster.secure";
49 /// Port that handles legacy style keymint/keymaster messages
50 const KM_NS_LEGACY_TIPC_SRV_PORT: &str = "com.android.trusty.keymaster";
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;
60
61 const KEYMINT_MAX_BUFFER_LENGTH: usize = 4096;
62 const KEYMINT_MAX_MESSAGE_CONTENT_SIZE: usize = 4000;
63
64 /// TIPC connection context information.
65 struct Context {
66 uuid: Uuid,
67 }
68
69 /// Newtype wrapper for opaque messages.
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
deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> tipc::Result<Self>76 fn deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> tipc::Result<Self> {
77 Ok(KMMessage(Vec::try_alloc_from(bytes)?))
78 }
79 }
80
81 impl<'s> Serialize<'s> for KMMessage {
serialize<'a: 's, S: Serializer<'s>>( &'a self, serializer: &mut S, ) -> Result<S::Ok, S::Error>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
90 /// Convert KeyMint [`Algorithm`] to [`SigningAlgorithm`].
keymaster_algorithm_to_signing_algorithm( algorithm: Algorithm, ) -> Result<SigningAlgorithm, Error>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
105 /// TIPC service implementation for communication with the HAL service in Android.
106 struct KMService {
107 km_ta: Rc<RefCell<KeyMintTa>>,
108 }
109
110 impl KMService {
111 /// Create a service implementation.
new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self112 fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self {
113 KMService { km_ta }
114 }
115
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.
handle_message(&self, req_data: &[u8]) -> Result<Vec<Vec<u8>>, Error>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)
121 }
122 }
123
124 impl Service for KMService {
125 type Connection = Context;
126 type Message = KMMessage;
127
on_connect( &self, _port: &PortCfg, _handle: &Handle, peer: &Uuid, ) -> tipc::Result<ConnectResult<Self::Connection>>128 fn on_connect(
129 &self,
130 _port: &PortCfg,
131 _handle: &Handle,
132 peer: &Uuid,
133 ) -> tipc::Result<ConnectResult<Self::Connection>> {
134 debug!("Accepted connection from uuid {:?}.", peer);
135 Ok(ConnectResult::Accept(Context { uuid: peer.clone() }))
136 }
137
on_message( &self, _connection: &Self::Connection, handle: &Handle, msg: Self::Message, ) -> tipc::Result<MessageResult>138 fn on_message(
139 &self,
140 _connection: &Self::Connection,
141 handle: &Handle,
142 msg: Self::Message,
143 ) -> tipc::Result<MessageResult> {
144 debug!("Received a message.");
145 let resp_vec = self.handle_message(&msg.0).map_err(|e| match e {
146 Error::Hal(_, err_msg) => {
147 error!("Error: {} in handling the message.", err_msg);
148 TipcError::InvalidData
149 }
150 Error::Alloc(err_msg) => {
151 error!("Error: {} in handling the message.", err_msg);
152 TipcError::AllocError
153 }
154 _ => TipcError::UnknownError,
155 })?;
156 for resp in resp_vec {
157 handle.send(&KMMessage(resp))?;
158 }
159 Ok(MessageResult::MaintainConnection)
160 }
161 }
162
163 /// Retrieve the system state flag controlling provisioning.
get_system_state_provisioning_flag() -> Result<ProvisioningAllowedFlagValues, Error>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.
provisioning_allowed() -> Result<bool, Error>187 fn provisioning_allowed() -> Result<bool, Error> {
188 Ok(matches!(
189 get_system_state_provisioning_flag()?,
190 ProvisioningAllowedFlagValues::ProvisioningAllowed
191 ))
192 }
193
194 /// Indicate whether provisioning is allowed during boot.
provisioning_allowed_at_boot() -> Result<bool, Error>195 fn provisioning_allowed_at_boot() -> Result<bool, Error> {
196 Ok(matches!(
197 get_system_state_provisioning_flag()?,
198 ProvisioningAllowedFlagValues::ProvisioningAllowed
199 | ProvisioningAllowedFlagValues::ProvisioningAllowedAtBoot
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.
205 struct KMLegacyService {
206 km_ta: Rc<RefCell<KeyMintTa>>,
207 boot_info: RefCell<Option<BootInfo>>,
208 boot_patchlevel: RefCell<Option<u32>>,
209 }
210
211 impl KMLegacyService {
212 /// Create a service implementation.
new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self213 fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self {
214 KMLegacyService {
215 km_ta,
216 boot_info: RefCell::new(None),
217 boot_patchlevel: RefCell::new(None),
218 }
219 }
220
221 /// Indicate whether the boot process is complete.
boot_done(&self) -> bool222 fn boot_done(&self) -> bool {
223 self.km_ta.borrow().is_hal_info_set()
224 }
225
226 /// Indicate whether provisioning operations are allowed.
can_provision(&self) -> Result<bool, Error>227 fn can_provision(&self) -> Result<bool, Error> {
228 if self.boot_done() {
229 provisioning_allowed()
230 } else {
231 provisioning_allowed_at_boot()
232 }
233 }
234
235 /// Set the boot information for the TA if possible (i.e. if all parts of the required
236 /// information are available).
maybe_set_boot_info(&self)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
257 /// Process an incoming request message, returning the corresponding response.
handle_message(&self, req_msg: TrustyPerformOpReq) -> Result<TrustyPerformOpRsp, Error>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 {
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 }
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 }
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 }
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 }
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 }
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 }
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,
369 None,
370 )?;
371 Ok(TrustyPerformOpRsp::SetAttestationIds(SetAttestationIdsResponse {}))
372 }
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 }
387 }
388 }
389 }
390
391 impl Service for KMLegacyService {
392 type Connection = Context;
393 type Message = KMMessage;
394
on_connect( &self, _port: &PortCfg, _handle: &Handle, peer: &Uuid, ) -> tipc::Result<ConnectResult<Self::Connection>>395 fn on_connect(
396 &self,
397 _port: &PortCfg,
398 _handle: &Handle,
399 peer: &Uuid,
400 ) -> tipc::Result<ConnectResult<Self::Connection>> {
401 debug!("Accepted connection from uuid {:?}.", peer);
402 Ok(ConnectResult::Accept(Context { uuid: peer.clone() }))
403 }
404
on_message( &self, _connection: &Self::Connection, handle: &Handle, msg: Self::Message, ) -> tipc::Result<MessageResult>405 fn on_message(
406 &self,
407 _connection: &Self::Connection,
408 handle: &Handle,
409 msg: Self::Message,
410 ) -> tipc::Result<MessageResult> {
411 debug!("Received legacy message.");
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 })?;
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 };
435 handle.send(&KMMessage(resp))?;
436 Ok(MessageResult::MaintainConnection)
437 }
438 }
439
440 /// TIPC service implementation for secure communication with other components in Trusty
441 /// (e.g. Gatekeeper, ConfirmationUI), using legacy (C++) message formats.
442 struct KMSecureService {
443 km_ta: Rc<RefCell<KeyMintTa>>,
444 }
445
446 impl KMSecureService {
447 /// Create a service implementation.
new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self448 fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self {
449 KMSecureService { km_ta }
450 }
handle_message( &self, req_msg: TrustyPerformSecureOpReq, ) -> Result<TrustyPerformSecureOpRsp, Error>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 }
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,
481 None,
482 )?;
483 Ok(TrustyPerformSecureOpRsp::SetAttestationIds(SetAttestationIdsResponse {}))
484 }
485 }
486 }
487 }
488
489 impl Service for KMSecureService {
490 type Connection = Context;
491 type Message = KMMessage;
492
on_connect( &self, _port: &PortCfg, _handle: &Handle, peer: &Uuid, ) -> tipc::Result<ConnectResult<Self::Connection>>493 fn on_connect(
494 &self,
495 _port: &PortCfg,
496 _handle: &Handle,
497 peer: &Uuid,
498 ) -> tipc::Result<ConnectResult<Self::Connection>> {
499 if !keymint_check_target_access_policy(peer) {
500 error!("access policy rejected the uuid: {:?}", peer);
501 return Ok(ConnectResult::CloseConnection);
502 }
503 debug!("Accepted connection from uuid {:?}.", peer);
504 Ok(ConnectResult::Accept(Context { uuid: peer.clone() }))
505 }
506
on_message( &self, connection: &Self::Connection, handle: &Handle, msg: Self::Message, ) -> tipc::Result<MessageResult>507 fn on_message(
508 &self,
509 connection: &Self::Connection,
510 handle: &Handle,
511 msg: Self::Message,
512 ) -> tipc::Result<MessageResult> {
513 debug!("Received secure message.");
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 })?;
519 let op = req_msg.code();
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);
524 return Ok(MessageResult::CloseConnection);
525 }
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 );
539 TipcError::InvalidData
540 })?
541 }
542 Err(e) => {
543 error!("error handling secure legacy message: {:?}", e);
544 return Err(TipcError::UnknownError);
545 }
546 };
547 handle.send(&KMMessage(resp))?;
548 Ok(MessageResult::MaintainConnection)
549 }
550 }
551
552 service_dispatcher! {
553 enum KMServiceDispatcher {
554 KMService,
555 KMSecureService,
556 KMLegacyService,
557 }
558 }
559
560 /// Main loop handler for the KeyMint TA.
handle_port_connections( hw_info: HardwareInfo, rpc_info: RpcInfo, imp: crypto::Implementation, dev: kmr_ta::device::Implementation, ) -> Result<(), Error>561 pub fn handle_port_connections(
562 hw_info: HardwareInfo,
563 rpc_info: RpcInfo,
564 imp: crypto::Implementation,
565 dev: kmr_ta::device::Implementation,
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));
569 let legacy_service = KMLegacyService::new(Rc::clone(&km_ta));
570 let sec_service = KMSecureService::new(km_ta);
571
572 let mut dispatcher = KMServiceDispatcher::<3>::new()
573 .map_err(|e| km_err!(UnknownError, "could not create multi-service dispatcher: {:?}", e))?;
574 let cfg = PortCfg::new(KM_NS_TIPC_SRV_PORT)
575 .map_err(|e| {
576 km_err!(
577 UnknownError,
578 "could not create port config for {}: {:?}",
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| {
586 km_err!(UnknownError, "could not add non-secure service to dispatcher: {:?}", e)
587 })?;
588 let cfg = PortCfg::new(KM_SEC_TIPC_SRV_PORT)
589 .map_err(|e| {
590 km_err!(
591 UnknownError,
592 "could not create port config for {}: {:?}",
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| {
599 km_err!(UnknownError, "could not add secure service to dispatcher: {:?}", e)
600 })?;
601 let cfg = PortCfg::new(KM_NS_LEGACY_TIPC_SRV_PORT)
602 .map_err(|e| {
603 km_err!(
604 UnknownError,
605 "could not create port config for {}: {:?}",
606 KM_NS_LEGACY_TIPC_SRV_PORT,
607 e
608 )
609 })?
610 .allow_ta_connect()
611 .allow_ns_connect();
612 dispatcher.add_service(Rc::new(legacy_service), cfg).map_err(|e| {
613 km_err!(UnknownError, "could not add secure service to dispatcher: {:?}", e)
614 })?;
615 let buffer = [0u8; 4096];
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))?;
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
625 // TODO: remove when tests reinstated
626 #[allow(dead_code)]
627 #[cfg(test)]
628 mod tests {
629 use super::*;
630 use kmr_wire::{
631 keymint::{ErrorCode, VerifiedBootState},
632 legacy::{self, InnerSerialize},
633 };
634 use test::{expect, skip};
635 use trusty_std::ffi::{CString, FallibleCString};
636
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;
640 const SET_ATTESTATION_IDS_CMD: u32 = legacy::TrustyKeymasterOperation::SetAttestationIds as u32;
641 const SET_ATTESTATION_KEY_CMD: u32 = legacy::TrustyKeymasterOperation::SetAttestationKey as u32;
642
643 #[test]
connection_test()644 fn connection_test() {
645 if !cfg!(kmr_enabled) {
646 skip!("KeyMint Rust TA not configured");
647 }
648
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();
651 let _session1 = Handle::connect(port1.as_c_str()).unwrap();
652 let port2 = CString::try_new(KM_SEC_TIPC_SRV_PORT).unwrap();
653 let _session2 = Handle::connect(port2.as_c_str()).unwrap();
654 let port3 = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap();
655 let _session3 = Handle::connect(port3.as_c_str()).unwrap();
656 }
657
658 #[test]
test_access_policy()659 fn test_access_policy() {
660 if !cfg!(kmr_enabled) {
661 skip!("KeyMint Rust TA not configured");
662 }
663
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
check_response_status(rsp: &KMMessage) -> Result<(), ErrorCode>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
get_message_request(cmd: u32) -> Vec<u8>688 fn get_message_request(cmd: u32) -> Vec<u8> {
689 (cmd << legacy::TRUSTY_CMD_SHIFT).to_ne_bytes().to_vec()
690 }
691
get_response_status(session: &Handle) -> Result<(), ErrorCode>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
get_configure_boot_patchlevel_message( boot_patchlevel: u32, ) -> Result<Vec<u8>, legacy::Error>699 fn get_configure_boot_patchlevel_message(
700 boot_patchlevel: u32,
701 ) -> Result<Vec<u8>, legacy::Error> {
702 let mut req = get_message_request(CONFIGURE_BOOT_PATCHLEVEL_CMD);
703 boot_patchlevel.serialize_into(&mut req)?;
704 Ok(req)
705 }
706
get_set_boot_params_message( os_version: u32, os_patchlevel: u32, device_locked: bool, verified_boot_state: VerifiedBootState, verified_boot_key: Vec<u8>, verified_boot_hash: Vec<u8>, ) -> Result<Vec<u8>, legacy::Error>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> {
715 let mut req = get_message_request(SET_BOOT_PARAMS_CMD);
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
get_set_attestation_ids_message( brand: &Vec<u8>, product: &Vec<u8>, device: &Vec<u8>, serial: &Vec<u8>, imei: &Vec<u8>, meid: &Vec<u8>, manufacturer: &Vec<u8>, model: &Vec<u8>, ) -> Result<Vec<u8>, legacy::Error>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
get_set_attestation_key_message( algorithm: Algorithm, content: &[u8], ) -> Result<Vec<u8>, legacy::Error>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
758 // This test should only be run manually as it writes to the secure storage
759 // of the device under test.
760 // #[test]
set_attestation_keys_certs()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
769 session.send(&set_attestation_key_req).unwrap();
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
set_attestation_ids_secure() -> tipc::Result<()>776 fn set_attestation_ids_secure() -> tipc::Result<()> {
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
808 // This test should only be run manually as it writes to the secure storage
809 // of the device under test.
810 // #[test]
set_attestation_ids()811 fn set_attestation_ids() {
812 if !cfg!(kmr_enabled) {
813 skip!("KeyMint Rust TA not configured");
814 }
815
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
842 session.send(&set_attestation_ids_req).unwrap();
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
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]
send_setbootparams_configure_setbootparams_configure()853 fn send_setbootparams_configure_setbootparams_configure() {
854 if true {
855 skip!("SetBootParams cannot be performed more than once");
856 }
857
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
880 session.send(&set_boot_param_req).unwrap();
881 let km_error_code = get_response_status(&session);
882 expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");
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
891 session.send(&configure_bootpatchlevel_req).unwrap();
892 let km_error_code = get_response_status(&session);
893 expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");
894
895 // Checking that sending the message a second time fails
896 session.send(&set_boot_param_req).unwrap();
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");
899
900 // Checking that sending the message a second time fails
901 session.send(&configure_bootpatchlevel_req).unwrap();
902 let km_error_code = get_response_status(&session);
903 expect!(
904 km_error_code.is_err(),
905 "Shouldn't be able to call ConfigureBootPatchlevel a second time"
906 );
907 }
908
909 #[test]
send_configure_configure_setbootparams_setbootparams()910 fn send_configure_configure_setbootparams_setbootparams() {
911 if true {
912 skip!("SetBootParams cannot be performed more than once");
913 }
914
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
925 session.send(&req).unwrap();
926 let km_error_code = get_response_status(&session);
927 expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");
928
929 // Checking that sending the message a second time fails
930 session.send(&req).unwrap();
931 let km_error_code = get_response_status(&session);
932 expect!(
933 km_error_code.is_err(),
934 "Shouldn't be able to call ConfigureBootPatchlevel a second time"
935 );
936
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
956 session.send(&req).unwrap();
957 let km_error_code = get_response_status(&session);
958 expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");
959
960 // Checking that sending the message a second time fails
961 session.send(&req).unwrap();
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");
964 }
965
966 #[test]
send_setbootparams_setbootparams_configure_configure()967 fn send_setbootparams_setbootparams_configure_configure() {
968 if true {
969 skip!("SetBootParams cannot be performed more than once");
970 }
971
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
994 session.send(&req).unwrap();
995 let km_error_code = get_response_status(&session);
996 expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");
997
998 // Checking that sending the message a second time fails
999 session.send(&req).unwrap();
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");
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
1010 session.send(&req).unwrap();
1011 let km_error_code = get_response_status(&session);
1012 expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");
1013
1014 // Checking that sending the message a second time fails
1015 session.send(&req).unwrap();
1016 let km_error_code = get_response_status(&session);
1017 expect!(
1018 km_error_code.is_err(),
1019 "Shouldn't be able to call ConfigureBootPatchlevel a second time"
1020 );
1021 }
1022
1023 #[test]
send_configure_setbootparams_setbootparams_configure()1024 fn send_configure_setbootparams_setbootparams_configure() {
1025 if true {
1026 skip!("SetBootParams cannot be performed more than once");
1027 }
1028
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
1039 session.send(&configure_bootpatchlevel_req).unwrap();
1040 let km_error_code = get_response_status(&session);
1041 expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");
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
1062 session.send(&set_boot_param_req).unwrap();
1063 let km_error_code = get_response_status(&session);
1064 expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");
1065
1066 // Checking that sending the message a second time fails
1067 session.send(&set_boot_param_req).unwrap();
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");
1070
1071 // Checking that sending the message a second time fails
1072 session.send(&configure_bootpatchlevel_req).unwrap();
1073 let km_error_code = get_response_status(&session);
1074 expect!(
1075 km_error_code.is_err(),
1076 "Shouldn't be able to call ConfigureBootPatchlevel a second time"
1077 );
1078 }
1079 }
1080