blob: 04ad893ad6300d112b3e94fece3cb948f648f321 [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;
18use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
19 Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
20 HardwareAuthenticatorType::HardwareAuthenticatorType, KeyOrigin::KeyOrigin,
21 KeyParameter::KeyParameter, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
22};
23use statslog_rust::keystore2_key_creation_event_reported::{
24 Algorithm as StatsdAlgorithm, EcCurve as StatsdEcCurve, KeyOrigin as StatsdKeyOrigin,
25 Keystore2KeyCreationEventReported, UserAuthType as StatsdUserAuthType,
26};
27
28fn create_default_key_creation_atom() -> Keystore2KeyCreationEventReported {
29 // If a value is not present, fields represented by bitmaps and i32 fields
30 // will take 0, except error_code which defaults to 1 indicating NO_ERROR and key_size,
31 // and auth_time_out which default to -1.
32 // The boolean fields are set to false by default.
33 // Some keymint enums do have 0 as an enum variant value. In such cases, the corresponding
34 // enum variant value in atoms.proto is incremented by 1, in order to have 0 as the reserved
35 // value for unspecified fields.
36 Keystore2KeyCreationEventReported {
37 algorithm: StatsdAlgorithm::AlgorithmUnspecified,
38 key_size: -1,
39 key_origin: StatsdKeyOrigin::OriginUnspecified,
40 user_auth_type: StatsdUserAuthType::AuthTypeUnspecified,
41 user_auth_key_timeout_seconds: -1,
42 padding_mode_bitmap: 0,
43 digest_bitmap: 0,
44 block_mode_bitmap: 0,
45 purpose_bitmap: 0,
46 ec_curve: StatsdEcCurve::EcCurveUnspecified,
47 // as per keystore2/ResponseCode.aidl, 1 is reserved for NO_ERROR
48 error_code: 1,
49 attestation_requested: false,
50 }
51}
52
53/// Log key events via statsd API.
54pub fn log_key_creation_event_stats<U>(key_params: &[KeyParameter], result: &anyhow::Result<U>) {
55 let key_creation_event_stats = construct_key_creation_event_stats(key_params, result);
56
57 let logging_result = key_creation_event_stats.stats_write();
58
59 if let Err(e) = logging_result {
60 log::error!("In log_key_event_stats. Error in logging key event. {:?}", e);
61 }
62}
63
64// Given key parameters, event_type and result, populate the information in Keystore2KeyEventAtom.
65fn construct_key_creation_event_stats<U>(
66 key_params: &[KeyParameter],
67 result: &anyhow::Result<U>,
68) -> Keystore2KeyCreationEventReported {
69 let mut key_creation_event_atom = create_default_key_creation_atom();
70
71 if let Err(ref e) = result {
72 key_creation_event_atom.error_code = get_error_code(e);
73 }
74
75 for key_param in key_params.iter().map(KsKeyParamValue::from) {
76 match key_param {
77 KsKeyParamValue::Algorithm(a) => {
78 key_creation_event_atom.algorithm = match a {
79 Algorithm::RSA => StatsdAlgorithm::Rsa,
80 Algorithm::EC => StatsdAlgorithm::Ec,
81 Algorithm::AES => StatsdAlgorithm::Aes,
82 Algorithm::TRIPLE_DES => StatsdAlgorithm::TripleDes,
83 Algorithm::HMAC => StatsdAlgorithm::Hmac,
84 _ => StatsdAlgorithm::AlgorithmUnspecified,
85 }
86 }
87 KsKeyParamValue::KeySize(s) => {
88 key_creation_event_atom.key_size = s;
89 }
90 KsKeyParamValue::KeyOrigin(o) => {
91 key_creation_event_atom.key_origin = match o {
92 KeyOrigin::GENERATED => StatsdKeyOrigin::Generated,
93 KeyOrigin::DERIVED => StatsdKeyOrigin::Derived,
94 KeyOrigin::IMPORTED => StatsdKeyOrigin::Imported,
95 KeyOrigin::RESERVED => StatsdKeyOrigin::Reserved,
96 KeyOrigin::SECURELY_IMPORTED => StatsdKeyOrigin::SecurelyImported,
97 _ => StatsdKeyOrigin::OriginUnspecified,
98 }
99 }
100 KsKeyParamValue::HardwareAuthenticatorType(a) => {
101 key_creation_event_atom.user_auth_type = match a {
102 HardwareAuthenticatorType::NONE => StatsdUserAuthType::None,
103 HardwareAuthenticatorType::PASSWORD => StatsdUserAuthType::Password,
104 HardwareAuthenticatorType::FINGERPRINT => StatsdUserAuthType::Fingerprint,
105 HardwareAuthenticatorType::ANY => StatsdUserAuthType::Any,
106 _ => StatsdUserAuthType::AuthTypeUnspecified,
107 }
108 }
109 KsKeyParamValue::AuthTimeout(t) => {
110 key_creation_event_atom.user_auth_key_timeout_seconds = t;
111 }
112 KsKeyParamValue::PaddingMode(p) => {
113 key_creation_event_atom.padding_mode_bitmap =
114 compute_padding_mode_bitmap(&key_creation_event_atom.padding_mode_bitmap, p);
115 }
116 KsKeyParamValue::Digest(d) => {
117 key_creation_event_atom.digest_bitmap =
118 compute_digest_bitmap(&key_creation_event_atom.digest_bitmap, d);
119 }
120 KsKeyParamValue::BlockMode(b) => {
121 key_creation_event_atom.block_mode_bitmap =
122 compute_block_mode_bitmap(&key_creation_event_atom.block_mode_bitmap, b);
123 }
124 KsKeyParamValue::KeyPurpose(k) => {
125 key_creation_event_atom.purpose_bitmap =
126 compute_purpose_bitmap(&key_creation_event_atom.purpose_bitmap, k);
127 }
128 KsKeyParamValue::EcCurve(e) => {
129 key_creation_event_atom.ec_curve = match e {
130 EcCurve::P_224 => StatsdEcCurve::P224,
131 EcCurve::P_256 => StatsdEcCurve::P256,
132 EcCurve::P_384 => StatsdEcCurve::P384,
133 EcCurve::P_521 => StatsdEcCurve::P521,
134 _ => StatsdEcCurve::EcCurveUnspecified,
135 }
136 }
137 KsKeyParamValue::AttestationChallenge(_) => {
138 key_creation_event_atom.attestation_requested = true;
139 }
140 _ => {}
141 }
142 }
143 key_creation_event_atom
144}
145
146fn compute_purpose_bitmap(purpose_bitmap: &i32, purpose: KeyPurpose) -> i32 {
147 let mut bitmap = *purpose_bitmap;
148 match purpose {
149 KeyPurpose::ENCRYPT => {
150 bitmap |= 1 << KeyPurposeBitPosition::ENCRYPT_BIT_POS as i32;
151 }
152 KeyPurpose::DECRYPT => {
153 bitmap |= 1 << KeyPurposeBitPosition::DECRYPT_BIT_POS as i32;
154 }
155 KeyPurpose::SIGN => {
156 bitmap |= 1 << KeyPurposeBitPosition::SIGN_BIT_POS as i32;
157 }
158 KeyPurpose::VERIFY => {
159 bitmap |= 1 << KeyPurposeBitPosition::VERIFY_BIT_POS as i32;
160 }
161 KeyPurpose::WRAP_KEY => {
162 bitmap |= 1 << KeyPurposeBitPosition::WRAP_KEY_BIT_POS as i32;
163 }
164 KeyPurpose::AGREE_KEY => {
165 bitmap |= 1 << KeyPurposeBitPosition::AGREE_KEY_BIT_POS as i32;
166 }
167 KeyPurpose::ATTEST_KEY => {
168 bitmap |= 1 << KeyPurposeBitPosition::ATTEST_KEY_BIT_POS as i32;
169 }
170 _ => {}
171 }
172 bitmap
173}
174
175fn compute_padding_mode_bitmap(padding_mode_bitmap: &i32, padding_mode: PaddingMode) -> i32 {
176 let mut bitmap = *padding_mode_bitmap;
177 match padding_mode {
178 PaddingMode::NONE => {
179 bitmap |= 1 << PaddingModeBitPosition::NONE_BIT_POSITION as i32;
180 }
181 PaddingMode::RSA_OAEP => {
182 bitmap |= 1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS as i32;
183 }
184 PaddingMode::RSA_PSS => {
185 bitmap |= 1 << PaddingModeBitPosition::RSA_PSS_BIT_POS as i32;
186 }
187 PaddingMode::RSA_PKCS1_1_5_ENCRYPT => {
188 bitmap |= 1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS as i32;
189 }
190 PaddingMode::RSA_PKCS1_1_5_SIGN => {
191 bitmap |= 1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS as i32;
192 }
193 PaddingMode::PKCS7 => {
194 bitmap |= 1 << PaddingModeBitPosition::PKCS7_BIT_POS as i32;
195 }
196 _ => {}
197 }
198 bitmap
199}
200
201fn compute_digest_bitmap(digest_bitmap: &i32, digest: Digest) -> i32 {
202 let mut bitmap = *digest_bitmap;
203 match digest {
204 Digest::NONE => {
205 bitmap |= 1 << DigestBitPosition::NONE_BIT_POSITION as i32;
206 }
207 Digest::MD5 => {
208 bitmap |= 1 << DigestBitPosition::MD5_BIT_POS as i32;
209 }
210 Digest::SHA1 => {
211 bitmap |= 1 << DigestBitPosition::SHA_1_BIT_POS as i32;
212 }
213 Digest::SHA_2_224 => {
214 bitmap |= 1 << DigestBitPosition::SHA_2_224_BIT_POS as i32;
215 }
216 Digest::SHA_2_256 => {
217 bitmap |= 1 << DigestBitPosition::SHA_2_256_BIT_POS as i32;
218 }
219 Digest::SHA_2_384 => {
220 bitmap |= 1 << DigestBitPosition::SHA_2_384_BIT_POS as i32;
221 }
222 Digest::SHA_2_512 => {
223 bitmap |= 1 << DigestBitPosition::SHA_2_512_BIT_POS as i32;
224 }
225 _ => {}
226 }
227 bitmap
228}
229
230fn compute_block_mode_bitmap(block_mode_bitmap: &i32, block_mode: BlockMode) -> i32 {
231 let mut bitmap = *block_mode_bitmap;
232 match block_mode {
233 BlockMode::ECB => {
234 bitmap |= 1 << BlockModeBitPosition::ECB_BIT_POS as i32;
235 }
236 BlockMode::CBC => {
237 bitmap |= 1 << BlockModeBitPosition::CBC_BIT_POS as i32;
238 }
239 BlockMode::CTR => {
240 bitmap |= 1 << BlockModeBitPosition::CTR_BIT_POS as i32;
241 }
242 BlockMode::GCM => {
243 bitmap |= 1 << BlockModeBitPosition::GCM_BIT_POS as i32;
244 }
245 _ => {}
246 }
247 bitmap
248}
249/// Enum defining the bit position for each padding mode. Since padding mode can be repeatable, it
250/// is represented using a bitmap.
251#[allow(non_camel_case_types)]
252#[repr(i32)]
253pub enum PaddingModeBitPosition {
254 ///Bit position in the PaddingMode bitmap for NONE.
255 NONE_BIT_POSITION = 0,
256 ///Bit position in the PaddingMode bitmap for RSA_OAEP.
257 RSA_OAEP_BIT_POS = 1,
258 ///Bit position in the PaddingMode bitmap for RSA_PSS.
259 RSA_PSS_BIT_POS = 2,
260 ///Bit position in the PaddingMode bitmap for RSA_PKCS1_1_5_ENCRYPT.
261 RSA_PKCS1_1_5_ENCRYPT_BIT_POS = 3,
262 ///Bit position in the PaddingMode bitmap for RSA_PKCS1_1_5_SIGN.
263 RSA_PKCS1_1_5_SIGN_BIT_POS = 4,
264 ///Bit position in the PaddingMode bitmap for RSA_PKCS7.
265 PKCS7_BIT_POS = 5,
266}
267
268/// Enum defining the bit position for each digest type. Since digest can be repeatable in
269/// key parameters, it is represented using a bitmap.
270#[allow(non_camel_case_types)]
271#[repr(i32)]
272pub enum DigestBitPosition {
273 ///Bit position in the Digest bitmap for NONE.
274 NONE_BIT_POSITION = 0,
275 ///Bit position in the Digest bitmap for MD5.
276 MD5_BIT_POS = 1,
277 ///Bit position in the Digest bitmap for SHA1.
278 SHA_1_BIT_POS = 2,
279 ///Bit position in the Digest bitmap for SHA_2_224.
280 SHA_2_224_BIT_POS = 3,
281 ///Bit position in the Digest bitmap for SHA_2_256.
282 SHA_2_256_BIT_POS = 4,
283 ///Bit position in the Digest bitmap for SHA_2_384.
284 SHA_2_384_BIT_POS = 5,
285 ///Bit position in the Digest bitmap for SHA_2_512.
286 SHA_2_512_BIT_POS = 6,
287}
288
289/// Enum defining the bit position for each block mode type. Since block mode can be repeatable in
290/// key parameters, it is represented using a bitmap.
291#[allow(non_camel_case_types)]
292#[repr(i32)]
293enum BlockModeBitPosition {
294 ///Bit position in the BlockMode bitmap for ECB.
295 ECB_BIT_POS = 1,
296 ///Bit position in the BlockMode bitmap for CBC.
297 CBC_BIT_POS = 2,
298 ///Bit position in the BlockMode bitmap for CTR.
299 CTR_BIT_POS = 3,
300 ///Bit position in the BlockMode bitmap for GCM.
301 GCM_BIT_POS = 4,
302}
303
304/// Enum defining the bit position for each key purpose. Since key purpose can be repeatable in
305/// key parameters, it is represented using a bitmap.
306#[allow(non_camel_case_types)]
307#[repr(i32)]
308enum KeyPurposeBitPosition {
309 ///Bit position in the KeyPurpose bitmap for Encrypt.
310 ENCRYPT_BIT_POS = 1,
311 ///Bit position in the KeyPurpose bitmap for Decrypt.
312 DECRYPT_BIT_POS = 2,
313 ///Bit position in the KeyPurpose bitmap for Sign.
314 SIGN_BIT_POS = 3,
315 ///Bit position in the KeyPurpose bitmap for Verify.
316 VERIFY_BIT_POS = 4,
317 ///Bit position in the KeyPurpose bitmap for Wrap Key.
318 WRAP_KEY_BIT_POS = 5,
319 ///Bit position in the KeyPurpose bitmap for Agree Key.
320 AGREE_KEY_BIT_POS = 6,
321 ///Bit position in the KeyPurpose bitmap for Attest Key.
322 ATTEST_KEY_BIT_POS = 7,
323}