blob: c5dd582aade6c5dcf414e91499a573dc843e79a9 [file] [log] [blame]
Hasini Gunasingheb7142972021-02-20 03:11:27 +00001// Copyright 2021, 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//! This module provides convenience functions for keystore2 logging.
16use crate::error::get_error_code;
17use crate::key_parameter::KeyParameterValue as KsKeyParamValue;
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +000018use crate::operation::Outcome;
Hasini Gunasingheb7142972021-02-20 03:11:27 +000019use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
20 Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
21 HardwareAuthenticatorType::HardwareAuthenticatorType, KeyOrigin::KeyOrigin,
22 KeyParameter::KeyParameter, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +000023 SecurityLevel::SecurityLevel,
Hasini Gunasingheb7142972021-02-20 03:11:27 +000024};
25use statslog_rust::keystore2_key_creation_event_reported::{
26 Algorithm as StatsdAlgorithm, EcCurve as StatsdEcCurve, KeyOrigin as StatsdKeyOrigin,
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +000027 Keystore2KeyCreationEventReported, SecurityLevel as StatsdKeyCreationSecurityLevel,
28 UserAuthType as StatsdUserAuthType,
Hasini Gunasingheb7142972021-02-20 03:11:27 +000029};
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +000030use statslog_rust::keystore2_key_operation_event_reported::{
31 Keystore2KeyOperationEventReported, Outcome as StatsdOutcome, Purpose as StatsdKeyPurpose,
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +000032 SecurityLevel as StatsdKeyOperationSecurityLevel,
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +000033};
34
Hasini Gunasingheb7142972021-02-20 03:11:27 +000035fn create_default_key_creation_atom() -> Keystore2KeyCreationEventReported {
36 // If a value is not present, fields represented by bitmaps and i32 fields
37 // will take 0, except error_code which defaults to 1 indicating NO_ERROR and key_size,
38 // and auth_time_out which default to -1.
39 // The boolean fields are set to false by default.
40 // Some keymint enums do have 0 as an enum variant value. In such cases, the corresponding
41 // enum variant value in atoms.proto is incremented by 1, in order to have 0 as the reserved
42 // value for unspecified fields.
43 Keystore2KeyCreationEventReported {
44 algorithm: StatsdAlgorithm::AlgorithmUnspecified,
45 key_size: -1,
46 key_origin: StatsdKeyOrigin::OriginUnspecified,
47 user_auth_type: StatsdUserAuthType::AuthTypeUnspecified,
48 user_auth_key_timeout_seconds: -1,
49 padding_mode_bitmap: 0,
50 digest_bitmap: 0,
51 block_mode_bitmap: 0,
52 purpose_bitmap: 0,
53 ec_curve: StatsdEcCurve::EcCurveUnspecified,
54 // as per keystore2/ResponseCode.aidl, 1 is reserved for NO_ERROR
55 error_code: 1,
56 attestation_requested: false,
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +000057 security_level: StatsdKeyCreationSecurityLevel::SecurityLevelUnspecified,
Hasini Gunasingheb7142972021-02-20 03:11:27 +000058 }
59}
60
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +000061fn create_default_key_operation_atom() -> Keystore2KeyOperationEventReported {
62 Keystore2KeyOperationEventReported {
63 purpose: StatsdKeyPurpose::KeyPurposeUnspecified,
64 padding_mode_bitmap: 0,
65 digest_bitmap: 0,
66 block_mode_bitmap: 0,
67 outcome: StatsdOutcome::OutcomeUnspecified,
68 error_code: 1,
69 key_upgraded: false,
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +000070 security_level: StatsdKeyOperationSecurityLevel::SecurityLevelUnspecified,
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +000071 }
72}
73
74/// Log key creation events via statsd API.
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +000075pub fn log_key_creation_event_stats<U>(
76 sec_level: SecurityLevel,
77 key_params: &[KeyParameter],
78 result: &anyhow::Result<U>,
79) {
80 let key_creation_event_stats =
81 construct_key_creation_event_stats(sec_level, key_params, result);
Hasini Gunasingheb7142972021-02-20 03:11:27 +000082
83 let logging_result = key_creation_event_stats.stats_write();
84
85 if let Err(e) = logging_result {
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +000086 log::error!(
87 "In log_key_creation_event_stats. Error in logging key creation event. {:?}",
88 e
89 );
Hasini Gunasingheb7142972021-02-20 03:11:27 +000090 }
91}
92
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +000093/// Log key operation events via statsd API.
94pub fn log_key_operation_event_stats(
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +000095 sec_level: SecurityLevel,
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +000096 key_purpose: KeyPurpose,
97 op_params: &[KeyParameter],
98 op_outcome: &Outcome,
99 key_upgraded: bool,
100) {
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +0000101 let key_operation_event_stats = construct_key_operation_event_stats(
102 sec_level,
103 key_purpose,
104 op_params,
105 op_outcome,
106 key_upgraded,
107 );
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +0000108
109 let logging_result = key_operation_event_stats.stats_write();
110
111 if let Err(e) = logging_result {
112 log::error!(
113 "In log_key_operation_event_stats. Error in logging key operation event. {:?}",
114 e
115 );
116 }
117}
118
Hasini Gunasingheb7142972021-02-20 03:11:27 +0000119fn construct_key_creation_event_stats<U>(
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +0000120 sec_level: SecurityLevel,
Hasini Gunasingheb7142972021-02-20 03:11:27 +0000121 key_params: &[KeyParameter],
122 result: &anyhow::Result<U>,
123) -> Keystore2KeyCreationEventReported {
124 let mut key_creation_event_atom = create_default_key_creation_atom();
125
126 if let Err(ref e) = result {
127 key_creation_event_atom.error_code = get_error_code(e);
128 }
129
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +0000130 key_creation_event_atom.security_level = match sec_level {
131 SecurityLevel::SOFTWARE => StatsdKeyCreationSecurityLevel::SecurityLevelSoftware,
132 SecurityLevel::TRUSTED_ENVIRONMENT => {
133 StatsdKeyCreationSecurityLevel::SecurityLevelTrustedEnvironment
134 }
135 SecurityLevel::STRONGBOX => StatsdKeyCreationSecurityLevel::SecurityLevelStrongbox,
136 //KEYSTORE is not a valid variant here
137 _ => StatsdKeyCreationSecurityLevel::SecurityLevelUnspecified,
138 };
139
Hasini Gunasingheb7142972021-02-20 03:11:27 +0000140 for key_param in key_params.iter().map(KsKeyParamValue::from) {
141 match key_param {
142 KsKeyParamValue::Algorithm(a) => {
143 key_creation_event_atom.algorithm = match a {
144 Algorithm::RSA => StatsdAlgorithm::Rsa,
145 Algorithm::EC => StatsdAlgorithm::Ec,
146 Algorithm::AES => StatsdAlgorithm::Aes,
147 Algorithm::TRIPLE_DES => StatsdAlgorithm::TripleDes,
148 Algorithm::HMAC => StatsdAlgorithm::Hmac,
149 _ => StatsdAlgorithm::AlgorithmUnspecified,
150 }
151 }
152 KsKeyParamValue::KeySize(s) => {
153 key_creation_event_atom.key_size = s;
154 }
155 KsKeyParamValue::KeyOrigin(o) => {
156 key_creation_event_atom.key_origin = match o {
157 KeyOrigin::GENERATED => StatsdKeyOrigin::Generated,
158 KeyOrigin::DERIVED => StatsdKeyOrigin::Derived,
159 KeyOrigin::IMPORTED => StatsdKeyOrigin::Imported,
160 KeyOrigin::RESERVED => StatsdKeyOrigin::Reserved,
161 KeyOrigin::SECURELY_IMPORTED => StatsdKeyOrigin::SecurelyImported,
162 _ => StatsdKeyOrigin::OriginUnspecified,
163 }
164 }
165 KsKeyParamValue::HardwareAuthenticatorType(a) => {
166 key_creation_event_atom.user_auth_type = match a {
167 HardwareAuthenticatorType::NONE => StatsdUserAuthType::None,
168 HardwareAuthenticatorType::PASSWORD => StatsdUserAuthType::Password,
169 HardwareAuthenticatorType::FINGERPRINT => StatsdUserAuthType::Fingerprint,
170 HardwareAuthenticatorType::ANY => StatsdUserAuthType::Any,
171 _ => StatsdUserAuthType::AuthTypeUnspecified,
172 }
173 }
174 KsKeyParamValue::AuthTimeout(t) => {
175 key_creation_event_atom.user_auth_key_timeout_seconds = t;
176 }
177 KsKeyParamValue::PaddingMode(p) => {
178 key_creation_event_atom.padding_mode_bitmap =
179 compute_padding_mode_bitmap(&key_creation_event_atom.padding_mode_bitmap, p);
180 }
181 KsKeyParamValue::Digest(d) => {
182 key_creation_event_atom.digest_bitmap =
183 compute_digest_bitmap(&key_creation_event_atom.digest_bitmap, d);
184 }
185 KsKeyParamValue::BlockMode(b) => {
186 key_creation_event_atom.block_mode_bitmap =
187 compute_block_mode_bitmap(&key_creation_event_atom.block_mode_bitmap, b);
188 }
189 KsKeyParamValue::KeyPurpose(k) => {
190 key_creation_event_atom.purpose_bitmap =
191 compute_purpose_bitmap(&key_creation_event_atom.purpose_bitmap, k);
192 }
193 KsKeyParamValue::EcCurve(e) => {
194 key_creation_event_atom.ec_curve = match e {
195 EcCurve::P_224 => StatsdEcCurve::P224,
196 EcCurve::P_256 => StatsdEcCurve::P256,
197 EcCurve::P_384 => StatsdEcCurve::P384,
198 EcCurve::P_521 => StatsdEcCurve::P521,
199 _ => StatsdEcCurve::EcCurveUnspecified,
200 }
201 }
202 KsKeyParamValue::AttestationChallenge(_) => {
203 key_creation_event_atom.attestation_requested = true;
204 }
205 _ => {}
206 }
207 }
208 key_creation_event_atom
209}
210
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +0000211fn construct_key_operation_event_stats(
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +0000212 sec_level: SecurityLevel,
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +0000213 key_purpose: KeyPurpose,
214 op_params: &[KeyParameter],
215 op_outcome: &Outcome,
216 key_upgraded: bool,
217) -> Keystore2KeyOperationEventReported {
218 let mut key_operation_event_atom = create_default_key_operation_atom();
219
Hasini Gunasinghe9617fd92021-04-01 22:27:07 +0000220 key_operation_event_atom.security_level = match sec_level {
221 SecurityLevel::SOFTWARE => StatsdKeyOperationSecurityLevel::SecurityLevelSoftware,
222 SecurityLevel::TRUSTED_ENVIRONMENT => {
223 StatsdKeyOperationSecurityLevel::SecurityLevelTrustedEnvironment
224 }
225 SecurityLevel::STRONGBOX => StatsdKeyOperationSecurityLevel::SecurityLevelStrongbox,
226 //KEYSTORE is not a valid variant here
227 _ => StatsdKeyOperationSecurityLevel::SecurityLevelUnspecified,
228 };
229
Hasini Gunasinghe0aba68a2021-03-19 00:43:52 +0000230 key_operation_event_atom.key_upgraded = key_upgraded;
231
232 key_operation_event_atom.purpose = match key_purpose {
233 KeyPurpose::ENCRYPT => StatsdKeyPurpose::Encrypt,
234 KeyPurpose::DECRYPT => StatsdKeyPurpose::Decrypt,
235 KeyPurpose::SIGN => StatsdKeyPurpose::Sign,
236 KeyPurpose::VERIFY => StatsdKeyPurpose::Verify,
237 KeyPurpose::WRAP_KEY => StatsdKeyPurpose::WrapKey,
238 KeyPurpose::AGREE_KEY => StatsdKeyPurpose::AgreeKey,
239 KeyPurpose::ATTEST_KEY => StatsdKeyPurpose::AttestKey,
240 _ => StatsdKeyPurpose::KeyPurposeUnspecified,
241 };
242
243 key_operation_event_atom.outcome = match op_outcome {
244 Outcome::Unknown | Outcome::Dropped => StatsdOutcome::Dropped,
245 Outcome::Success => StatsdOutcome::Success,
246 Outcome::Abort => StatsdOutcome::Abort,
247 Outcome::Pruned => StatsdOutcome::Pruned,
248 Outcome::ErrorCode(e) => {
249 key_operation_event_atom.error_code = e.0;
250 StatsdOutcome::Error
251 }
252 };
253
254 for key_param in op_params.iter().map(KsKeyParamValue::from) {
255 match key_param {
256 KsKeyParamValue::PaddingMode(p) => {
257 key_operation_event_atom.padding_mode_bitmap =
258 compute_padding_mode_bitmap(&key_operation_event_atom.padding_mode_bitmap, p);
259 }
260 KsKeyParamValue::Digest(d) => {
261 key_operation_event_atom.digest_bitmap =
262 compute_digest_bitmap(&key_operation_event_atom.digest_bitmap, d);
263 }
264 KsKeyParamValue::BlockMode(b) => {
265 key_operation_event_atom.block_mode_bitmap =
266 compute_block_mode_bitmap(&key_operation_event_atom.block_mode_bitmap, b);
267 }
268 _ => {}
269 }
270 }
271
272 key_operation_event_atom
273}
274
Hasini Gunasingheb7142972021-02-20 03:11:27 +0000275fn compute_purpose_bitmap(purpose_bitmap: &i32, purpose: KeyPurpose) -> i32 {
276 let mut bitmap = *purpose_bitmap;
277 match purpose {
278 KeyPurpose::ENCRYPT => {
279 bitmap |= 1 << KeyPurposeBitPosition::ENCRYPT_BIT_POS as i32;
280 }
281 KeyPurpose::DECRYPT => {
282 bitmap |= 1 << KeyPurposeBitPosition::DECRYPT_BIT_POS as i32;
283 }
284 KeyPurpose::SIGN => {
285 bitmap |= 1 << KeyPurposeBitPosition::SIGN_BIT_POS as i32;
286 }
287 KeyPurpose::VERIFY => {
288 bitmap |= 1 << KeyPurposeBitPosition::VERIFY_BIT_POS as i32;
289 }
290 KeyPurpose::WRAP_KEY => {
291 bitmap |= 1 << KeyPurposeBitPosition::WRAP_KEY_BIT_POS as i32;
292 }
293 KeyPurpose::AGREE_KEY => {
294 bitmap |= 1 << KeyPurposeBitPosition::AGREE_KEY_BIT_POS as i32;
295 }
296 KeyPurpose::ATTEST_KEY => {
297 bitmap |= 1 << KeyPurposeBitPosition::ATTEST_KEY_BIT_POS as i32;
298 }
299 _ => {}
300 }
301 bitmap
302}
303
304fn compute_padding_mode_bitmap(padding_mode_bitmap: &i32, padding_mode: PaddingMode) -> i32 {
305 let mut bitmap = *padding_mode_bitmap;
306 match padding_mode {
307 PaddingMode::NONE => {
308 bitmap |= 1 << PaddingModeBitPosition::NONE_BIT_POSITION as i32;
309 }
310 PaddingMode::RSA_OAEP => {
311 bitmap |= 1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS as i32;
312 }
313 PaddingMode::RSA_PSS => {
314 bitmap |= 1 << PaddingModeBitPosition::RSA_PSS_BIT_POS as i32;
315 }
316 PaddingMode::RSA_PKCS1_1_5_ENCRYPT => {
317 bitmap |= 1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS as i32;
318 }
319 PaddingMode::RSA_PKCS1_1_5_SIGN => {
320 bitmap |= 1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS as i32;
321 }
322 PaddingMode::PKCS7 => {
323 bitmap |= 1 << PaddingModeBitPosition::PKCS7_BIT_POS as i32;
324 }
325 _ => {}
326 }
327 bitmap
328}
329
330fn compute_digest_bitmap(digest_bitmap: &i32, digest: Digest) -> i32 {
331 let mut bitmap = *digest_bitmap;
332 match digest {
333 Digest::NONE => {
334 bitmap |= 1 << DigestBitPosition::NONE_BIT_POSITION as i32;
335 }
336 Digest::MD5 => {
337 bitmap |= 1 << DigestBitPosition::MD5_BIT_POS as i32;
338 }
339 Digest::SHA1 => {
340 bitmap |= 1 << DigestBitPosition::SHA_1_BIT_POS as i32;
341 }
342 Digest::SHA_2_224 => {
343 bitmap |= 1 << DigestBitPosition::SHA_2_224_BIT_POS as i32;
344 }
345 Digest::SHA_2_256 => {
346 bitmap |= 1 << DigestBitPosition::SHA_2_256_BIT_POS as i32;
347 }
348 Digest::SHA_2_384 => {
349 bitmap |= 1 << DigestBitPosition::SHA_2_384_BIT_POS as i32;
350 }
351 Digest::SHA_2_512 => {
352 bitmap |= 1 << DigestBitPosition::SHA_2_512_BIT_POS as i32;
353 }
354 _ => {}
355 }
356 bitmap
357}
358
359fn compute_block_mode_bitmap(block_mode_bitmap: &i32, block_mode: BlockMode) -> i32 {
360 let mut bitmap = *block_mode_bitmap;
361 match block_mode {
362 BlockMode::ECB => {
363 bitmap |= 1 << BlockModeBitPosition::ECB_BIT_POS as i32;
364 }
365 BlockMode::CBC => {
366 bitmap |= 1 << BlockModeBitPosition::CBC_BIT_POS as i32;
367 }
368 BlockMode::CTR => {
369 bitmap |= 1 << BlockModeBitPosition::CTR_BIT_POS as i32;
370 }
371 BlockMode::GCM => {
372 bitmap |= 1 << BlockModeBitPosition::GCM_BIT_POS as i32;
373 }
374 _ => {}
375 }
376 bitmap
377}
378/// Enum defining the bit position for each padding mode. Since padding mode can be repeatable, it
379/// is represented using a bitmap.
380#[allow(non_camel_case_types)]
381#[repr(i32)]
382pub enum PaddingModeBitPosition {
383 ///Bit position in the PaddingMode bitmap for NONE.
384 NONE_BIT_POSITION = 0,
385 ///Bit position in the PaddingMode bitmap for RSA_OAEP.
386 RSA_OAEP_BIT_POS = 1,
387 ///Bit position in the PaddingMode bitmap for RSA_PSS.
388 RSA_PSS_BIT_POS = 2,
389 ///Bit position in the PaddingMode bitmap for RSA_PKCS1_1_5_ENCRYPT.
390 RSA_PKCS1_1_5_ENCRYPT_BIT_POS = 3,
391 ///Bit position in the PaddingMode bitmap for RSA_PKCS1_1_5_SIGN.
392 RSA_PKCS1_1_5_SIGN_BIT_POS = 4,
393 ///Bit position in the PaddingMode bitmap for RSA_PKCS7.
394 PKCS7_BIT_POS = 5,
395}
396
397/// Enum defining the bit position for each digest type. Since digest can be repeatable in
398/// key parameters, it is represented using a bitmap.
399#[allow(non_camel_case_types)]
400#[repr(i32)]
401pub enum DigestBitPosition {
402 ///Bit position in the Digest bitmap for NONE.
403 NONE_BIT_POSITION = 0,
404 ///Bit position in the Digest bitmap for MD5.
405 MD5_BIT_POS = 1,
406 ///Bit position in the Digest bitmap for SHA1.
407 SHA_1_BIT_POS = 2,
408 ///Bit position in the Digest bitmap for SHA_2_224.
409 SHA_2_224_BIT_POS = 3,
410 ///Bit position in the Digest bitmap for SHA_2_256.
411 SHA_2_256_BIT_POS = 4,
412 ///Bit position in the Digest bitmap for SHA_2_384.
413 SHA_2_384_BIT_POS = 5,
414 ///Bit position in the Digest bitmap for SHA_2_512.
415 SHA_2_512_BIT_POS = 6,
416}
417
418/// Enum defining the bit position for each block mode type. Since block mode can be repeatable in
419/// key parameters, it is represented using a bitmap.
420#[allow(non_camel_case_types)]
421#[repr(i32)]
422enum BlockModeBitPosition {
423 ///Bit position in the BlockMode bitmap for ECB.
424 ECB_BIT_POS = 1,
425 ///Bit position in the BlockMode bitmap for CBC.
426 CBC_BIT_POS = 2,
427 ///Bit position in the BlockMode bitmap for CTR.
428 CTR_BIT_POS = 3,
429 ///Bit position in the BlockMode bitmap for GCM.
430 GCM_BIT_POS = 4,
431}
432
433/// Enum defining the bit position for each key purpose. Since key purpose can be repeatable in
434/// key parameters, it is represented using a bitmap.
435#[allow(non_camel_case_types)]
436#[repr(i32)]
437enum KeyPurposeBitPosition {
438 ///Bit position in the KeyPurpose bitmap for Encrypt.
439 ENCRYPT_BIT_POS = 1,
440 ///Bit position in the KeyPurpose bitmap for Decrypt.
441 DECRYPT_BIT_POS = 2,
442 ///Bit position in the KeyPurpose bitmap for Sign.
443 SIGN_BIT_POS = 3,
444 ///Bit position in the KeyPurpose bitmap for Verify.
445 VERIFY_BIT_POS = 4,
446 ///Bit position in the KeyPurpose bitmap for Wrap Key.
447 WRAP_KEY_BIT_POS = 5,
448 ///Bit position in the KeyPurpose bitmap for Agree Key.
449 AGREE_KEY_BIT_POS = 6,
450 ///Bit position in the KeyPurpose bitmap for Attest Key.
451 ATTEST_KEY_BIT_POS = 7,
452}