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