• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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