• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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