• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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