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