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