1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #define LOG_TAG "KeystoreOperation"
17
18 #include "key_creation_log_handler.h"
19 #include <statslog.h>
20
21 namespace keystore {
22
23 template <typename Tag>
getEnumTagValue(const AuthorizationSet & authorization_set,Tag tag)24 int32_t getEnumTagValue(const AuthorizationSet& authorization_set, Tag tag) {
25 auto tagValue = authorization_set.GetTagValue(tag);
26 if (tagValue.isOk()) {
27 static_assert(sizeof(decltype(tagValue.value())) <= sizeof(int32_t),
28 "Tag type value will be truncated, if cast to int32_t");
29 return static_cast<int32_t>(tagValue.value());
30 }
31 // Usually, if the value is not present, 0 is set. However, since 0 is a valid
32 // enum value, -1 is set for single enum fields.
33 return -1;
34 }
35
generateBitMapForPaddingModeValues(const AuthorizationSet & authorization_set)36 int32_t generateBitMapForPaddingModeValues(const AuthorizationSet& authorization_set) {
37 int32_t bitMap = 0;
38 int32_t tagValueCount = authorization_set.GetTagCount(TAG_PADDING);
39 if (tagValueCount == 0) {
40 // unlike in the single enum fields, if no value is provided,
41 // 0 is set for the bitmap
42 return bitMap;
43 }
44 int current_offset = -1;
45 while (tagValueCount > 0) {
46 current_offset = authorization_set.find(TAG_PADDING, current_offset);
47 KeyParameter keyParam = authorization_set[current_offset];
48 auto tagValue = accessTagValue(TAG_PADDING, keyParam);
49 switch (tagValue) {
50 case PaddingMode::NONE:
51 bitMap |= (1 << NONE_BIT_POS);
52 break;
53 case PaddingMode::RSA_OAEP:
54 bitMap |= (1 << PaddingModeBitPosition::RSA_OAEP_BIT_POS);
55 break;
56 case PaddingMode::RSA_PSS:
57 bitMap |= (1 << PaddingModeBitPosition::RSA_PSS_BIT_POS);
58 break;
59 case PaddingMode::RSA_PKCS1_1_5_ENCRYPT:
60 bitMap |= (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_ENCRYPT_BIT_POS);
61 break;
62 case PaddingMode::RSA_PKCS1_1_5_SIGN:
63 bitMap |= (1 << PaddingModeBitPosition::RSA_PKCS1_1_5_SIGN_BIT_POS);
64 break;
65 case PaddingMode::PKCS7:
66 bitMap |= (1 << PaddingModeBitPosition::PKCS7_BIT_POS);
67 break;
68 default:
69 break;
70 }
71 tagValueCount -= 1;
72 }
73 return bitMap;
74 }
75
generateBitMapForDigestValues(const AuthorizationSet & authorization_set)76 int32_t generateBitMapForDigestValues(const AuthorizationSet& authorization_set) {
77 int32_t bitMap = 0;
78 int32_t tagValueCount = authorization_set.GetTagCount(TAG_DIGEST);
79 if (tagValueCount == 0) {
80 // unlike in the single enum fields, if no value is provided,
81 // 0 is set for the bitmap
82 return bitMap;
83 }
84 int current_offset = -1;
85 while (tagValueCount > 0) {
86 current_offset = authorization_set.find(TAG_DIGEST, current_offset);
87 KeyParameter keyParam = authorization_set[current_offset];
88 auto tagValue = accessTagValue(TAG_DIGEST, keyParam);
89 switch (tagValue) {
90 case Digest::NONE:
91 bitMap |= (1 << NONE_BIT_POS);
92 break;
93 case Digest::MD5:
94 bitMap |= (1 << DigestBitPosition::MD5_BIT_POS);
95 break;
96 case Digest::SHA1:
97 bitMap |= (1 << DigestBitPosition::SHA1_BIT_POS);
98 break;
99 case Digest::SHA_2_224:
100 bitMap |= (1 << DigestBitPosition::SHA_2_224_BIT_POS);
101 break;
102 case Digest::SHA_2_256:
103 bitMap |= (1 << DigestBitPosition::SHA_2_256_BIT_POS);
104 break;
105 case Digest::SHA_2_384:
106 bitMap |= (1 << DigestBitPosition::SHA_2_384_BIT_POS);
107 break;
108 case Digest::SHA_2_512:
109 bitMap |= (1 << DigestBitPosition::SHA_2_512_BIT_POS);
110 break;
111 default:
112 break;
113 }
114 tagValueCount -= 1;
115 }
116 return bitMap;
117 }
118
generateBitMapForBlockModeValues(const AuthorizationSet & authorization_set)119 int32_t generateBitMapForBlockModeValues(const AuthorizationSet& authorization_set) {
120 int32_t bitMap = 0;
121 int32_t tagValueCount = authorization_set.GetTagCount(TAG_BLOCK_MODE);
122 if (tagValueCount == 0) {
123 // unlike in the single enum fields, if no value is provided,
124 // 0 is set for the bitmap
125 return bitMap;
126 }
127 int current_offset = -1;
128 while (tagValueCount > 0) {
129 current_offset = authorization_set.find(TAG_BLOCK_MODE, current_offset);
130 KeyParameter keyParam = authorization_set[current_offset];
131 auto tagValue = accessTagValue(TAG_BLOCK_MODE, keyParam);
132 switch (tagValue) {
133 case BlockMode::ECB:
134 bitMap |= (1 << BlockModeBitPosition::ECB_BIT_POS);
135 break;
136 case BlockMode::CBC:
137 bitMap |= (1 << BlockModeBitPosition::CBC_BIT_POS);
138 break;
139 case BlockMode::CTR:
140 bitMap |= (1 << BlockModeBitPosition::CTR_BIT_POS);
141 break;
142 case BlockMode::GCM:
143 bitMap |= (1 << BlockModeBitPosition::GCM_BIT_POS);
144 break;
145 default:
146 break;
147 }
148 tagValueCount -= 1;
149 }
150 return bitMap;
151 }
152
generateBitMapForKeyPurposeValues(const AuthorizationSet & authorization_set)153 int32_t generateBitMapForKeyPurposeValues(const AuthorizationSet& authorization_set) {
154 int32_t bitMap = 0;
155 int32_t tagValueCount = authorization_set.GetTagCount(TAG_PURPOSE);
156 if (tagValueCount == 0) {
157 // unlike in the single enum fields, if no value is provided,
158 // 0 is set for the bitmap
159 return bitMap;
160 }
161 int current_offset = -1;
162 while (tagValueCount > 0) {
163 current_offset = authorization_set.find(TAG_PURPOSE, current_offset);
164 KeyParameter keyParam = authorization_set[current_offset];
165 auto tagValue = accessTagValue(TAG_PURPOSE, keyParam);
166 switch (tagValue) {
167 case KeyPurpose::ENCRYPT:
168 bitMap |= (1 << KeyPurposeBitPosition::ENCRYPT_BIT_POS);
169 break;
170 case KeyPurpose::DECRYPT:
171 bitMap |= (1 << KeyPurposeBitPosition::DECRYPT_BIT_POS);
172 break;
173 case KeyPurpose::SIGN:
174 bitMap |= (1 << KeyPurposeBitPosition::SIGN_BIT_POS);
175 break;
176 case KeyPurpose::VERIFY:
177 bitMap |= (1 << KeyPurposeBitPosition::VERIFY_BIT_POS);
178 break;
179 case KeyPurpose::WRAP_KEY:
180 bitMap |= (1 << KeyPurposeBitPosition::WRAP_KEY_BIT_POS);
181 break;
182 default:
183 break;
184 }
185 tagValueCount -= 1;
186 }
187 return bitMap;
188 }
189
logKeystoreKeyCreationEvent(const hidl_vec<KeyParameter> & keyParams,bool wasCreationSuccessful,int32_t errorCode)190 void logKeystoreKeyCreationEvent(const hidl_vec<KeyParameter>& keyParams,
191 bool wasCreationSuccessful, int32_t errorCode) {
192 AuthorizationSet authorization_set(keyParams);
193 authorization_set.Deduplicate();
194
195 android::util::stats_write(android::util::KEYSTORE_KEY_EVENT_REPORTED,
196 getEnumTagValue(authorization_set, TAG_ALGORITHM),
197 getEnumTagValue(authorization_set, TAG_KEY_SIZE),
198 getEnumTagValue(authorization_set, TAG_ORIGIN),
199 getEnumTagValue(authorization_set, TAG_USER_AUTH_TYPE),
200 getEnumTagValue(authorization_set, TAG_AUTH_TIMEOUT),
201 generateBitMapForPaddingModeValues(authorization_set),
202 generateBitMapForDigestValues(authorization_set),
203 generateBitMapForBlockModeValues(authorization_set),
204 generateBitMapForKeyPurposeValues(authorization_set),
205 getEnumTagValue(authorization_set, TAG_EC_CURVE),
206 getEnumTagValue(authorization_set, TAG_BLOB_USAGE_REQUIREMENTS),
207 android::util::KEYSTORE_KEY_EVENT_REPORTED__TYPE__KEY_CREATION,
208 wasCreationSuccessful, errorCode);
209 }
210
211 } // namespace keystore
212