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