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