1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! KeyMint HAL device implementation.
16 
17 use crate::binder;
18 use crate::hal::{
19     failed_conversion, keymint, keymint::IKeyMintOperation::IKeyMintOperation,
20     secureclock::TimeStampToken::TimeStampToken, Innto, TryInnto,
21 };
22 use crate::{ChannelHalService, SerializedChannel};
23 use kmr_wire::{keymint::KeyParam, AsCborValue, *};
24 use log::warn;
25 use std::ffi::CString;
26 use std::{
27     ops::DerefMut,
28     sync::{Arc, Mutex, MutexGuard, RwLock},
29 };
30 
31 /// Maximum overhead size from CBOR serialization of operation messages.
32 ///
33 /// A serialized `FinishRequest` includes the following additional bytes over and
34 /// above the size of the input (at most):
35 /// -    1: array wrapper (0x86)
36 ///   -  9: int (0x1b + u64) [op_handle]
37 ///   -  1: array wrapper (0x81) [input]
38 ///      -  9: input data length
39 ///      - XX:  input data
40 ///   -  1: array wrapper (0x81) [signature]
41 ///      - 5: signature data length
42 ///      - 132: signature data (P-521 point)
43 ///   -  1: array wrapper (0x81) [auth_token]
44 ///      -  9: int (0x1b + u64) [challenge]
45 ///      -  9: int (0x1b + u64) [user_id]
46 ///      -  9: int (0x1b + u64) [authenticator_id]
47 ///      -  9: int (0x1b + u64) [authenticator_type]
48 ///      -  1: array wrapper (0x81)[timestamp]
49 ///         -  9: int (0x1b + u64) [user_id]
50 ///      -  2: bstr header [mac]
51 ///      - 32: bstr [mac]
52 ///   -  1: array wrapper (0x81) [timestamp_token]
53 ///      -  1: array wrapper [TimeStampToken]
54 ///         -  9: int (0x1b + u64) [challenge]
55 ///         -  1: array wrapper (0x81)[timestamp]
56 ///            -  9: int (0x1b + u64) [user_id]
57 ///         -  2: bstr header [mac]
58 ///         - 32: bstr [mac]
59 ///   -  1: array wrapper (0x81) [confirmation_token]
60 ///      -  2: bstr header [confirmation token]
61 ///      - 32: bstr [confirmation token (HMAC-SHA256)]
62 ///
63 /// Add some leeway in case encodings change.
64 pub const MAX_CBOR_OVERHEAD: usize = 350;
65 
66 /// IKeyMintDevice implementation which converts all method invocations to serialized
67 /// requests that are sent down the associated channel.
68 pub struct Device<T: SerializedChannel + 'static> {
69     channel: Arc<Mutex<T>>,
70 }
71 
72 impl<T: SerializedChannel + 'static> Device<T> {
73     /// Construct a new instance that uses the provided channel.
new(channel: Arc<Mutex<T>>) -> Self74     pub fn new(channel: Arc<Mutex<T>>) -> Self {
75         Self { channel }
76     }
77 
78     /// Create a new instance wrapped in a proxy object.
new_as_binder( channel: Arc<Mutex<T>>, ) -> binder::Strong<dyn keymint::IKeyMintDevice::IKeyMintDevice>79     pub fn new_as_binder(
80         channel: Arc<Mutex<T>>,
81     ) -> binder::Strong<dyn keymint::IKeyMintDevice::IKeyMintDevice> {
82         keymint::IKeyMintDevice::BnKeyMintDevice::new_binder(
83             Self::new(channel),
84             binder::BinderFeatures::default(),
85         )
86     }
87 }
88 
89 impl<T: SerializedChannel> ChannelHalService<T> for Device<T> {
channel(&self) -> MutexGuard<T>90     fn channel(&self) -> MutexGuard<T> {
91         self.channel.lock().unwrap()
92     }
93 }
94 
95 impl<T: SerializedChannel> binder::Interface for Device<T> {}
96 
97 impl<T: SerializedChannel> keymint::IKeyMintDevice::IKeyMintDevice for Device<T> {
getHardwareInfo(&self) -> binder::Result<keymint::KeyMintHardwareInfo::KeyMintHardwareInfo>98     fn getHardwareInfo(&self) -> binder::Result<keymint::KeyMintHardwareInfo::KeyMintHardwareInfo> {
99         let rsp: GetHardwareInfoResponse = self.execute(GetHardwareInfoRequest {})?;
100         Ok(rsp.ret.innto())
101     }
addRngEntropy(&self, data: &[u8]) -> binder::Result<()>102     fn addRngEntropy(&self, data: &[u8]) -> binder::Result<()> {
103         let _rsp: AddRngEntropyResponse =
104             self.execute(AddRngEntropyRequest { data: data.to_vec() })?;
105         Ok(())
106     }
generateKey( &self, keyParams: &[keymint::KeyParameter::KeyParameter], attestationKey: Option<&keymint::AttestationKey::AttestationKey>, ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult>107     fn generateKey(
108         &self,
109         keyParams: &[keymint::KeyParameter::KeyParameter],
110         attestationKey: Option<&keymint::AttestationKey::AttestationKey>,
111     ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult> {
112         let rsp: GenerateKeyResponse = self.execute(GenerateKeyRequest {
113             key_params: keyParams
114                 .iter()
115                 .filter_map(|p| p.try_innto().transpose())
116                 .collect::<Result<Vec<KeyParam>, _>>()
117                 .map_err(failed_conversion)?,
118             attestation_key: match attestationKey {
119                 None => None,
120                 Some(k) => Some(k.clone().try_innto().map_err(failed_conversion)?),
121             },
122         })?;
123         Ok(rsp.ret.innto())
124     }
importKey( &self, keyParams: &[keymint::KeyParameter::KeyParameter], keyFormat: keymint::KeyFormat::KeyFormat, keyData: &[u8], attestationKey: Option<&keymint::AttestationKey::AttestationKey>, ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult>125     fn importKey(
126         &self,
127         keyParams: &[keymint::KeyParameter::KeyParameter],
128         keyFormat: keymint::KeyFormat::KeyFormat,
129         keyData: &[u8],
130         attestationKey: Option<&keymint::AttestationKey::AttestationKey>,
131     ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult> {
132         let rsp: ImportKeyResponse = self.execute(ImportKeyRequest {
133             key_params: keyParams
134                 .iter()
135                 .filter_map(|p| p.try_innto().transpose())
136                 .collect::<Result<Vec<KeyParam>, _>>()
137                 .map_err(failed_conversion)?,
138             key_format: keyFormat.try_innto().map_err(failed_conversion)?,
139             key_data: keyData.to_vec(),
140             attestation_key: match attestationKey {
141                 None => None,
142                 Some(k) => Some(k.clone().try_innto().map_err(failed_conversion)?),
143             },
144         })?;
145         Ok(rsp.ret.innto())
146     }
importWrappedKey( &self, wrappedKeyData: &[u8], wrappingKeyBlob: &[u8], maskingKey: &[u8], unwrappingParams: &[keymint::KeyParameter::KeyParameter], passwordSid: i64, biometricSid: i64, ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult>147     fn importWrappedKey(
148         &self,
149         wrappedKeyData: &[u8],
150         wrappingKeyBlob: &[u8],
151         maskingKey: &[u8],
152         unwrappingParams: &[keymint::KeyParameter::KeyParameter],
153         passwordSid: i64,
154         biometricSid: i64,
155     ) -> binder::Result<keymint::KeyCreationResult::KeyCreationResult> {
156         let rsp: ImportWrappedKeyResponse = self.execute(ImportWrappedKeyRequest {
157             wrapped_key_data: wrappedKeyData.to_vec(),
158             wrapping_key_blob: wrappingKeyBlob.to_vec(),
159             masking_key: maskingKey.to_vec(),
160             unwrapping_params: unwrappingParams
161                 .iter()
162                 .filter_map(|p| p.try_innto().transpose())
163                 .collect::<Result<Vec<KeyParam>, _>>()
164                 .map_err(failed_conversion)?,
165             password_sid: passwordSid,
166             biometric_sid: biometricSid,
167         })?;
168         Ok(rsp.ret.innto())
169     }
upgradeKey( &self, keyBlobToUpgrade: &[u8], upgradeParams: &[keymint::KeyParameter::KeyParameter], ) -> binder::Result<Vec<u8>>170     fn upgradeKey(
171         &self,
172         keyBlobToUpgrade: &[u8],
173         upgradeParams: &[keymint::KeyParameter::KeyParameter],
174     ) -> binder::Result<Vec<u8>> {
175         let rsp: UpgradeKeyResponse = self.execute(UpgradeKeyRequest {
176             key_blob_to_upgrade: keyBlobToUpgrade.to_vec(),
177             upgrade_params: upgradeParams
178                 .iter()
179                 .filter_map(|p| p.try_innto().transpose())
180                 .collect::<Result<Vec<KeyParam>, _>>()
181                 .map_err(failed_conversion)?,
182         })?;
183         Ok(rsp.ret)
184     }
deleteKey(&self, keyBlob: &[u8]) -> binder::Result<()>185     fn deleteKey(&self, keyBlob: &[u8]) -> binder::Result<()> {
186         let _rsp: DeleteKeyResponse =
187             self.execute(DeleteKeyRequest { key_blob: keyBlob.to_vec() })?;
188         Ok(())
189     }
deleteAllKeys(&self) -> binder::Result<()>190     fn deleteAllKeys(&self) -> binder::Result<()> {
191         let _rsp: DeleteAllKeysResponse = self.execute(DeleteAllKeysRequest {})?;
192         Ok(())
193     }
destroyAttestationIds(&self) -> binder::Result<()>194     fn destroyAttestationIds(&self) -> binder::Result<()> {
195         let _rsp: DestroyAttestationIdsResponse = self.execute(DestroyAttestationIdsRequest {})?;
196         Ok(())
197     }
begin( &self, purpose: keymint::KeyPurpose::KeyPurpose, keyBlob: &[u8], params: &[keymint::KeyParameter::KeyParameter], authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>, ) -> binder::Result<keymint::BeginResult::BeginResult>198     fn begin(
199         &self,
200         purpose: keymint::KeyPurpose::KeyPurpose,
201         keyBlob: &[u8],
202         params: &[keymint::KeyParameter::KeyParameter],
203         authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>,
204     ) -> binder::Result<keymint::BeginResult::BeginResult> {
205         let rsp: BeginResponse = self.execute(BeginRequest {
206             purpose: purpose.try_innto().map_err(failed_conversion)?,
207             key_blob: keyBlob.to_vec(),
208             params: params
209                 .iter()
210                 .filter_map(|p| p.try_innto().transpose())
211                 .collect::<Result<Vec<KeyParam>, _>>()
212                 .map_err(failed_conversion)?,
213             auth_token: match authToken {
214                 None => None,
215                 Some(t) => Some(t.clone().try_innto().map_err(failed_conversion)?),
216             },
217         })?;
218         // The `begin()` method is a special case.
219         // - Internally, the in-progress operation is identified by an opaque handle value.
220         // - Externally, the in-progress operation is represented as an `IKeyMintOperation` Binder
221         //   object.
222         // The `WireOperation` struct contains the former, and acts as the latter.
223         let op = Operation::new_as_binder(self.channel.clone(), rsp.ret.op_handle);
224         Ok(keymint::BeginResult::BeginResult {
225             challenge: rsp.ret.challenge,
226             params: rsp.ret.params.innto(),
227             operation: Some(op),
228         })
229     }
deviceLocked( &self, _passwordOnly: bool, _timestampToken: Option<&TimeStampToken>, ) -> binder::Result<()>230     fn deviceLocked(
231         &self,
232         _passwordOnly: bool,
233         _timestampToken: Option<&TimeStampToken>,
234     ) -> binder::Result<()> {
235         // This method is deprecated and unused, so just fail with error UNIMPLEMENTED.
236         warn!("Deprecated method devicedLocked() was called");
237         Err(binder::Status::new_service_specific_error(
238             keymint::ErrorCode::ErrorCode::UNIMPLEMENTED.0,
239             Some(&CString::new("Deprecated method deviceLocked() is not implemented").unwrap()),
240         ))
241     }
earlyBootEnded(&self) -> binder::Result<()>242     fn earlyBootEnded(&self) -> binder::Result<()> {
243         let _rsp: EarlyBootEndedResponse = self.execute(EarlyBootEndedRequest {})?;
244         Ok(())
245     }
convertStorageKeyToEphemeral(&self, storageKeyBlob: &[u8]) -> binder::Result<Vec<u8>>246     fn convertStorageKeyToEphemeral(&self, storageKeyBlob: &[u8]) -> binder::Result<Vec<u8>> {
247         let rsp: ConvertStorageKeyToEphemeralResponse =
248             self.execute(ConvertStorageKeyToEphemeralRequest {
249                 storage_key_blob: storageKeyBlob.to_vec(),
250             })?;
251         Ok(rsp.ret)
252     }
getKeyCharacteristics( &self, keyBlob: &[u8], appId: &[u8], appData: &[u8], ) -> binder::Result<Vec<keymint::KeyCharacteristics::KeyCharacteristics>>253     fn getKeyCharacteristics(
254         &self,
255         keyBlob: &[u8],
256         appId: &[u8],
257         appData: &[u8],
258     ) -> binder::Result<Vec<keymint::KeyCharacteristics::KeyCharacteristics>> {
259         let rsp: GetKeyCharacteristicsResponse = self.execute(GetKeyCharacteristicsRequest {
260             key_blob: keyBlob.to_vec(),
261             app_id: appId.to_vec(),
262             app_data: appData.to_vec(),
263         })?;
264         Ok(rsp.ret.innto())
265     }
266     #[cfg(feature = "hal_v2")]
getRootOfTrustChallenge(&self) -> binder::Result<[u8; 16]>267     fn getRootOfTrustChallenge(&self) -> binder::Result<[u8; 16]> {
268         let rsp: GetRootOfTrustChallengeResponse =
269             self.execute(GetRootOfTrustChallengeRequest {})?;
270         Ok(rsp.ret)
271     }
272     #[cfg(feature = "hal_v2")]
getRootOfTrust(&self, challenge: &[u8; 16]) -> binder::Result<Vec<u8>>273     fn getRootOfTrust(&self, challenge: &[u8; 16]) -> binder::Result<Vec<u8>> {
274         let rsp: GetRootOfTrustResponse =
275             self.execute(GetRootOfTrustRequest { challenge: *challenge })?;
276         Ok(rsp.ret)
277     }
278     #[cfg(feature = "hal_v2")]
sendRootOfTrust(&self, root_of_trust: &[u8]) -> binder::Result<()>279     fn sendRootOfTrust(&self, root_of_trust: &[u8]) -> binder::Result<()> {
280         let _rsp: SendRootOfTrustResponse =
281             self.execute(SendRootOfTrustRequest { root_of_trust: root_of_trust.to_vec() })?;
282         Ok(())
283     }
284 }
285 
286 /// Representation of an in-progress KeyMint operation on a `SerializedChannel`.
287 #[derive(Debug)]
288 struct Operation<T: SerializedChannel + 'static> {
289     channel: Arc<Mutex<T>>,
290     op_handle: RwLock<Option<i64>>,
291 }
292 
293 impl<T: SerializedChannel + 'static> Drop for Operation<T> {
drop(&mut self)294     fn drop(&mut self) {
295         // Ensure that the TA is kept up-to-date by calling `abort()`, but ignore the result.
296         let _ = self.abort();
297     }
298 }
299 
300 impl<T: SerializedChannel> ChannelHalService<T> for Operation<T> {
channel(&self) -> MutexGuard<T>301     fn channel(&self) -> MutexGuard<T> {
302         self.channel.lock().unwrap()
303     }
304 
305     /// Execute the given request as part of the operation.  If the request fails, the operation is
306     /// invalidated (and any future requests for the operation will fail).
execute<R, S>(&self, req: R) -> binder::Result<S> where R: AsCborValue + Code<KeyMintOperation>, S: AsCborValue + Code<KeyMintOperation>,307     fn execute<R, S>(&self, req: R) -> binder::Result<S>
308     where
309         R: AsCborValue + Code<KeyMintOperation>,
310         S: AsCborValue + Code<KeyMintOperation>,
311     {
312         let result = super::channel_execute(self.channel().deref_mut(), req);
313         if result.is_err() {
314             // Any failed method on an operation terminates the operation.
315             self.invalidate();
316         }
317         result
318     }
319 }
320 
321 impl<T: SerializedChannel> binder::Interface for Operation<T> {}
322 
323 impl<T: SerializedChannel + 'static> Operation<T> {
324     /// Create a new `Operation` wrapped in a proxy object.
new_as_binder( channel: Arc<Mutex<T>>, op_handle: i64, ) -> binder::Strong<dyn keymint::IKeyMintOperation::IKeyMintOperation>325     fn new_as_binder(
326         channel: Arc<Mutex<T>>,
327         op_handle: i64,
328     ) -> binder::Strong<dyn keymint::IKeyMintOperation::IKeyMintOperation> {
329         let op = Self { channel, op_handle: RwLock::new(Some(op_handle)) };
330         keymint::IKeyMintOperation::BnKeyMintOperation::new_binder(
331             op,
332             binder::BinderFeatures::default(),
333         )
334     }
335 }
336 
337 impl<T: SerializedChannel> Operation<T> {
338     // Maximum size allowed for the operation data.
339     const MAX_DATA_SIZE: usize = T::MAX_SIZE - MAX_CBOR_OVERHEAD;
340 
341     /// Invalidate the operation.
invalidate(&self)342     fn invalidate(&self) {
343         *self.op_handle.write().unwrap() = None;
344     }
345 
346     /// Retrieve the operation handle, if not already failed.
validate_handle(&self) -> binder::Result<i64>347     fn validate_handle(&self) -> binder::Result<i64> {
348         self.op_handle.read().unwrap().ok_or_else(|| {
349             binder::Status::new_service_specific_error(
350                 keymint::ErrorCode::ErrorCode::INVALID_OPERATION_HANDLE.0,
351                 Some(&CString::new("Operation handle not valid").unwrap()),
352             )
353         })
354     }
355 }
356 
357 /// Implement the `IKeyMintOperation` interface for a [`Operation`].  Each method invocation is
358 /// serialized into a request message that is sent over the `Operation`'s channel, and a
359 /// corresponding response message is read.  This response message is deserialized back into the
360 /// method's output value(s).
361 impl<T: SerializedChannel + 'static> keymint::IKeyMintOperation::IKeyMintOperation
362     for Operation<T>
363 {
updateAad( &self, mut input: &[u8], authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>, timeStampToken: Option<&TimeStampToken>, ) -> binder::Result<()>364     fn updateAad(
365         &self,
366         mut input: &[u8],
367         authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>,
368         timeStampToken: Option<&TimeStampToken>,
369     ) -> binder::Result<()> {
370         let req_template = UpdateAadRequest {
371             op_handle: self.validate_handle()?,
372             input: vec![],
373             auth_token: match authToken {
374                 None => None,
375                 Some(t) => Some(t.clone().try_innto().map_err(failed_conversion)?),
376             },
377             timestamp_token: timeStampToken.map(|t| t.clone().innto()),
378         };
379         while !input.is_empty() {
380             let mut req = req_template.clone();
381             let batch_len = core::cmp::min(Self::MAX_DATA_SIZE, input.len());
382             req.input = input[..batch_len].to_vec();
383             input = &input[batch_len..];
384             let _rsp: UpdateAadResponse = self.execute(req).map_err(|e| {
385                 // Any failure invalidates the operation
386                 self.invalidate();
387                 e
388             })?;
389         }
390         Ok(())
391     }
update( &self, mut input: &[u8], authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>, timeStampToken: Option<&TimeStampToken>, ) -> binder::Result<Vec<u8>>392     fn update(
393         &self,
394         mut input: &[u8],
395         authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>,
396         timeStampToken: Option<&TimeStampToken>,
397     ) -> binder::Result<Vec<u8>> {
398         let req_template = UpdateRequest {
399             op_handle: self.validate_handle()?,
400             input: input.to_vec(),
401             auth_token: match authToken {
402                 None => None,
403                 Some(t) => Some(t.clone().try_innto().map_err(failed_conversion)?),
404             },
405             timestamp_token: timeStampToken.map(|t| t.clone().innto()),
406         };
407         let mut output = vec![];
408         while !input.is_empty() {
409             let mut req = req_template.clone();
410             let batch_len = core::cmp::min(Self::MAX_DATA_SIZE, input.len());
411             req.input = input[..batch_len].to_vec();
412             input = &input[batch_len..];
413             let rsp: UpdateResponse = self.execute(req).map_err(|e| {
414                 self.invalidate();
415                 e
416             })?;
417             output.extend_from_slice(&rsp.ret);
418         }
419         Ok(output)
420     }
finish( &self, input: Option<&[u8]>, signature: Option<&[u8]>, authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>, timestampToken: Option<&TimeStampToken>, confirmationToken: Option<&[u8]>, ) -> binder::Result<Vec<u8>>421     fn finish(
422         &self,
423         input: Option<&[u8]>,
424         signature: Option<&[u8]>,
425         authToken: Option<&keymint::HardwareAuthToken::HardwareAuthToken>,
426         timestampToken: Option<&TimeStampToken>,
427         confirmationToken: Option<&[u8]>,
428     ) -> binder::Result<Vec<u8>> {
429         let op_handle = self.validate_handle()?;
430         let auth_token = match authToken {
431             None => None,
432             Some(t) => Some(t.clone().try_innto().map_err(failed_conversion)?),
433         };
434         let timestamp_token = timestampToken.map(|t| t.clone().innto());
435         let confirmation_token = confirmationToken.map(|v| v.to_vec());
436 
437         let mut output = vec![];
438         let result: binder::Result<FinishResponse> = if let Some(mut input) = input {
439             let MAX_DATA_SIZE = Self::MAX_DATA_SIZE;
440             while input.len() > MAX_DATA_SIZE {
441                 let req = UpdateRequest {
442                     op_handle,
443                     input: input[..MAX_DATA_SIZE].to_vec(),
444                     auth_token: auth_token.clone(),
445                     timestamp_token: timestamp_token.clone(),
446                 };
447                 input = &input[MAX_DATA_SIZE..];
448                 let rsp: UpdateResponse = self.execute(req).map_err(|e| {
449                     self.invalidate();
450                     e
451                 })?;
452                 output.extend_from_slice(&rsp.ret);
453             }
454 
455             self.execute(FinishRequest {
456                 op_handle,
457                 input: Some(input.to_vec()),
458                 signature: signature.map(|v| v.to_vec()),
459                 auth_token,
460                 timestamp_token,
461                 confirmation_token,
462             })
463         } else {
464             self.execute(FinishRequest {
465                 op_handle,
466                 input: None,
467                 signature: signature.map(|v| v.to_vec()),
468                 auth_token,
469                 timestamp_token,
470                 confirmation_token,
471             })
472         };
473         // Finish always invalidates the operation.
474         self.invalidate();
475         result.map(|rsp| {
476             output.extend_from_slice(&rsp.ret);
477             output
478         })
479     }
abort(&self) -> binder::Result<()>480     fn abort(&self) -> binder::Result<()> {
481         let result: binder::Result<AbortResponse> =
482             self.execute(AbortRequest { op_handle: self.validate_handle()? });
483         // Abort always invalidates the operation.
484         self.invalidate();
485         let _ = result?;
486         Ok(())
487     }
488 }
489