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