• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use crate::keystore2_client_test_utils::{
16     perform_sample_sym_key_decrypt_op, perform_sample_sym_key_encrypt_op, SAMPLE_PLAIN_TEXT,
17 };
18 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
19     Algorithm::Algorithm, BlockMode::BlockMode, ErrorCode::ErrorCode, KeyPurpose::KeyPurpose,
20     PaddingMode::PaddingMode,
21 };
22 use android_system_keystore2::aidl::android::system::keystore2::{
23     Domain::Domain, KeyDescriptor::KeyDescriptor,
24 };
25 use keystore2_test_utils::{authorizations, key_generations, key_generations::Error, SecLevel};
26 
27 /// Generate a 3DES key. Create encryption and decryption operations using the generated key.
create_3des_key_and_operation( sl: &SecLevel, padding_mode: PaddingMode, block_mode: BlockMode, nonce: &mut Option<Vec<u8>>, ) -> Result<(), binder::Status>28 fn create_3des_key_and_operation(
29     sl: &SecLevel,
30     padding_mode: PaddingMode,
31     block_mode: BlockMode,
32     nonce: &mut Option<Vec<u8>>,
33 ) -> Result<(), binder::Status> {
34     let alias = format!("ks_3des_test_key_{}{}", block_mode.0, padding_mode.0);
35 
36     let key_metadata = key_generations::generate_sym_key(
37         sl,
38         Algorithm::TRIPLE_DES,
39         168,
40         &alias,
41         &padding_mode,
42         &block_mode,
43         None,
44     )?;
45 
46     // Encrypts `SAMPLE_PLAIN_TEXT` whose length is multiple of DES block size.
47     let cipher_text = perform_sample_sym_key_encrypt_op(
48         &sl.binder,
49         padding_mode,
50         block_mode,
51         nonce,
52         None,
53         &key_metadata.key,
54     )?;
55     assert!(cipher_text.is_some());
56 
57     let plain_text = perform_sample_sym_key_decrypt_op(
58         &sl.binder,
59         &cipher_text.unwrap(),
60         padding_mode,
61         block_mode,
62         nonce,
63         None,
64         &key_metadata.key,
65     )
66     .unwrap();
67     assert!(plain_text.is_some());
68     assert_eq!(plain_text.unwrap(), SAMPLE_PLAIN_TEXT.to_vec());
69     Ok(())
70 }
71 
72 /// Generate 3DES keys with various block modes and paddings.
73 ///  - Block Modes: ECB, CBC
74 ///  - Padding Modes: NONE, PKCS7
75 ///
76 /// Test should generate keys and perform operation successfully.
77 #[test]
keystore2_3des_ecb_cbc_generate_key_success()78 fn keystore2_3des_ecb_cbc_generate_key_success() {
79     let block_modes = [BlockMode::ECB, BlockMode::CBC];
80     let padding_modes = [PaddingMode::PKCS7, PaddingMode::NONE];
81 
82     let sl = SecLevel::tee();
83     for block_mode in block_modes {
84         for padding_mode in padding_modes {
85             assert_eq!(
86                 Ok(()),
87                 create_3des_key_and_operation(&sl, padding_mode, block_mode, &mut None)
88             );
89         }
90     }
91 }
92 
93 /// Try to generate 3DES key with invalid key size. Test should fail to generate a key with
94 /// an error code `UNSUPPORTED_KEY_SIZE`.
95 #[test]
keystore2_3des_key_fails_unsupported_key_size()96 fn keystore2_3des_key_fails_unsupported_key_size() {
97     let sl = SecLevel::tee();
98     let alias = "3des_key_test_invalid_1";
99     let invalid_key_size = 128;
100 
101     let result = key_generations::map_ks_error(key_generations::generate_sym_key(
102         &sl,
103         Algorithm::TRIPLE_DES,
104         invalid_key_size,
105         alias,
106         &PaddingMode::PKCS7,
107         &BlockMode::CBC,
108         None,
109     ));
110     assert!(result.is_err());
111     assert_eq!(Error::Km(ErrorCode::UNSUPPORTED_KEY_SIZE), result.unwrap_err());
112 }
113 
114 /// Generate a 3DES key without providing padding mode and try to use the generated key to create
115 /// an operation. Test should fail to create an operation with an error code
116 /// `UNSUPPORTED_PADDING_MODE`.
117 #[test]
keystore2_3des_key_fails_missing_padding()118 fn keystore2_3des_key_fails_missing_padding() {
119     let sl = SecLevel::tee();
120     let alias = "3des_key_test_missing_padding";
121 
122     let gen_params = authorizations::AuthSetBuilder::new()
123         .no_auth_required()
124         .algorithm(Algorithm::TRIPLE_DES)
125         .purpose(KeyPurpose::ENCRYPT)
126         .purpose(KeyPurpose::DECRYPT)
127         .key_size(168)
128         .block_mode(BlockMode::ECB);
129 
130     let key_metadata = sl
131         .binder
132         .generateKey(
133             &KeyDescriptor {
134                 domain: Domain::APP,
135                 nspace: -1,
136                 alias: Some(alias.to_string()),
137                 blob: None,
138             },
139             None,
140             &gen_params,
141             0,
142             b"entropy",
143         )
144         .unwrap();
145 
146     let op_params = authorizations::AuthSetBuilder::new()
147         .purpose(KeyPurpose::ENCRYPT)
148         .block_mode(BlockMode::ECB);
149 
150     let result = key_generations::map_ks_error(sl.binder.createOperation(
151         &key_metadata.key,
152         &op_params,
153         false,
154     ));
155     assert!(result.is_err());
156     assert_eq!(Error::Km(ErrorCode::UNSUPPORTED_PADDING_MODE), result.unwrap_err());
157 }
158 
159 /// Generate a 3DES key with padding mode NONE. Try to encrypt a text whose length isn't a
160 /// multiple of the DES block size.
161 #[test]
keystore2_3des_key_encrypt_fails_invalid_input_length()162 fn keystore2_3des_key_encrypt_fails_invalid_input_length() {
163     let sl = SecLevel::tee();
164     let alias = "3des_key_test_invalid_input_len";
165 
166     let key_metadata = key_generations::generate_sym_key(
167         &sl,
168         Algorithm::TRIPLE_DES,
169         168,
170         alias,
171         &PaddingMode::NONE,
172         &BlockMode::ECB,
173         None,
174     )
175     .unwrap();
176 
177     let op_params = authorizations::AuthSetBuilder::new()
178         .purpose(KeyPurpose::ENCRYPT)
179         .padding_mode(PaddingMode::NONE)
180         .block_mode(BlockMode::ECB);
181 
182     let op_response = sl
183         .binder
184         .createOperation(&key_metadata.key, &op_params, false)
185         .expect("Error in creation of operation using rebound key.");
186     assert!(op_response.iOperation.is_some());
187 
188     let op = op_response.iOperation.unwrap();
189     // 3DES expects input should be multiple of DES block size (64-bits) length. Try with invalid
190     // length of input.
191     let invalid_block_size_msg = b"my message 111";
192     let result = key_generations::map_ks_error(op.finish(Some(invalid_block_size_msg), None));
193     assert!(result.is_err());
194     assert_eq!(Error::Km(ErrorCode::INVALID_INPUT_LENGTH), result.unwrap_err());
195 }
196 
197 /// Try to generate 3DES key with BlockMode::CTR. Test should fail to create an operation with an
198 /// error code `UNSUPPORTED_BLOCK_MODE`.
199 #[test]
keystore2_3des_key_fails_unsupported_block_mode()200 fn keystore2_3des_key_fails_unsupported_block_mode() {
201     let sl = SecLevel::tee();
202 
203     let result = key_generations::map_ks_error(create_3des_key_and_operation(
204         &sl,
205         PaddingMode::NONE,
206         BlockMode::CTR,
207         &mut None,
208     ));
209     assert!(result.is_err());
210     assert_eq!(Error::Km(ErrorCode::UNSUPPORTED_BLOCK_MODE), result.unwrap_err());
211 }
212