1 /* 2 * Copyright (C) 2024 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 17 //! Module providing a shim for the different crypto operations. 18 19 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{ 20 HmacOperationParameters::HmacOperationParameters, KeyUse::KeyUse, 21 SymmetricCryptoParameters::SymmetricCryptoParameters, SymmetricOperation::SymmetricOperation, 22 }; 23 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::{ 24 OperationParameters::OperationParameters, PatternParameters::PatternParameters, 25 }; 26 use hwcryptohal_common::{err::HwCryptoError, hwcrypto_err}; 27 use kmr_common::crypto::{ 28 self, Aes, Hmac, KeyMaterial, SymmetricOperation as CryptoSymmetricOperation, 29 }; 30 31 use crate::cmd_processing::DataToProcess; 32 use crate::crypto_provider; 33 use crate::helpers; 34 use crate::opaque_key::OpaqueKey; 35 36 // Pattern for cbcs operations. cbcs is based on partially encryption using AES-CBC as defined in 37 // IEC 23001-7:2016 38 enum CbcsPattern { 39 Protected(usize), 40 Clear(usize), 41 } 42 43 struct CbcsPatternParams { 44 num_encrypted_bytes: usize, 45 num_clear_bytes: usize, 46 current_pattern: CbcsPattern, 47 } 48 49 impl CbcsPatternParams { new(pattern_parameters: &PatternParameters) -> Result<Self, HwCryptoError>50 fn new(pattern_parameters: &PatternParameters) -> Result<Self, HwCryptoError> { 51 let mut num_encrypted_blocks: usize = 52 pattern_parameters.numberBlocksProcess.try_into().map_err(|e| { 53 hwcrypto_err!(BAD_PARAMETER, "number encrypted blocks cannot be negative: {:?}", e) 54 })?; 55 let num_clear_blocks: usize = 56 pattern_parameters.numberBlocksCopy.try_into().map_err(|e| { 57 hwcrypto_err!(BAD_PARAMETER, "number clear blocks cannot be negative: {:?}", e) 58 })?; 59 // Special case. Some encoders pass a 0,0 to represent full sample encryption. Treating it 60 // the same as 1, 0. 61 if (num_encrypted_blocks == 0) && (num_clear_blocks == 0) { 62 num_encrypted_blocks = 1; 63 } 64 let num_encrypted_bytes = num_encrypted_blocks 65 .checked_mul(crypto::aes::BLOCK_SIZE) 66 .ok_or(hwcrypto_err!(BAD_PARAMETER, "number encrypted blocks was too high"))?; 67 let num_clear_bytes = num_clear_blocks 68 .checked_mul(crypto::aes::BLOCK_SIZE) 69 .ok_or(hwcrypto_err!(BAD_PARAMETER, "number clear blocks was too high"))?; 70 // Patterns starts with a number of protected blocks 71 let current_pattern = CbcsPattern::Protected(num_encrypted_bytes); 72 Ok(Self { num_encrypted_bytes, num_clear_bytes, current_pattern }) 73 } 74 } 75 76 pub(crate) trait ICryptographicOperation: Send { 77 // Returns the required minimum size in bytes the output buffer needs to have for the given 78 // `input` get_operation_req_size( &self, input: Option<&DataToProcess>, is_finish: bool, ) -> Result<usize, HwCryptoError>79 fn get_operation_req_size( 80 &self, 81 input: Option<&DataToProcess>, 82 is_finish: bool, 83 ) -> Result<usize, HwCryptoError>; 84 operation<'a>( &mut self, input: Option<&mut DataToProcess<'a>>, output: &mut DataToProcess<'a>, is_finish: bool, ) -> Result<usize, HwCryptoError>85 fn operation<'a>( 86 &mut self, 87 input: Option<&mut DataToProcess<'a>>, 88 output: &mut DataToProcess<'a>, 89 is_finish: bool, 90 ) -> Result<usize, HwCryptoError>; 91 is_active(&self) -> bool92 fn is_active(&self) -> bool; 93 is_valid(&self) -> bool94 fn is_valid(&self) -> bool; 95 96 #[allow(dead_code)] update_aad(&mut self, _input: &DataToProcess) -> Result<(), HwCryptoError>97 fn update_aad(&mut self, _input: &DataToProcess) -> Result<(), HwCryptoError> { 98 Err(hwcrypto_err!( 99 BAD_PARAMETER, 100 "update aad only valid for authenticated symmetric operations" 101 )) 102 } 103 set_operation_pattern( &mut self, _patter_parameter: &PatternParameters, ) -> Result<(), HwCryptoError>104 fn set_operation_pattern( 105 &mut self, 106 _patter_parameter: &PatternParameters, 107 ) -> Result<(), HwCryptoError> { 108 Err(hwcrypto_err!(BAD_PARAMETER, "set_operation_pattern only supported for AES CBC")) 109 } 110 } 111 112 trait IBaseCryptoOperation: Send { update<'a>( &mut self, input: &mut DataToProcess<'a>, output: &mut DataToProcess<'a>, ) -> Result<usize, HwCryptoError>113 fn update<'a>( 114 &mut self, 115 input: &mut DataToProcess<'a>, 116 output: &mut DataToProcess<'a>, 117 ) -> Result<usize, HwCryptoError>; 118 finish(&mut self, output: &mut DataToProcess) -> Result<usize, HwCryptoError>119 fn finish(&mut self, output: &mut DataToProcess) -> Result<usize, HwCryptoError>; 120 get_req_size_finish(&self) -> Result<usize, HwCryptoError>121 fn get_req_size_finish(&self) -> Result<usize, HwCryptoError>; 122 get_req_size_update(&self, input: &DataToProcess) -> Result<usize, HwCryptoError>123 fn get_req_size_update(&self, input: &DataToProcess) -> Result<usize, HwCryptoError>; 124 is_active(&self) -> bool125 fn is_active(&self) -> bool; 126 is_valid(&self) -> bool127 fn is_valid(&self) -> bool; 128 update_aad(&mut self, _input: &DataToProcess) -> Result<(), HwCryptoError>129 fn update_aad(&mut self, _input: &DataToProcess) -> Result<(), HwCryptoError> { 130 Err(hwcrypto_err!( 131 BAD_PARAMETER, 132 "update aad only valid for authenticated symmetric operations" 133 )) 134 } 135 set_operation_pattern( &mut self, patter_parameter: &PatternParameters, ) -> Result<(), HwCryptoError>136 fn set_operation_pattern( 137 &mut self, 138 patter_parameter: &PatternParameters, 139 ) -> Result<(), HwCryptoError>; 140 } 141 142 impl<T: IBaseCryptoOperation> ICryptographicOperation for T { get_operation_req_size( &self, input: Option<&DataToProcess>, is_finish: bool, ) -> Result<usize, HwCryptoError>143 fn get_operation_req_size( 144 &self, 145 input: Option<&DataToProcess>, 146 is_finish: bool, 147 ) -> Result<usize, HwCryptoError> { 148 if is_finish { 149 self.get_req_size_finish() 150 } else { 151 let input = 152 input.ok_or_else(|| hwcrypto_err!(BAD_PARAMETER, "input was not provided"))?; 153 self.get_req_size_update(input) 154 } 155 } 156 operation<'a>( &mut self, mut input: Option<&mut DataToProcess<'a>>, output: &mut DataToProcess<'a>, is_finish: bool, ) -> Result<usize, HwCryptoError>157 fn operation<'a>( 158 &mut self, 159 mut input: Option<&mut DataToProcess<'a>>, 160 output: &mut DataToProcess<'a>, 161 is_finish: bool, 162 ) -> Result<usize, HwCryptoError> { 163 if is_finish { 164 self.finish(output) 165 } else { 166 let input = 167 input.take().ok_or(hwcrypto_err!(BAD_PARAMETER, "input was not provided"))?; 168 self.update(input, output) 169 } 170 } 171 is_active(&self) -> bool172 fn is_active(&self) -> bool { 173 self.is_active() 174 } 175 is_valid(&self) -> bool176 fn is_valid(&self) -> bool { 177 self.is_valid() 178 } 179 update_aad(&mut self, input: &DataToProcess) -> Result<(), HwCryptoError>180 fn update_aad(&mut self, input: &DataToProcess) -> Result<(), HwCryptoError> { 181 self.update_aad(input) 182 } 183 set_operation_pattern( &mut self, patter_parameter: &PatternParameters, ) -> Result<(), HwCryptoError>184 fn set_operation_pattern( 185 &mut self, 186 patter_parameter: &PatternParameters, 187 ) -> Result<(), HwCryptoError> { 188 self.set_operation_pattern(patter_parameter) 189 } 190 } 191 192 // Newtype used because the traits we currently use for cryptographic operations cannot directly 193 // either process `VolatileSlice`s or use pointers to memory, so we need to make a copy of the data. 194 // TODO: refactor traits to not require copying the input for VolatileSlices 195 struct TempBuffer(Vec<u8>); 196 197 impl TempBuffer { new() -> Self198 fn new() -> Self { 199 TempBuffer(Vec::new()) 200 } 201 read_into_buffer_reference<'a>( &'a mut self, input: &'a mut DataToProcess, len: Option<usize>, ) -> Result<&'a [u8], HwCryptoError>202 fn read_into_buffer_reference<'a>( 203 &'a mut self, 204 input: &'a mut DataToProcess, 205 len: Option<usize>, 206 ) -> Result<&'a [u8], HwCryptoError> { 207 let len = len.unwrap_or(input.len()); 208 if len > input.len() { 209 return Err(hwcrypto_err!( 210 BAD_PARAMETER, 211 "end {} out of slice bounds for slice size {}", 212 len, 213 input.len() 214 )); 215 } 216 217 if !input.is_non_volatile_slice_backed() { 218 let slice = input.try_slice(len)?; 219 Ok(slice) 220 } else { 221 self.0.clear(); 222 self.0.try_reserve(len)?; 223 // Addition should be safe because try_reserve didn't fail 224 self.0.resize_with(len, Default::default); 225 input.read_into_slice(self.0.as_mut_slice(), Some(len))?; 226 Ok(&self.0[..]) 227 } 228 } 229 } 230 231 pub(crate) struct HmacOperation { 232 opaque_key: OpaqueKey, 233 accumulating_op: Option<Box<dyn crypto::AccumulatingOperation>>, 234 } 235 236 impl HmacOperation { new(parameters: &HmacOperationParameters) -> Result<Self, HwCryptoError>237 fn new(parameters: &HmacOperationParameters) -> Result<Self, HwCryptoError> { 238 let opaque_key: OpaqueKey = parameters 239 .key 240 .as_ref() 241 .ok_or(hwcrypto_err!(BAD_PARAMETER, "hmac key not provided"))? 242 .try_into()?; 243 Self::check_parameters(&opaque_key, parameters)?; 244 let digest = helpers::aidl_to_rust_digest(&opaque_key.get_key_type())?; 245 let hmac = crypto_provider::HmacImpl; 246 let accumulating_op = match opaque_key.key_material { 247 KeyMaterial::Hmac(ref key) => hmac.begin(key.clone(), digest).map_err(|e| { 248 hwcrypto_err!(GENERIC_ERROR, "couldn't begin hmac operation: {:?}", e) 249 }), 250 _ => Err(hwcrypto_err!(BAD_PARAMETER, "Invalid key type for HMAC operation")), 251 }?; 252 Ok(HmacOperation { opaque_key, accumulating_op: Some(accumulating_op) }) 253 } 254 check_parameters( opaque_key: &OpaqueKey, _parameters: &HmacOperationParameters, ) -> Result<(), HwCryptoError>255 fn check_parameters( 256 opaque_key: &OpaqueKey, 257 _parameters: &HmacOperationParameters, 258 ) -> Result<(), HwCryptoError> { 259 if !opaque_key.key_usage_supported(KeyUse::SIGN) { 260 return Err(hwcrypto_err!(BAD_PARAMETER, "Provided key cannot be used for signing")); 261 } 262 opaque_key.expiration_time_valid()?; 263 match &opaque_key.key_material { 264 KeyMaterial::Hmac(_) => Ok(()), 265 _ => Err(hwcrypto_err!(BAD_PARAMETER, "Invalid key type for HMAC operation")), 266 } 267 } 268 } 269 270 impl IBaseCryptoOperation for HmacOperation { get_req_size_update(&self, _input: &DataToProcess) -> Result<usize, HwCryptoError>271 fn get_req_size_update(&self, _input: &DataToProcess) -> Result<usize, HwCryptoError> { 272 Ok(0) 273 } 274 get_req_size_finish(&self) -> Result<usize, HwCryptoError>275 fn get_req_size_finish(&self) -> Result<usize, HwCryptoError> { 276 Ok(crypto_provider::HMAC_MAX_SIZE) 277 } 278 update( &mut self, input: &mut DataToProcess, _output: &mut DataToProcess, ) -> Result<usize, HwCryptoError>279 fn update( 280 &mut self, 281 input: &mut DataToProcess, 282 _output: &mut DataToProcess, 283 ) -> Result<usize, HwCryptoError> { 284 let op = self 285 .accumulating_op 286 .as_mut() 287 .ok_or(hwcrypto_err!(BAD_STATE, "operation was already finished"))?; 288 // TODO: refactor traits to not require copying the input for VolatileSlices 289 let mut input_buffer = TempBuffer::new(); 290 let input_data = input_buffer.read_into_buffer_reference(input, None)?; 291 op.update(input_data)?; 292 Ok(0) 293 } 294 finish(&mut self, output: &mut DataToProcess) -> Result<usize, HwCryptoError>295 fn finish(&mut self, output: &mut DataToProcess) -> Result<usize, HwCryptoError> { 296 let op = self 297 .accumulating_op 298 .take() 299 .ok_or(hwcrypto_err!(BAD_STATE, "operation was already finished"))?; 300 let req_size = self.get_req_size_finish()?; 301 if output.len() != req_size { 302 return Err(hwcrypto_err!(BAD_PARAMETER, "input size was not {}", req_size)); 303 } 304 let output_data = op.finish()?; 305 let output_len = output_data.len(); 306 output.append_slice(output_data.as_slice())?; 307 Ok(output_len) 308 } 309 is_active(&self) -> bool310 fn is_active(&self) -> bool { 311 self.accumulating_op.is_some() 312 } 313 is_valid(&self) -> bool314 fn is_valid(&self) -> bool { 315 self.opaque_key.expiration_time_valid().is_ok() 316 } 317 set_operation_pattern( &mut self, _patter_parameter: &PatternParameters, ) -> Result<(), HwCryptoError>318 fn set_operation_pattern( 319 &mut self, 320 _patter_parameter: &PatternParameters, 321 ) -> Result<(), HwCryptoError> { 322 Err(hwcrypto_err!(BAD_PARAMETER, "set_operation_pattern only supported for AES CBC")) 323 } 324 } 325 326 pub(crate) struct AesOperation { 327 opaque_key: OpaqueKey, 328 emitting_op: Option<Box<dyn crypto::EmittingOperation>>, 329 dir: CryptoSymmetricOperation, 330 remaining_unaligned_data_size: usize, 331 block_based_encryption: bool, 332 cbcs_pattern: Option<CbcsPatternParams>, 333 operation_started: bool, 334 } 335 336 impl AesOperation { new( opaque_key: OpaqueKey, dir: SymmetricOperation, parameters: &SymmetricCryptoParameters, ) -> Result<Self, HwCryptoError>337 fn new( 338 opaque_key: OpaqueKey, 339 dir: SymmetricOperation, 340 parameters: &SymmetricCryptoParameters, 341 ) -> Result<Self, HwCryptoError> { 342 AesOperation::check_cipher_parameters(&opaque_key, dir, parameters)?; 343 let key_material = &opaque_key.key_material; 344 let dir = helpers::aidl_to_rust_symmetric_direction(dir)?; 345 let emitting_op = match key_material { 346 KeyMaterial::Aes(key) => { 347 let aes = crypto_provider::AesImpl; 348 let mode = helpers::aidl_to_rust_aes_cipher_params(parameters, &opaque_key)?; 349 aes.begin(key.clone(), mode, dir).map_err(|e| { 350 hwcrypto_err!(GENERIC_ERROR, "couldn't begin aes operation: {:?}", e) 351 }) 352 } 353 _ => Err(hwcrypto_err!(BAD_PARAMETER, "Invalid key type for AES symmetric operation")), 354 }?; 355 let block_based_encryption = helpers::symmetric_encryption_block_based(parameters)?; 356 let aes_operation = Self { 357 opaque_key, 358 emitting_op: Some(emitting_op), 359 dir, 360 remaining_unaligned_data_size: 0, 361 block_based_encryption, 362 cbcs_pattern: None, 363 operation_started: false, 364 }; 365 Ok(aes_operation) 366 } 367 check_cipher_parameters( opaque_key: &OpaqueKey, dir: SymmetricOperation, parameters: &SymmetricCryptoParameters, ) -> Result<(), HwCryptoError>368 fn check_cipher_parameters( 369 opaque_key: &OpaqueKey, 370 dir: SymmetricOperation, 371 parameters: &SymmetricCryptoParameters, 372 ) -> Result<(), HwCryptoError> { 373 opaque_key.expiration_time_valid()?; 374 opaque_key.symmetric_operation_is_compatible(dir)?; 375 opaque_key.parameters_are_compatible_symmetric_cipher(parameters) 376 } 377 378 // Returns the size required to process the current block and how much extra data was cached for 379 // a future call get_update_req_size_with_remainder( &self, input: &DataToProcess, ) -> Result<(usize, usize), HwCryptoError>380 fn get_update_req_size_with_remainder( 381 &self, 382 input: &DataToProcess, 383 ) -> Result<(usize, usize), HwCryptoError> { 384 let input_size = input.len(); 385 self.get_req_size_from_len(input_size) 386 } 387 get_req_size_from_len(&self, input_len: usize) -> Result<(usize, usize), HwCryptoError>388 fn get_req_size_from_len(&self, input_len: usize) -> Result<(usize, usize), HwCryptoError> { 389 if self.block_based_encryption { 390 match self.dir { 391 CryptoSymmetricOperation::Encrypt => { 392 let input_size = input_len + self.remaining_unaligned_data_size; 393 let extra_data_len = input_size % crypto::aes::BLOCK_SIZE; 394 Ok((input_size - extra_data_len, extra_data_len)) 395 } 396 CryptoSymmetricOperation::Decrypt => { 397 Ok((AesOperation::round_to_block_size(input_len), 0)) 398 } 399 } 400 } else { 401 Ok((input_len, 0)) 402 } 403 } 404 round_to_block_size(size: usize) -> usize405 fn round_to_block_size(size: usize) -> usize { 406 ((size + crypto::aes::BLOCK_SIZE - 1) / crypto::aes::BLOCK_SIZE) * crypto::aes::BLOCK_SIZE 407 } 408 cbcs_update<'a>( &mut self, input: &mut DataToProcess<'a>, output: &mut DataToProcess<'a>, ) -> Result<usize, HwCryptoError>409 fn cbcs_update<'a>( 410 &mut self, 411 input: &mut DataToProcess<'a>, 412 output: &mut DataToProcess<'a>, 413 ) -> Result<usize, HwCryptoError> { 414 let mut total_pattern_size = input.len(); 415 let unencrypted_bytes_last_block = total_pattern_size % crypto::aes::BLOCK_SIZE; 416 if unencrypted_bytes_last_block != 0 { 417 // on cbcs if there are remainders on the last block, then those need to be directly 418 // copied, they will be unencrypted 419 total_pattern_size -= unencrypted_bytes_last_block; 420 } 421 if output.len() != input.len() { 422 return Err(hwcrypto_err!(BAD_PARAMETER, "output size was not {}", input.len())); 423 } 424 let cbcs_pattern = self 425 .cbcs_pattern 426 .as_mut() 427 .ok_or(hwcrypto_err!(BAD_PARAMETER, "not a cbcs operation"))?; 428 // TODO: refactor to remove need of input copy for memory slices 429 let mut input_buff = TempBuffer::new(); 430 let mut remaining_len = total_pattern_size; 431 let aes_op = self 432 .emitting_op 433 .as_mut() 434 .ok_or(hwcrypto_err!(BAD_STATE, "operation was already finished"))?; 435 while remaining_len > 0 { 436 match cbcs_pattern.current_pattern { 437 CbcsPattern::Protected(num_encrypted_bytes) => { 438 let encrypted_bytes = std::cmp::min(remaining_len, num_encrypted_bytes); 439 let input_data = 440 input_buff.read_into_buffer_reference(input, Some(encrypted_bytes))?; 441 let output_data = aes_op.update(input_data)?; 442 output.append_slice(output_data.as_slice())?; 443 if remaining_len > num_encrypted_bytes { 444 // There is still data to process, advance index and change pattern to clear 445 // In this case encrypted_bytes == num_encrypted_bytes 446 cbcs_pattern.current_pattern = 447 CbcsPattern::Clear(cbcs_pattern.num_clear_bytes); 448 } else { 449 // We processed all available data, check if we should change pattern or 450 // keep the same 451 if num_encrypted_bytes > remaining_len { 452 // We are still on the protected pattern area 453 cbcs_pattern.current_pattern = 454 CbcsPattern::Protected(num_encrypted_bytes - remaining_len); 455 } else { 456 // We need to switch to a clear area 457 cbcs_pattern.current_pattern = 458 CbcsPattern::Clear(cbcs_pattern.num_clear_bytes); 459 } 460 break; 461 } 462 remaining_len -= num_encrypted_bytes; 463 } 464 CbcsPattern::Clear(num_clear_bytes) => { 465 let clear_bytes = std::cmp::min(remaining_len, num_clear_bytes); 466 output.read_from_slice(input, Some(clear_bytes))?; 467 if remaining_len > num_clear_bytes { 468 // There is still data to process, advance index and change pattern to 469 // protected. In this case clear_bytes == num_clear_bytes 470 cbcs_pattern.current_pattern = 471 CbcsPattern::Protected(cbcs_pattern.num_encrypted_bytes); 472 } else { 473 // We processed all available data, check if we should change pattern or 474 // keep the same 475 if num_clear_bytes > remaining_len { 476 // We are still on the clear pattern area 477 cbcs_pattern.current_pattern = 478 CbcsPattern::Clear(num_clear_bytes - remaining_len); 479 } else { 480 // We need to switch to a protected area 481 cbcs_pattern.current_pattern = 482 CbcsPattern::Protected(cbcs_pattern.num_encrypted_bytes); 483 } 484 break; 485 } 486 remaining_len -= num_clear_bytes; 487 } 488 } 489 } 490 if unencrypted_bytes_last_block != 0 { 491 output.read_from_slice(input, Some(unencrypted_bytes_last_block))?; 492 } 493 Ok(total_pattern_size + unencrypted_bytes_last_block) 494 } 495 } 496 497 impl IBaseCryptoOperation for AesOperation { update<'a>( &mut self, input: &mut DataToProcess<'a>, output: &mut DataToProcess<'a>, ) -> Result<usize, HwCryptoError>498 fn update<'a>( 499 &mut self, 500 input: &mut DataToProcess<'a>, 501 output: &mut DataToProcess<'a>, 502 ) -> Result<usize, HwCryptoError> { 503 self.operation_started = true; 504 if self.cbcs_pattern.is_some() { 505 return self.cbcs_update(input, output); 506 } 507 let (req_size, unaligned_size) = self.get_update_req_size_with_remainder(&input)?; 508 if output.len() != req_size { 509 return Err(hwcrypto_err!(BAD_PARAMETER, "input size was not {}", req_size)); 510 } 511 let op = self 512 .emitting_op 513 .as_mut() 514 .ok_or(hwcrypto_err!(BAD_STATE, "operation was already finished"))?; 515 // TODO: refactor traits to not require copying the input for VolatileSlices 516 let mut input_buffer = TempBuffer::new(); 517 let input_data = input_buffer.read_into_buffer_reference(input, None)?; 518 let output_data = op.update(input_data)?; 519 let output_len = output_data.len(); 520 output.append_slice(output_data.as_slice())?; 521 self.remaining_unaligned_data_size = unaligned_size; 522 Ok(output_len) 523 } 524 finish(&mut self, output: &mut DataToProcess) -> Result<usize, HwCryptoError>525 fn finish(&mut self, output: &mut DataToProcess) -> Result<usize, HwCryptoError> { 526 let op = self 527 .emitting_op 528 .take() 529 .ok_or(hwcrypto_err!(BAD_STATE, "operation was already finished"))?; 530 let req_size = self.get_req_size_finish()?; 531 if output.len() != req_size { 532 return Err(hwcrypto_err!(BAD_PARAMETER, "input size was not {}", req_size)); 533 } 534 let output_data = op.finish()?; 535 let output_len = output_data.len(); 536 output.append_slice(output_data.as_slice())?; 537 self.remaining_unaligned_data_size = 0; 538 self.operation_started = false; 539 Ok(output_len) 540 } 541 update_aad(&mut self, _input: &DataToProcess) -> Result<(), HwCryptoError>542 fn update_aad(&mut self, _input: &DataToProcess) -> Result<(), HwCryptoError> { 543 unimplemented!("GCM AES note supported yet"); 544 } 545 get_req_size_finish(&self) -> Result<usize, HwCryptoError>546 fn get_req_size_finish(&self) -> Result<usize, HwCryptoError> { 547 if self.cbcs_pattern.is_some() { 548 // On CBCS patterns we do not have more data to write on finish, because there is no 549 // padding needed and all operations were done using block boundaries. 550 Ok(0) 551 } else { 552 let (req_size_to_process, _) = self.get_req_size_from_len(0)?; 553 match self.dir { 554 CryptoSymmetricOperation::Encrypt => { 555 Ok(req_size_to_process + crypto::aes::BLOCK_SIZE) 556 } 557 CryptoSymmetricOperation::Decrypt => Ok(crypto::aes::BLOCK_SIZE), 558 } 559 } 560 } 561 get_req_size_update(&self, input: &DataToProcess) -> Result<usize, HwCryptoError>562 fn get_req_size_update(&self, input: &DataToProcess) -> Result<usize, HwCryptoError> { 563 if self.cbcs_pattern.is_some() { 564 // On CBCS patterns we are currently processing all the input at once (remaining bytes 565 // that are not multiples of a block are copied unencrypted) so the space needed is 566 // always the size of the input. 567 Ok(input.len()) 568 } else { 569 let (req_size, _) = self.get_update_req_size_with_remainder(input)?; 570 Ok(req_size) 571 } 572 } 573 is_active(&self) -> bool574 fn is_active(&self) -> bool { 575 self.emitting_op.is_some() 576 } 577 is_valid(&self) -> bool578 fn is_valid(&self) -> bool { 579 self.opaque_key.expiration_time_valid().is_ok() 580 } 581 set_operation_pattern( &mut self, pattern_parameters: &PatternParameters, ) -> Result<(), HwCryptoError>582 fn set_operation_pattern( 583 &mut self, 584 pattern_parameters: &PatternParameters, 585 ) -> Result<(), HwCryptoError> { 586 self.opaque_key.supports_pattern_encryption()?; 587 // We only support setting a pattern if we have not started encrypting/decrypting 588 if self.operation_started { 589 return Err(hwcrypto_err!(BAD_STATE, "pattern cannot be set if operation has started")); 590 } 591 // We do not support changing an already set up pattern 592 if self.cbcs_pattern.is_some() { 593 return Err(hwcrypto_err!(BAD_STATE, "pattern has already been set")); 594 } 595 self.cbcs_pattern = Some(CbcsPatternParams::new(pattern_parameters)?); 596 Ok(()) 597 } 598 } 599 600 pub(crate) struct CopyOperation; 601 602 impl ICryptographicOperation for CopyOperation { get_operation_req_size( &self, input: Option<&DataToProcess>, _is_finish: bool, ) -> Result<usize, HwCryptoError>603 fn get_operation_req_size( 604 &self, 605 input: Option<&DataToProcess>, 606 _is_finish: bool, 607 ) -> Result<usize, HwCryptoError> { 608 let input = input.ok_or_else(|| hwcrypto_err!(BAD_PARAMETER, "input was not provided"))?; 609 Ok(input.len()) 610 } 611 operation<'a>( &mut self, input: Option<&mut DataToProcess<'a>>, output: &mut DataToProcess<'a>, _is_finish: bool, ) -> Result<usize, HwCryptoError>612 fn operation<'a>( 613 &mut self, 614 input: Option<&mut DataToProcess<'a>>, 615 output: &mut DataToProcess<'a>, 616 _is_finish: bool, 617 ) -> Result<usize, HwCryptoError> { 618 let num_bytes_copy = self.get_operation_req_size(input.as_deref(), false)?; 619 let mut input = 620 input.ok_or_else(|| hwcrypto_err!(BAD_PARAMETER, "input was not provided"))?; 621 output.read_from_slice(&mut input, None)?; 622 Ok(num_bytes_copy) 623 } 624 is_active(&self) -> bool625 fn is_active(&self) -> bool { 626 true 627 } 628 is_valid(&self) -> bool629 fn is_valid(&self) -> bool { 630 true 631 } 632 } 633 634 pub(crate) struct CryptographicOperation; 635 636 impl CryptographicOperation { new_binder( crypto_operation_parameters: &OperationParameters, ) -> Result<Box<dyn ICryptographicOperation>, HwCryptoError>637 pub(crate) fn new_binder( 638 crypto_operation_parameters: &OperationParameters, 639 ) -> Result<Box<dyn ICryptographicOperation>, HwCryptoError> { 640 match crypto_operation_parameters { 641 OperationParameters::SymmetricCrypto(symmetric_params) => { 642 if let Some(key) = &symmetric_params.key { 643 let opaque_key: OpaqueKey = key.try_into()?; 644 let dir = symmetric_params.direction; 645 let parameters = &symmetric_params.parameters; 646 AesOperation::check_cipher_parameters(&opaque_key, dir, parameters)?; 647 let aes_operation = AesOperation::new(opaque_key, dir, parameters)?; 648 Ok(Box::new(aes_operation)) 649 } else { 650 Err(hwcrypto_err!(BAD_PARAMETER, "key was null")) 651 } 652 } 653 OperationParameters::Hmac(params) => { 654 let hmac_op = HmacOperation::new(params)?; 655 Ok(Box::new(hmac_op)) 656 } 657 _ => unimplemented!("operation not implemented yet"), 658 } 659 } 660 } 661 662 // Implementing ICryptographicOperation for () to use it as a type for when we need to pass a `None` 663 // on an `Option<&impl ICryptographicOperation>` 664 impl ICryptographicOperation for () { get_operation_req_size( &self, _input: Option<&DataToProcess>, _is_finish: bool, ) -> Result<usize, HwCryptoError>665 fn get_operation_req_size( 666 &self, 667 _input: Option<&DataToProcess>, 668 _is_finish: bool, 669 ) -> Result<usize, HwCryptoError> { 670 Err(hwcrypto_err!(UNSUPPORTED, "cannot get size for null operation")) 671 } 672 operation( &mut self, _input: Option<&mut DataToProcess>, _output: &mut DataToProcess, _is_finish: bool, ) -> Result<usize, HwCryptoError>673 fn operation( 674 &mut self, 675 _input: Option<&mut DataToProcess>, 676 _output: &mut DataToProcess, 677 _is_finish: bool, 678 ) -> Result<usize, HwCryptoError> { 679 Err(hwcrypto_err!(UNSUPPORTED, "nothing to execute on null operation")) 680 } 681 is_active(&self) -> bool682 fn is_active(&self) -> bool { 683 false 684 } 685 is_valid(&self) -> bool686 fn is_valid(&self) -> bool { 687 false 688 } 689 } 690 691 #[cfg(test)] 692 mod tests { 693 use super::*; 694 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::{ 695 AesCipherMode::AesCipherMode, CipherModeParameters::CipherModeParameters, 696 KeyLifetime::KeyLifetime, 697 KeyType::KeyType, KeyUse::KeyUse, 698 SymmetricCryptoParameters::SymmetricCryptoParameters, 699 SymmetricOperation::SymmetricOperation, 700 SymmetricOperationParameters::SymmetricOperationParameters, 701 }; 702 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::{ 703 KeyPolicy::KeyPolicy, 704 }; 705 use test::{expect, expect_eq}; 706 use tipc::Uuid; 707 connection_info() -> Uuid708 fn connection_info() -> Uuid { 709 // TODO: This is a temporary mock function for testing until we move to use DICE policies. 710 Uuid::new_from_string("f41a7796-975a-4279-8cc4-b73f8820430d").unwrap() 711 } 712 713 #[test] use_aes_key()714 fn use_aes_key() { 715 let usage = KeyUse::ENCRYPT_DECRYPT; 716 let key_type = KeyType::AES_256_CBC_PKCS7_PADDING; 717 let policy = KeyPolicy { 718 usage, 719 keyLifetime: KeyLifetime::EPHEMERAL, 720 keyPermissions: Vec::new(), 721 keyType: key_type, 722 keyManagementKey: false, 723 }; 724 let handle = OpaqueKey::generate_opaque_key(&policy, connection_info()) 725 .expect("couldn't generate key"); 726 let nonce = [0u8; 16]; 727 let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters { 728 nonce: nonce.into(), 729 })); 730 let direction = SymmetricOperation::ENCRYPT; 731 let sym_op_params = 732 SymmetricOperationParameters { key: Some(handle.clone()), direction, parameters }; 733 let op_params = OperationParameters::SymmetricCrypto(sym_op_params); 734 let input_to_encrypt = "hello world1234"; 735 let mut input_data = input_to_encrypt.as_bytes().to_vec(); 736 let mut input_slice = DataToProcess::new_from_slice(&mut input_data[..]); 737 let mut op = 738 CryptographicOperation::new_binder(&op_params).expect("couldn't create aes operation"); 739 let req_size = op 740 .get_operation_req_size(Some(&input_slice), false) 741 .expect("couldn't get required_size"); 742 expect_eq!(req_size, 0, "Required size for encryptiong less than a block should be 0"); 743 let mut output_data = vec![]; 744 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[..]); 745 let written_bytes = op 746 .operation(Some(&mut input_slice), &mut output_slice, false) 747 .expect("couldn't update"); 748 expect_eq!(written_bytes, 0, "Written bytes for encryptiong less than a block should be 0"); 749 let req_size_finish = 750 op.get_operation_req_size(None, true).expect("couldn't get required_size"); 751 expect_eq!( 752 req_size_finish, 753 16, 754 "Required size for encryptiong less than a block should be a block" 755 ); 756 output_data.append(&mut vec![0u8; 16]); 757 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[..]); 758 op.operation(None, &mut output_slice, true).expect("couldn't finish"); 759 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[0..0]); 760 let mut input_slice = DataToProcess::new_from_slice(&mut input_data[..]); 761 let update_op = op.operation(Some(&mut input_slice), &mut output_slice, false); 762 expect!(update_op.is_err(), "shouldn't be able to run operations anymore"); 763 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[0..0]); 764 let finish_op = op.operation(None, &mut output_slice, true); 765 expect!(finish_op.is_err(), "shouldn't be able to run operations anymore"); 766 let direction = SymmetricOperation::DECRYPT; 767 let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters { 768 nonce: nonce.into(), 769 })); 770 let sym_op_params = 771 SymmetricOperationParameters { key: Some(handle), direction, parameters }; 772 let op_params = OperationParameters::SymmetricCrypto(sym_op_params); 773 let mut op = 774 CryptographicOperation::new_binder(&op_params).expect("couldn't create aes operation"); 775 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[..]); 776 let req_size = op 777 .get_operation_req_size(Some(&output_slice), false) 778 .expect("couldn't get required_size"); 779 let mut decrypted_data = vec![0; req_size]; 780 let mut decrypted_slice = DataToProcess::new_from_slice(&mut decrypted_data[..]); 781 let mut decrypted_data_size = op 782 .operation(Some(&mut output_slice), &mut decrypted_slice, false) 783 .expect("couldn't update"); 784 let decrypted_data_start = decrypted_data_size; 785 let req_size_finish = 786 op.get_operation_req_size(None, true).expect("couldn't get required_size"); 787 let decrypted_data_end = decrypted_data_size + req_size_finish; 788 let mut decrypted_slice = DataToProcess::new_from_slice( 789 &mut decrypted_data[decrypted_data_start..decrypted_data_end], 790 ); 791 let total_finish_size = 792 op.operation(None, &mut decrypted_slice, true).expect("couldn't finish"); 793 decrypted_data_size += total_finish_size; 794 decrypted_data.truncate(decrypted_data_size); 795 expect_eq!(input_to_encrypt.len(), decrypted_data_size, "bad length for decrypted data"); 796 let decrypted_str = String::from_utf8(decrypted_data).unwrap(); 797 expect_eq!(input_to_encrypt, decrypted_str, "bad data decrypted"); 798 } 799 800 #[test] process_aes_encrypt_decrypt_operations()801 fn process_aes_encrypt_decrypt_operations() { 802 let usage = KeyUse::ENCRYPT_DECRYPT; 803 let key_type = KeyType::AES_256_CBC_PKCS7_PADDING; 804 let policy = KeyPolicy { 805 usage, 806 keyLifetime: KeyLifetime::EPHEMERAL, 807 keyPermissions: Vec::new(), 808 keyType: key_type, 809 keyManagementKey: false, 810 }; 811 let handle = OpaqueKey::generate_opaque_key(&policy, connection_info()) 812 .expect("couldn't generate key"); 813 let nonce = [0u8; 16]; 814 let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters { 815 nonce: nonce.into(), 816 })); 817 let direction = SymmetricOperation::ENCRYPT; 818 let sym_op_params = 819 SymmetricOperationParameters { key: Some(handle.clone()), direction, parameters }; 820 let op_params = OperationParameters::SymmetricCrypto(sym_op_params); 821 let mut op = 822 CryptographicOperation::new_binder(&op_params).expect("couldn't create aes operation"); 823 let input_to_encrypt = "test encryption string"; 824 let mut input_data = input_to_encrypt.as_bytes().to_vec(); 825 let mut input_slice = DataToProcess::new_from_slice(&mut input_data[..]); 826 let req_size = op 827 .get_operation_req_size(Some(&input_slice), false) 828 .expect("couldn't get required_size"); 829 expect_eq!(req_size, 16, "Implementation should try to encrypt a block in this case"); 830 let mut output_data = vec![0; 200]; 831 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[..req_size]); 832 let mut total_encryption_size = 0; 833 let written_bytes = op 834 .operation(Some(&mut input_slice), &mut output_slice, false) 835 .expect("couldn't update"); 836 total_encryption_size += written_bytes; 837 expect_eq!(written_bytes, 16, "A block should have been encrypted"); 838 let input_to_encrypt_2 = " for this "; 839 let mut input_data = input_to_encrypt_2.as_bytes().to_vec(); 840 let mut input_slice = DataToProcess::new_from_slice(&mut input_data[..]); 841 let req_size = op 842 .get_operation_req_size(Some(&input_slice), false) 843 .expect("couldn't get required_size"); 844 let output_start = written_bytes; 845 let output_stop = written_bytes + req_size; 846 expect_eq!(req_size, 16, "Implementation should try to encrypt a block in this case"); 847 let mut output_slice = 848 DataToProcess::new_from_slice(&mut output_data[output_start..output_stop]); 849 let written_bytes = op 850 .operation(Some(&mut input_slice), &mut output_slice, false) 851 .expect("couldn't update"); 852 expect_eq!(written_bytes, 16, "A block should have been encrypted"); 853 total_encryption_size += written_bytes; 854 let output_start = output_start + written_bytes; 855 let input_to_encrypt_3 = "test"; 856 let mut input_data = input_to_encrypt_3.as_bytes().to_vec(); 857 let mut input_slice = DataToProcess::new_from_slice(&mut input_data[..]); 858 let req_size = op 859 .get_operation_req_size(Some(&input_slice), false) 860 .expect("couldn't get required_size"); 861 expect_eq!(req_size, 0, "Required size for encryptiong less than a block should be 0"); 862 let mut output_slice = 863 DataToProcess::new_from_slice(&mut output_data[output_start..output_start]); 864 let written_bytes = op 865 .operation(Some(&mut input_slice), &mut output_slice, false) 866 .expect("couldn't update"); 867 total_encryption_size += written_bytes; 868 expect_eq!(written_bytes, 0, "No bytes should have been written"); 869 let input_to_encrypt_4 = " is"; 870 let mut input_data = input_to_encrypt_4.as_bytes().to_vec(); 871 let mut input_slice = DataToProcess::new_from_slice(&mut input_data[..]); 872 let req_size = op 873 .get_operation_req_size(Some(&input_slice), false) 874 .expect("couldn't get required_size"); 875 expect_eq!(req_size, 0, "Required size for encryptiong less than a block should be 0"); 876 let mut output_slice = 877 DataToProcess::new_from_slice(&mut output_data[output_start..output_start]); 878 let written_bytes = op 879 .operation(Some(&mut input_slice), &mut output_slice, false) 880 .expect("couldn't update"); 881 expect_eq!(written_bytes, 0, "No bytes should have been written"); 882 total_encryption_size += written_bytes; 883 let input_to_encrypt_5 = " a "; 884 let mut input_data = input_to_encrypt_5.as_bytes().to_vec(); 885 let mut input_slice = DataToProcess::new_from_slice(&mut input_data[..]); 886 let req_size = op 887 .get_operation_req_size(Some(&input_slice), false) 888 .expect("couldn't get required_size"); 889 expect_eq!(req_size, 0, "Required size for encryptiong less than a block should be 0"); 890 let mut output_slice = 891 DataToProcess::new_from_slice(&mut output_data[output_start..output_start]); 892 let written_bytes = op 893 .operation(Some(&mut input_slice), &mut output_slice, false) 894 .expect("couldn't update"); 895 expect_eq!(written_bytes, 0, "No bytes should have been written"); 896 total_encryption_size += written_bytes; 897 let input_to_encrypt_6 = "random one."; 898 let mut input_data = input_to_encrypt_6.as_bytes().to_vec(); 899 let mut input_slice = DataToProcess::new_from_slice(&mut input_data[..]); 900 let req_size = op 901 .get_operation_req_size(Some(&input_slice), false) 902 .expect("couldn't get required_size"); 903 expect_eq!(req_size, 16, "Implementation should try to encrypt a block in this case"); 904 let output_stop = output_start + req_size; 905 let mut output_slice = 906 DataToProcess::new_from_slice(&mut output_data[output_start..output_stop]); 907 let written_bytes = op 908 .operation(Some(&mut input_slice), &mut output_slice, false) 909 .expect("couldn't update"); 910 total_encryption_size += written_bytes; 911 expect_eq!(written_bytes, 16, "A block should have been encrypted"); 912 let output_start = output_start + written_bytes; 913 let req_size_finish = 914 op.get_operation_req_size(None, true).expect("couldn't get required_size"); 915 expect_eq!( 916 req_size_finish, 917 16, 918 "Required size for encryptiong less than a block should be a block" 919 ); 920 let output_stop = output_start + req_size_finish; 921 let mut output_slice = 922 DataToProcess::new_from_slice(&mut output_data[output_start..output_stop]); 923 let finish_written_bytes = 924 op.operation(None, &mut output_slice, true).expect("couldn't finish"); 925 expect_eq!(finish_written_bytes, 16, "With padding we should have written a block"); 926 total_encryption_size += finish_written_bytes; 927 output_data.truncate(total_encryption_size); 928 // Decrypting 929 let mut decrypted_data_size = 0; 930 let direction = SymmetricOperation::DECRYPT; 931 let parameters = SymmetricCryptoParameters::Aes(AesCipherMode::Cbc(CipherModeParameters { 932 nonce: nonce.into(), 933 })); 934 let sym_op_params = 935 SymmetricOperationParameters { key: Some(handle), direction, parameters }; 936 let op_params = OperationParameters::SymmetricCrypto(sym_op_params); 937 let mut op = 938 CryptographicOperation::new_binder(&op_params).expect("couldn't create aes operation"); 939 let mut decrypted_data = vec![0; total_encryption_size]; 940 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[..4]); 941 let req_size = op 942 .get_operation_req_size(Some(&output_slice), false) 943 .expect("couldn't get required_size"); 944 expect_eq!(req_size, 16, "worse case space for this size of input is a block"); 945 let mut decrypted_slice = DataToProcess::new_from_slice(&mut decrypted_data[..16]); 946 let written_bytes = op 947 .operation(Some(&mut output_slice), &mut decrypted_slice, false) 948 .expect("couldn't update"); 949 decrypted_data_size += written_bytes; 950 expect_eq!(written_bytes, 0, "No bytes should have been written"); 951 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[4..32]); 952 let req_size = op 953 .get_operation_req_size(Some(&output_slice), false) 954 .expect("couldn't get required_size"); 955 expect_eq!(req_size, 32, "worse case space for this size of input is 2 blocks"); 956 let mut decrypted_slice = DataToProcess::new_from_slice(&mut decrypted_data[..32]); 957 let written_bytes = op 958 .operation(Some(&mut output_slice), &mut decrypted_slice, false) 959 .expect("couldn't update"); 960 decrypted_data_size += written_bytes; 961 expect_eq!(written_bytes, 16, "One block should have been written"); 962 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[32..50]); 963 let req_size = op 964 .get_operation_req_size(Some(&output_slice), false) 965 .expect("couldn't get required_size"); 966 expect_eq!(req_size, 32, "worse case space for this size of input is 2 blocks"); 967 let mut decrypted_slice = DataToProcess::new_from_slice(&mut decrypted_data[16..48]); 968 let written_bytes = op 969 .operation(Some(&mut output_slice), &mut decrypted_slice, false) 970 .expect("couldn't update"); 971 decrypted_data_size += written_bytes; 972 expect_eq!(written_bytes, 32, "Two block should have been written"); 973 let mut output_slice = DataToProcess::new_from_slice(&mut output_data[50..64]); 974 let req_size = op 975 .get_operation_req_size(Some(&output_slice), false) 976 .expect("couldn't get required_size"); 977 expect_eq!(req_size, 16, "worse case space for this size of input is 1 block"); 978 let mut decrypted_slice = DataToProcess::new_from_slice(&mut decrypted_data[48..64]); 979 let written_bytes = op 980 .operation(Some(&mut output_slice), &mut decrypted_slice, false) 981 .expect("couldn't update"); 982 decrypted_data_size += written_bytes; 983 expect_eq!(written_bytes, 0, "No blocks should have been written"); 984 let req_size_finish = 985 op.get_operation_req_size(None, true).expect("couldn't get required_size"); 986 expect_eq!(req_size_finish, 16, "Max size required to finish should be 1 block"); 987 let mut decrypted_slice = DataToProcess::new_from_slice(&mut decrypted_data[48..64]); 988 let total_finish_size = 989 op.operation(None, &mut decrypted_slice, true).expect("couldn't finish"); 990 decrypted_data_size += total_finish_size; 991 decrypted_data.truncate(decrypted_data_size); 992 let decrypted_msg = 993 String::from_utf8(decrypted_data).expect("couldn't decode receivedd message"); 994 let original_msg = input_to_encrypt.to_owned() 995 + input_to_encrypt_2 996 + input_to_encrypt_3 997 + input_to_encrypt_4 998 + input_to_encrypt_5 999 + input_to_encrypt_6; 1000 expect_eq!(original_msg.len(), decrypted_msg.len(), "bad length for decrypted data"); 1001 expect_eq!(original_msg, decrypted_msg, "bad data decrypted"); 1002 } 1003 } 1004