1 /*
2  * Copyright (C) 2021 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 <fstream>
18 #include "keymaster4_common.h"
19 
20 namespace android::hardware::keymaster::V4_0::fuzzer {
21 
22 constexpr size_t kMaxVectorSize = 100;
23 constexpr size_t kMaxKeyParameter = 10;
24 
25 constexpr Tag kTagArray[] = {Tag::INVALID,
26                              Tag::PURPOSE,
27                              Tag::ALGORITHM,
28                              Tag::KEY_SIZE,
29                              Tag::BLOCK_MODE,
30                              Tag::DIGEST,
31                              Tag::PADDING,
32                              Tag::CALLER_NONCE,
33                              Tag::MIN_MAC_LENGTH,
34                              Tag::EC_CURVE,
35                              Tag::RSA_PUBLIC_EXPONENT,
36                              Tag::INCLUDE_UNIQUE_ID,
37                              Tag::BLOB_USAGE_REQUIREMENTS,
38                              Tag::BOOTLOADER_ONLY,
39                              Tag::ROLLBACK_RESISTANCE,
40                              Tag::HARDWARE_TYPE,
41                              Tag::ACTIVE_DATETIME,
42                              Tag::ORIGINATION_EXPIRE_DATETIME,
43                              Tag::USAGE_EXPIRE_DATETIME,
44                              Tag::MIN_SECONDS_BETWEEN_OPS,
45                              Tag::MAX_USES_PER_BOOT,
46                              Tag::USER_ID,
47                              Tag::USER_SECURE_ID,
48                              Tag::NO_AUTH_REQUIRED,
49                              Tag::USER_AUTH_TYPE,
50                              Tag::AUTH_TIMEOUT,
51                              Tag::ALLOW_WHILE_ON_BODY,
52                              Tag::TRUSTED_USER_PRESENCE_REQUIRED,
53                              Tag::TRUSTED_CONFIRMATION_REQUIRED,
54                              Tag::UNLOCKED_DEVICE_REQUIRED,
55                              Tag::APPLICATION_ID,
56                              Tag::APPLICATION_DATA,
57                              Tag::CREATION_DATETIME,
58                              Tag::ORIGIN,
59                              Tag::ROOT_OF_TRUST,
60                              Tag::OS_VERSION,
61                              Tag::OS_PATCHLEVEL,
62                              Tag::UNIQUE_ID,
63                              Tag::ATTESTATION_CHALLENGE,
64                              Tag::ATTESTATION_APPLICATION_ID,
65                              Tag::ATTESTATION_ID_BRAND,
66                              Tag::ATTESTATION_ID_DEVICE,
67                              Tag::ATTESTATION_ID_PRODUCT,
68                              Tag::ATTESTATION_ID_SERIAL,
69                              Tag::ATTESTATION_ID_IMEI,
70                              Tag::ATTESTATION_ID_MEID,
71                              Tag::ATTESTATION_ID_MANUFACTURER,
72                              Tag::ATTESTATION_ID_MODEL,
73                              Tag::VENDOR_PATCHLEVEL,
74                              Tag::BOOT_PATCHLEVEL,
75                              Tag::ASSOCIATED_DATA,
76                              Tag::NONCE,
77                              Tag::MAC_LENGTH,
78                              Tag::RESET_SINCE_ID_ROTATION,
79                              Tag::CONFIRMATION_TOKEN};
80 
81 class KeyMaster4AuthSetFuzzer {
82   public:
83     void process(const uint8_t* data, size_t size);
84 
85   private:
86     void invokeAuthSetAPIs();
87     std::unique_ptr<FuzzedDataProvider> mFdp = nullptr;
88 };
89 
90 /**
91  * @brief invokeAuthSetAPIs() function aims at calling functions of authorization_set.cpp
92  * and authorization_set.h in order to get a good coverage for libkeymaster4support.
93  */
invokeAuthSetAPIs()94 void KeyMaster4AuthSetFuzzer::invokeAuthSetAPIs() {
95     AuthorizationSet authSet = createAuthorizationSet(mFdp);
96     while (mFdp->remaining_bytes() > 0) {
97         uint32_t action = mFdp->ConsumeIntegralInRange<uint32_t>(0, 15);
98         switch (action) {
99             case 0: {
100                 authSet.Sort();
101             } break;
102             case 1: {
103                 authSet.Deduplicate();
104             } break;
105             case 2: {
106                 authSet.Union(createAuthorizationSet(mFdp));
107             } break;
108             case 3: {
109                 authSet.Subtract(createAuthorizationSet(mFdp));
110             } break;
111             case 4: {
112                 std::filebuf fbOut;
113                 fbOut.open("/dev/zero", std::ios::out);
114                 std::ostream out(&fbOut);
115                 authSet.Serialize(&out);
116             } break;
117             case 5: {
118                 std::filebuf fbIn;
119                 fbIn.open("/dev/zero", std::ios::in);
120                 std::istream in(&fbIn);
121                 authSet.Deserialize(&in);
122             } break;
123             case 6: {  // invoke push_back()
124                 AuthorizationSetBuilder builder = AuthorizationSetBuilder();
125                 for (const KeyParameter& tag : authSet) {
126                     builder.push_back(tag);
127                 }
128                 AuthorizationSet params = createAuthorizationSet(mFdp);
129                 authSet.push_back(params);
130             } break;
131             case 7: {  // invoke copy constructor
132                 auto params = AuthorizationSetBuilder().Authorizations(authSet);
133                 authSet = params;
134             } break;
135             case 8: {  // invoke move constructor
136                 auto params = AuthorizationSetBuilder().Authorizations(authSet);
137                 authSet = std::move(params);
138             } break;
139             case 9: {  // invoke Constructor from hidl_vec<KeyParameter>
140                 hidl_vec<KeyParameter> keyParam;
141                 size_t numKeyParam = mFdp->ConsumeIntegralInRange<size_t>(1, kMaxKeyParameter);
142                 keyParam.resize(numKeyParam);
143                 for (size_t i = 0; i < numKeyParam - 1; ++i) {
144                     keyParam[i].tag = mFdp->PickValueInArray(kTagArray);
145                     std::vector<uint8_t> dataVector = mFdp->ConsumeBytes<uint8_t>(
146                             mFdp->ConsumeIntegralInRange<size_t>(0, kMaxVectorSize));
147                     keyParam[i].blob = dataVector;
148                 }
149                 if (mFdp->ConsumeBool()) {
150                     AuthorizationSet auths(keyParam);
151                     auths.push_back(AuthorizationSet(keyParam));
152                 } else {  // invoke operator=
153                     AuthorizationSet auths = keyParam;
154                 }
155             } break;
156             case 10: {  // invoke 'Contains()'
157                 Tag tag;
158                 if (authSet.size() > 0) {
159                     tag = authSet[mFdp->ConsumeIntegralInRange<size_t>(0, authSet.size() - 1)].tag;
160                 }
161                 authSet.Contains(mFdp->ConsumeBool() ? tag : mFdp->PickValueInArray(kTagArray));
162             } break;
163             case 11: {  // invoke 'GetTagCount()'
164                 Tag tag;
165                 if (authSet.size() > 0) {
166                     tag = authSet[mFdp->ConsumeIntegralInRange<size_t>(0, authSet.size() - 1)].tag;
167                 }
168                 authSet.GetTagCount(mFdp->ConsumeBool() ? tag : mFdp->PickValueInArray(kTagArray));
169             } break;
170             case 12: {  // invoke 'empty()'
171                 authSet.empty();
172             } break;
173             case 13: {  // invoke 'data()'
174                 authSet.data();
175             } break;
176             case 14: {  // invoke 'hidl_data()'
177                 authSet.hidl_data();
178             } break;
179             case 15: {  // invoke 'erase()'
180                 if (authSet.size() > 0) {
181                     authSet.erase(mFdp->ConsumeIntegralInRange<size_t>(0, authSet.size() - 1));
182                 }
183             } break;
184             default:
185                 break;
186         };
187     }
188     authSet.Clear();
189 }
190 
process(const uint8_t * data,size_t size)191 void KeyMaster4AuthSetFuzzer::process(const uint8_t* data, size_t size) {
192     mFdp = std::make_unique<FuzzedDataProvider>(data, size);
193     invokeAuthSetAPIs();
194 }
195 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)196 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
197     KeyMaster4AuthSetFuzzer km4AuthSetFuzzer;
198     km4AuthSetFuzzer.process(data, size);
199     return 0;
200 }
201 
202 }  // namespace android::hardware::keymaster::V4_0::fuzzer
203