1 /*
2  * Copyright (C) 2024 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  */
17 #include <keymint_common.h>
18 #include <fstream>
19 
20 namespace android::hardware::security::keymint_support::fuzzer {
21 
22 constexpr size_t kMinAction = 0;
23 constexpr size_t kMaxAction = 10;
24 constexpr size_t kMinKeyParameter = 1;
25 constexpr size_t kMaxKeyParameter = 10;
26 
27 constexpr Tag kTagArray[] = {Tag::INVALID,
28                              Tag::PURPOSE,
29                              Tag::ALGORITHM,
30                              Tag::KEY_SIZE,
31                              Tag::BLOCK_MODE,
32                              Tag::DIGEST,
33                              Tag::PADDING,
34                              Tag::CALLER_NONCE,
35                              Tag::MIN_MAC_LENGTH,
36                              Tag::EC_CURVE,
37                              Tag::RSA_PUBLIC_EXPONENT,
38                              Tag::INCLUDE_UNIQUE_ID,
39                              Tag::RSA_OAEP_MGF_DIGEST,
40                              Tag::BOOTLOADER_ONLY,
41                              Tag::ROLLBACK_RESISTANCE,
42                              Tag::HARDWARE_TYPE,
43                              Tag::EARLY_BOOT_ONLY,
44                              Tag::ACTIVE_DATETIME,
45                              Tag::ORIGINATION_EXPIRE_DATETIME,
46                              Tag::USAGE_EXPIRE_DATETIME,
47                              Tag::MIN_SECONDS_BETWEEN_OPS,
48                              Tag::MAX_USES_PER_BOOT,
49                              Tag::USAGE_COUNT_LIMIT,
50                              Tag::USER_ID,
51                              Tag::USER_SECURE_ID,
52                              Tag::NO_AUTH_REQUIRED,
53                              Tag::USER_AUTH_TYPE,
54                              Tag::AUTH_TIMEOUT,
55                              Tag::ALLOW_WHILE_ON_BODY,
56                              Tag::TRUSTED_USER_PRESENCE_REQUIRED,
57                              Tag::TRUSTED_CONFIRMATION_REQUIRED,
58                              Tag::UNLOCKED_DEVICE_REQUIRED,
59                              Tag::APPLICATION_ID,
60                              Tag::APPLICATION_DATA,
61                              Tag::CREATION_DATETIME,
62                              Tag::ORIGIN,
63                              Tag::ROOT_OF_TRUST,
64                              Tag::OS_VERSION,
65                              Tag::OS_PATCHLEVEL,
66                              Tag::UNIQUE_ID,
67                              Tag::ATTESTATION_CHALLENGE,
68                              Tag::ATTESTATION_APPLICATION_ID,
69                              Tag::ATTESTATION_ID_BRAND,
70                              Tag::ATTESTATION_ID_DEVICE,
71                              Tag::ATTESTATION_ID_PRODUCT,
72                              Tag::ATTESTATION_ID_SERIAL,
73                              Tag::ATTESTATION_ID_IMEI,
74                              Tag::ATTESTATION_ID_MEID,
75                              Tag::ATTESTATION_ID_MANUFACTURER,
76                              Tag::ATTESTATION_ID_MODEL,
77                              Tag::VENDOR_PATCHLEVEL,
78                              Tag::BOOT_PATCHLEVEL,
79                              Tag::DEVICE_UNIQUE_ATTESTATION,
80                              Tag::IDENTITY_CREDENTIAL_KEY,
81                              Tag::STORAGE_KEY,
82                              Tag::ASSOCIATED_DATA,
83                              Tag::NONCE,
84                              Tag::MAC_LENGTH,
85                              Tag::RESET_SINCE_ID_ROTATION,
86                              Tag::CONFIRMATION_TOKEN,
87                              Tag::CERTIFICATE_SERIAL,
88                              Tag::CERTIFICATE_SUBJECT,
89                              Tag::CERTIFICATE_NOT_BEFORE,
90                              Tag::CERTIFICATE_NOT_AFTER,
91                              Tag::MAX_BOOT_LEVEL};
92 
93 class KeyMintAuthSetFuzzer {
94   public:
KeyMintAuthSetFuzzer(const uint8_t * data,size_t size)95     KeyMintAuthSetFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
96     void process();
97 
98   private:
99     FuzzedDataProvider mFdp;
100 };
101 
process()102 void KeyMintAuthSetFuzzer::process() {
103     AuthorizationSet authSet = createAuthorizationSet(&mFdp);
104     while (mFdp.remaining_bytes()) {
105         auto invokeAuthSetAPI = mFdp.PickValueInArray<const std::function<void()>>({
106                 [&]() { authSet.Sort(); },
107                 [&]() { authSet.Deduplicate(); },
108                 [&]() { authSet.Union(createAuthorizationSet(&mFdp)); },
109                 [&]() { authSet.Subtract(createAuthorizationSet(&mFdp)); },
110                 [&]() {  // invoke push_back()
111                     AuthorizationSetBuilder builder = AuthorizationSetBuilder();
112                     for (const KeyParameter& tag : authSet) {
113                         builder.push_back(tag);
114                     }
115                     AuthorizationSet params = createAuthorizationSet(&mFdp);
116                     authSet.push_back(params);
117                 },
118                 [&]() {  // invoke copy constructor
119                     auto params = AuthorizationSetBuilder().Authorizations(authSet);
120                     authSet = params;
121                 },
122                 [&]() {  // invoke move constructor
123                     auto params = AuthorizationSetBuilder().Authorizations(authSet);
124                     authSet = std::move(params);
125                 },
126                 [&]() {  // invoke Constructor from vector<KeyParameter>
127                     vector<KeyParameter> keyParam;
128                     size_t numKeyParam =
129                             mFdp.ConsumeIntegralInRange<size_t>(kMinKeyParameter, kMaxKeyParameter);
130                     keyParam.resize(numKeyParam);
131                     for (size_t idx = 0; idx < numKeyParam - 1; ++idx) {
132                         keyParam[idx].tag = mFdp.PickValueInArray(kTagArray);
133                     }
134                     if (mFdp.ConsumeBool()) {
135                         AuthorizationSet auths(keyParam);
136                         auths.push_back(AuthorizationSet(keyParam));
137                     } else {  // invoke operator=
138                         AuthorizationSet auths = keyParam;
139                     }
140                 },
141                 [&]() {  // invoke 'Contains()'
142                     Tag tag = Tag::INVALID;
143                     if (authSet.size() > 0) {
144                         tag = authSet[mFdp.ConsumeIntegralInRange<size_t>(0, authSet.size() - 1)]
145                                       .tag;
146                     }
147                     authSet.Contains(mFdp.ConsumeBool() ? tag : mFdp.PickValueInArray(kTagArray));
148                 },
149                 [&]() {  // invoke 'GetTagCount()'
150                     Tag tag = Tag::INVALID;
151                     if (authSet.size() > 0) {
152                         tag = authSet[mFdp.ConsumeIntegralInRange<size_t>(0, authSet.size() - 1)]
153                                       .tag;
154                     }
155                     authSet.GetTagCount(mFdp.ConsumeBool() ? tag
156                                                            : mFdp.PickValueInArray(kTagArray));
157                 },
158                 [&]() {  // invoke 'erase()'
159                     if (authSet.size() > 0) {
160                         authSet.erase(mFdp.ConsumeIntegralInRange<size_t>(0, authSet.size() - 1));
161                     }
162                 },
163         });
164         invokeAuthSetAPI();
165     }
166     authSet.Clear();
167 }
168 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)169 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
170     KeyMintAuthSetFuzzer kmAuthSetFuzzer(data, size);
171     kmAuthSetFuzzer.process();
172     return 0;
173 }
174 
175 }  // namespace android::hardware::security::keymint_support::fuzzer
176