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