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 android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
16 Algorithm::Algorithm, BlockMode::BlockMode, ErrorCode::ErrorCode, KeyPurpose::KeyPurpose,
17 PaddingMode::PaddingMode, SecurityLevel::SecurityLevel,
18 };
19
20 use android_system_keystore2::aidl::android::system::keystore2::{
21 Domain::Domain, IKeystoreSecurityLevel::IKeystoreSecurityLevel, KeyDescriptor::KeyDescriptor,
22 };
23
24 use keystore2_test_utils::{
25 authorizations, get_keystore_service, key_generations, key_generations::Error,
26 };
27
28 use crate::keystore2_client_test_utils::{
29 perform_sample_sym_key_decrypt_op, perform_sample_sym_key_encrypt_op, SAMPLE_PLAIN_TEXT,
30 };
31
32 /// Generate a 3DES key. Create encryption and decryption operations using the generated key.
create_3des_key_and_operation( sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>, padding_mode: PaddingMode, block_mode: BlockMode, nonce: &mut Option<Vec<u8>>, ) -> Result<(), binder::Status>33 fn create_3des_key_and_operation(
34 sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
35 padding_mode: PaddingMode,
36 block_mode: BlockMode,
37 nonce: &mut Option<Vec<u8>>,
38 ) -> Result<(), binder::Status> {
39 let alias = format!("ks_3des_test_key_{}{}", block_mode.0, padding_mode.0);
40
41 let key_metadata = key_generations::generate_sym_key(
42 sec_level,
43 Algorithm::TRIPLE_DES,
44 168,
45 &alias,
46 &padding_mode,
47 &block_mode,
48 None,
49 )?;
50
51 // Encrypts `SAMPLE_PLAIN_TEXT` whose length is multiple of DES block size.
52 let cipher_text = perform_sample_sym_key_encrypt_op(
53 sec_level,
54 padding_mode,
55 block_mode,
56 nonce,
57 None,
58 &key_metadata.key,
59 )?;
60 assert!(cipher_text.is_some());
61
62 let plain_text = perform_sample_sym_key_decrypt_op(
63 sec_level,
64 &cipher_text.unwrap(),
65 padding_mode,
66 block_mode,
67 nonce,
68 None,
69 &key_metadata.key,
70 )
71 .unwrap();
72 assert!(plain_text.is_some());
73 assert_eq!(plain_text.unwrap(), SAMPLE_PLAIN_TEXT.to_vec());
74 Ok(())
75 }
76
77 /// Generate 3DES keys with various block modes and paddings.
78 /// - Block Modes: ECB, CBC
79 /// - Padding Modes: NONE, PKCS7
80 /// Test should generate keys and perform operation successfully.
81 #[test]
keystore2_3des_ecb_cbc_generate_key_success()82 fn keystore2_3des_ecb_cbc_generate_key_success() {
83 let keystore2 = get_keystore_service();
84 let block_modes = [BlockMode::ECB, BlockMode::CBC];
85 let padding_modes = [PaddingMode::PKCS7, PaddingMode::NONE];
86
87 let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
88 for block_mode in block_modes {
89 for padding_mode in padding_modes {
90 assert_eq!(
91 Ok(()),
92 create_3des_key_and_operation(&sec_level, padding_mode, block_mode, &mut None)
93 );
94 }
95 }
96 }
97
98 /// Try to generate 3DES key with invalid key size. Test should fail to generate a key with
99 /// an error code `UNSUPPORTED_KEY_SIZE`.
100 #[test]
keystore2_3des_key_fails_unsupported_key_size()101 fn keystore2_3des_key_fails_unsupported_key_size() {
102 let keystore2 = get_keystore_service();
103 let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
104 let alias = "3des_key_test_invalid_1";
105 let invalid_key_size = 128;
106
107 let result = key_generations::map_ks_error(key_generations::generate_sym_key(
108 &sec_level,
109 Algorithm::TRIPLE_DES,
110 invalid_key_size,
111 alias,
112 &PaddingMode::PKCS7,
113 &BlockMode::CBC,
114 None,
115 ));
116 assert!(result.is_err());
117 assert_eq!(Error::Km(ErrorCode::UNSUPPORTED_KEY_SIZE), result.unwrap_err());
118 }
119
120 /// Generate a 3DES key without providing padding mode and try to use the generated key to create
121 /// an operation. Test should fail to create an operation with an error code
122 /// `UNSUPPORTED_PADDING_MODE`.
123 #[test]
keystore2_3des_key_fails_missing_padding()124 fn keystore2_3des_key_fails_missing_padding() {
125 let keystore2 = get_keystore_service();
126 let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
127 let alias = "3des_key_test_missing_padding";
128
129 let gen_params = authorizations::AuthSetBuilder::new()
130 .no_auth_required()
131 .algorithm(Algorithm::TRIPLE_DES)
132 .purpose(KeyPurpose::ENCRYPT)
133 .purpose(KeyPurpose::DECRYPT)
134 .key_size(168)
135 .block_mode(BlockMode::ECB);
136
137 let key_metadata = sec_level
138 .generateKey(
139 &KeyDescriptor {
140 domain: Domain::APP,
141 nspace: -1,
142 alias: Some(alias.to_string()),
143 blob: None,
144 },
145 None,
146 &gen_params,
147 0,
148 b"entropy",
149 )
150 .unwrap();
151
152 let op_params = authorizations::AuthSetBuilder::new()
153 .purpose(KeyPurpose::ENCRYPT)
154 .block_mode(BlockMode::ECB);
155
156 let result = key_generations::map_ks_error(sec_level.createOperation(
157 &key_metadata.key,
158 &op_params,
159 false,
160 ));
161 assert!(result.is_err());
162 assert_eq!(Error::Km(ErrorCode::UNSUPPORTED_PADDING_MODE), result.unwrap_err());
163 }
164
165 /// Generate a 3DES key with padding mode NONE. Try to encrypt a text whose length isn't a
166 /// multiple of the DES block size.
167 #[test]
keystore2_3des_key_encrypt_fails_invalid_input_length()168 fn keystore2_3des_key_encrypt_fails_invalid_input_length() {
169 let keystore2 = get_keystore_service();
170 let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
171 let alias = "3des_key_test_invalid_input_len";
172
173 let key_metadata = key_generations::generate_sym_key(
174 &sec_level,
175 Algorithm::TRIPLE_DES,
176 168,
177 alias,
178 &PaddingMode::NONE,
179 &BlockMode::ECB,
180 None,
181 )
182 .unwrap();
183
184 let op_params = authorizations::AuthSetBuilder::new()
185 .purpose(KeyPurpose::ENCRYPT)
186 .padding_mode(PaddingMode::NONE)
187 .block_mode(BlockMode::ECB);
188
189 let op_response = sec_level
190 .createOperation(&key_metadata.key, &op_params, false)
191 .expect("Error in creation of operation using rebound key.");
192 assert!(op_response.iOperation.is_some());
193
194 let op = op_response.iOperation.unwrap();
195 // 3DES expects input should be multiple of DES block size (64-bits) length. Try with invalid
196 // length of input.
197 let invalid_block_size_msg = b"my message 111";
198 let result = key_generations::map_ks_error(op.finish(Some(invalid_block_size_msg), None));
199 assert!(result.is_err());
200 assert_eq!(Error::Km(ErrorCode::INVALID_INPUT_LENGTH), result.unwrap_err());
201 }
202
203 /// Try to generate 3DES key with BlockMode::CTR. Test should fail to create an operation with an
204 /// error code `UNSUPPORTED_BLOCK_MODE`.
205 #[test]
keystore2_3des_key_fails_unsupported_block_mode()206 fn keystore2_3des_key_fails_unsupported_block_mode() {
207 let keystore2 = get_keystore_service();
208 let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
209
210 let result = key_generations::map_ks_error(create_3des_key_and_operation(
211 &sec_level,
212 PaddingMode::NONE,
213 BlockMode::CTR,
214 &mut None,
215 ));
216 assert!(result.is_err());
217 assert_eq!(Error::Km(ErrorCode::UNSUPPORTED_BLOCK_MODE), result.unwrap_err());
218 }
219