1 /*
2 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "fingerprint_auth_all_in_one_executor_hdi_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20
21 #include "parcel.h"
22
23 #include "iam_check.h"
24 #include "iam_fuzz_test.h"
25 #include "iam_logger.h"
26 #include "iam_ptr.h"
27
28 #include "fingerprint_auth_all_in_one_executor_hdi.h"
29
30 #define LOG_TAG "FINGERPRINT_AUTH_SA"
31
32 #undef private
33
34 using namespace std;
35 using namespace OHOS::UserIam::Common;
36 using namespace OHOS::UserIam::UserAuth;
37
38 namespace OHOS {
39 namespace UserIam {
40 namespace FingerprintAuth {
41 namespace {
42 constexpr uint32_t MAX_VECTOR_LEN = 100;
43 class DummyExecutorProxy : public IAllInOneExecutor {
44 public:
DummyExecutorProxy()45 DummyExecutorProxy() : fuzzParcel_(nullptr)
46 {
47 }
48
49 virtual ~DummyExecutorProxy() = default;
50
GetExecutorInfo(ExecutorInfo & executorInfo)51 int32_t GetExecutorInfo(ExecutorInfo &executorInfo)
52 {
53 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
54 FillFuzzHdiExecutorInfo(*fuzzParcel_, executorInfo);
55 return (*fuzzParcel_).ReadInt32();
56 }
57
OnRegisterFinish(const std::vector<uint64_t> & templateIdList,const std::vector<uint8_t> & frameworkPublicKey,const std::vector<uint8_t> & extraInfo)58 int32_t OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
59 const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
60 {
61 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
62 return (*fuzzParcel_).ReadInt32();
63 }
64
Enroll(uint64_t scheduleId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)65 int32_t Enroll(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo,
66 const sptr<IExecutorCallback> &callbackObj)
67 {
68 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
69 return (*fuzzParcel_).ReadInt32();
70 }
71
Authenticate(uint64_t scheduleId,const std::vector<uint64_t> & templateIdList,bool endAfterFirstFail,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)72 int32_t Authenticate(uint64_t scheduleId, const std::vector<uint64_t> &templateIdList, bool endAfterFirstFail,
73 const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
74 {
75 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
76 return (*fuzzParcel_).ReadInt32();
77 }
78
Identify(uint64_t scheduleId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)79 int32_t Identify(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo,
80 const sptr<IExecutorCallback> &callbackObj)
81 {
82 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
83 return (*fuzzParcel_).ReadInt32();
84 }
85
Delete(const std::vector<uint64_t> & templateIdList)86 int32_t Delete(const std::vector<uint64_t> &templateIdList)
87 {
88 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
89 return (*fuzzParcel_).ReadInt32();
90 }
91
Cancel(uint64_t scheduleId)92 int32_t Cancel(uint64_t scheduleId)
93 {
94 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
95 return (*fuzzParcel_).ReadInt32();
96 }
97
SendCommand(int32_t commandId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)98 int32_t SendCommand(int32_t commandId, const std::vector<uint8_t> &extraInfo,
99 const sptr<IExecutorCallback> &callbackObj)
100 {
101 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
102 return (*fuzzParcel_).ReadInt32();
103 }
104
SendMessage(uint64_t scheduleId,int32_t srcRole,const std::vector<uint8_t> & msg)105 int32_t SendMessage(uint64_t scheduleId, int32_t srcRole, const std::vector<uint8_t> &msg)
106 {
107 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
108 return (*fuzzParcel_).ReadInt32();
109 }
110
GetProperty(const std::vector<uint64_t> & templateIdList,const std::vector<int32_t> & propertyTypes,Property & property)111 int32_t GetProperty(const std::vector<uint64_t> &templateIdList, const std::vector<int32_t> &propertyTypes,
112 Property &property)
113 {
114 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
115 FillFuzzHdiProperty(*fuzzParcel_, property);
116 return (*fuzzParcel_).ReadInt32();
117 }
118
SetCachedTemplates(const std::vector<uint64_t> & templateIdList)119 int32_t SetCachedTemplates(const std::vector<uint64_t> &templateIdList)
120 {
121 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
122 return (*fuzzParcel_).ReadInt32();
123 }
124
RegisterSaCommandCallback(const sptr<ISaCommandCallback> & callbackObj)125 int32_t RegisterSaCommandCallback(const sptr<ISaCommandCallback> &callbackObj)
126 {
127 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
128 callbackObj_ = callbackObj;
129 return (*fuzzParcel_).ReadInt32();
130 }
131
SetParcel(Parcel & parcel)132 void SetParcel(Parcel &parcel)
133 {
134 fuzzParcel_ = &parcel;
135 }
136
ClearParcel()137 void ClearParcel()
138 {
139 fuzzParcel_ = nullptr;
140 }
141
FuzzTriggerSaCommandCallback(Parcel & parcel)142 void FuzzTriggerSaCommandCallback(Parcel &parcel)
143 {
144 if (callbackObj_ == nullptr) {
145 return;
146 }
147
148 std::vector<SaCommand> commands;
149 FillFuzzSaCommandVector(parcel, commands);
150 callbackObj_->OnSaCommands(commands);
151 }
152
153 private:
FillFuzzHdiExecutorInfo(Parcel & parcel,ExecutorInfo & executorInfo)154 void FillFuzzHdiExecutorInfo(Parcel &parcel, ExecutorInfo &executorInfo)
155 {
156 executorInfo.sensorId = parcel.ReadUint16();
157 executorInfo.executorMatcher = parcel.ReadUint32();
158 executorInfo.executorRole = static_cast<ExecutorRole>(parcel.ReadInt32());
159 executorInfo.authType = static_cast<AuthType>(parcel.ReadInt32());
160 executorInfo.esl = static_cast<ExecutorSecureLevel>(parcel.ReadInt32());
161 executorInfo.maxTemplateAcl = parcel.ReadInt32();
162 FillFuzzUint8Vector(parcel, executorInfo.publicKey);
163 FillFuzzUint8Vector(parcel, executorInfo.extraInfo);
164 IAM_LOGI("success");
165 }
166
FillFuzzHdiProperty(Parcel & parcel,Property & property)167 void FillFuzzHdiProperty(Parcel &parcel, Property &property)
168 {
169 property.authSubType = parcel.ReadUint64();
170 property.lockoutDuration = parcel.ReadInt32();
171 property.remainAttempts = parcel.ReadInt32();
172 FillFuzzString(parcel, property.enrollmentProgress);
173 FillFuzzString(parcel, property.sensorInfo);
174
175 IAM_LOGI("success");
176 }
177
FillFuzzSaCommand(Parcel & parcel,SaCommand & command)178 void FillFuzzSaCommand(Parcel &parcel, SaCommand &command)
179 {
180 command.id = static_cast<SaCommandId>(parcel.ReadInt32());
181 IAM_LOGI("success");
182 }
183
FillFuzzSaCommandVector(Parcel & parcel,std::vector<SaCommand> & commands)184 void FillFuzzSaCommandVector(Parcel &parcel, std::vector<SaCommand> &commands)
185 {
186 uint32_t len = parcel.ReadUint32() % MAX_VECTOR_LEN;
187 commands.resize(len);
188 for (uint32_t i = 0; i < len; i++) {
189 FillFuzzSaCommand(parcel, commands[i]);
190 }
191 IAM_LOGI("success");
192 }
193
194 Parcel *fuzzParcel_;
195 sptr<ISaCommandCallback> callbackObj_ { nullptr };
196 };
197
198 class DummyExecuteCallback : public UserAuth::IExecuteCallback {
199 public:
200 virtual ~DummyExecuteCallback() = default;
201
OnResult(ResultCode result,const std::vector<uint8_t> & extraInfo)202 void OnResult(ResultCode result, const std::vector<uint8_t> &extraInfo) override
203 {
204 }
205
OnResult(ResultCode result)206 void OnResult(ResultCode result) override
207 {
208 }
209
OnAcquireInfo(int32_t acquire,const std::vector<uint8_t> & extraInfo)210 void OnAcquireInfo(int32_t acquire, const std::vector<uint8_t> &extraInfo) override
211 {
212 }
213
OnMessage(int destRole,const std::vector<uint8_t> & msg)214 void OnMessage(int destRole, const std::vector<uint8_t> &msg) override
215 {}
216 };
217
218 auto g_proxy = new (nothrow) DummyExecutorProxy();
219 auto g_hdi = Common::MakeShared<FingerprintAllInOneExecutorHdi>(g_proxy);
220
FillFuzzExecutorInfo(Parcel & parcel,UserAuth::ExecutorInfo & executorInfo)221 void FillFuzzExecutorInfo(Parcel &parcel, UserAuth::ExecutorInfo &executorInfo)
222 {
223 executorInfo.executorSensorHint = parcel.ReadInt32();
224 executorInfo.authType = static_cast<UserAuth::AuthType>(parcel.ReadInt32());
225 executorInfo.executorRole = static_cast<UserAuth::ExecutorRole>(parcel.ReadInt32());
226 executorInfo.executorMatcher = parcel.ReadInt32();
227 executorInfo.esl = static_cast<UserAuth::ExecutorSecureLevel>(parcel.ReadInt32());
228 FillFuzzUint8Vector(parcel, executorInfo.publicKey);
229 IAM_LOGI("success");
230 }
231
FillFuzzIExecuteCallback(Parcel & parcel,std::shared_ptr<UserAuth::IExecuteCallback> & callback)232 void FillFuzzIExecuteCallback(Parcel &parcel, std::shared_ptr<UserAuth::IExecuteCallback> &callback)
233 {
234 callback = nullptr;
235 if (parcel.ReadBool()) {
236 callback = MakeShared<DummyExecuteCallback>();
237 if (callback == nullptr) {
238 IAM_LOGE("callback is nullptr");
239 }
240 }
241 IAM_LOGI("success");
242 }
243
FillFuzzAttributeKeyVector(Parcel & parcel,std::vector<UserAuth::Attributes::AttributeKey> & keys)244 void FillFuzzAttributeKeyVector(Parcel &parcel, std::vector<UserAuth::Attributes::AttributeKey> &keys)
245 {
246 std::vector<uint32_t> vals;
247 FillFuzzUint32Vector(parcel, vals);
248 for (const auto &val : vals) {
249 keys.push_back(static_cast<UserAuth::Attributes::AttributeKey>(val));
250 }
251
252 IAM_LOGI("success");
253 }
254
FuzzGetExecutorInfo(Parcel & parcel)255 void FuzzGetExecutorInfo(Parcel &parcel)
256 {
257 IAM_LOGI("begin");
258 UserAuth::ExecutorInfo info;
259 FillFuzzExecutorInfo(parcel, info);
260 g_hdi->GetExecutorInfo(info);
261 IAM_LOGI("end");
262 }
263
FuzzOnRegisterFinish(Parcel & parcel)264 void FuzzOnRegisterFinish(Parcel &parcel)
265 {
266 IAM_LOGI("begin");
267 std::vector<uint64_t> templateIdList;
268 FillFuzzUint64Vector(parcel, templateIdList);
269 std::vector<uint8_t> frameworkPublicKey;
270 FillFuzzUint8Vector(parcel, frameworkPublicKey);
271 std::vector<uint8_t> extraInfo;
272 FillFuzzUint8Vector(parcel, extraInfo);
273 g_hdi->OnRegisterFinish(templateIdList, frameworkPublicKey, extraInfo);
274 IAM_LOGI("end");
275 }
276
FuzzEnroll(Parcel & parcel)277 void FuzzEnroll(Parcel &parcel)
278 {
279 IAM_LOGI("begin");
280 uint64_t scheduleId = parcel.ReadUint64();
281 uint32_t tokenId = parcel.ReadUint32();
282 std::vector<uint8_t> extraInfo;
283 FillFuzzUint8Vector(parcel, extraInfo);
284 std::shared_ptr<UserAuth::IExecuteCallback> callbackObj;
285 FillFuzzIExecuteCallback(parcel, callbackObj);
286 g_hdi->Enroll(scheduleId, EnrollParam { tokenId, extraInfo }, callbackObj);
287 IAM_LOGI("end");
288 }
289
FuzzAuthenticate(Parcel & parcel)290 void FuzzAuthenticate(Parcel &parcel)
291 {
292 IAM_LOGI("begin");
293 uint64_t scheduleId = parcel.ReadUint64();
294 uint32_t tokenId = parcel.ReadUint32();
295 std::vector<uint64_t> templateIdList;
296 FillFuzzUint64Vector(parcel, templateIdList);
297 std::vector<uint8_t> extraInfo;
298 FillFuzzUint8Vector(parcel, extraInfo);
299 std::shared_ptr<UserAuth::IExecuteCallback> callbackObj;
300 FillFuzzIExecuteCallback(parcel, callbackObj);
301 bool endAfterFirstFail = parcel.ReadBool();
302 g_hdi->Authenticate(scheduleId, AuthenticateParam { tokenId, templateIdList, extraInfo, endAfterFirstFail },
303 callbackObj);
304 IAM_LOGI("end");
305 }
306
FuzzIdentify(Parcel & parcel)307 void FuzzIdentify(Parcel &parcel)
308 {
309 IAM_LOGI("begin");
310 uint64_t scheduleId = parcel.ReadUint64();
311 uint32_t tokenId = parcel.ReadUint32();
312 std::vector<uint8_t> extraInfo;
313 FillFuzzUint8Vector(parcel, extraInfo);
314 std::shared_ptr<UserAuth::IExecuteCallback> callbackObj;
315 FillFuzzIExecuteCallback(parcel, callbackObj);
316 g_hdi->Identify(scheduleId, IdentifyParam { tokenId, extraInfo }, callbackObj);
317 IAM_LOGI("end");
318 }
319
FuzzDelete(Parcel & parcel)320 void FuzzDelete(Parcel &parcel)
321 {
322 IAM_LOGI("begin");
323 std::vector<uint64_t> templateIdList;
324 FillFuzzUint64Vector(parcel, templateIdList);
325 g_hdi->Delete(templateIdList);
326 IAM_LOGI("end");
327 }
328
FuzzCancel(Parcel & parcel)329 void FuzzCancel(Parcel &parcel)
330 {
331 IAM_LOGI("begin");
332 uint64_t scheduleId = parcel.ReadUint64();
333 g_hdi->Cancel(scheduleId);
334 IAM_LOGI("end");
335 }
336
FuzzSendCommand(Parcel & parcel)337 void FuzzSendCommand(Parcel &parcel)
338 {
339 IAM_LOGI("begin");
340 PropertyMode commandId = static_cast<PropertyMode>(parcel.ReadInt32());
341 std::vector<uint8_t> extraInfo;
342 FillFuzzUint8Vector(parcel, extraInfo);
343 std::shared_ptr<UserAuth::IExecuteCallback> callbackObj;
344 FillFuzzIExecuteCallback(parcel, callbackObj);
345 g_hdi->SendCommand(commandId, extraInfo, callbackObj);
346 IAM_LOGI("end");
347 }
348
FuzzGetProperty(Parcel & parcel)349 void FuzzGetProperty(Parcel &parcel)
350 {
351 IAM_LOGI("begin");
352 std::vector<uint64_t> templateIdList;
353 FillFuzzUint64Vector(parcel, templateIdList);
354 std::vector<UserAuth::Attributes::AttributeKey> keys;
355 FillFuzzAttributeKeyVector(parcel, keys);
356 UserAuth::Property property;
357 g_hdi->GetProperty(templateIdList, keys, property);
358 IAM_LOGI("end");
359 }
360
FuzzSetCachedTemplates(Parcel & parcel)361 void FuzzSetCachedTemplates(Parcel &parcel)
362 {
363 IAM_LOGI("begin");
364 std::vector<uint64_t> templateIdList;
365 FillFuzzUint64Vector(parcel, templateIdList);
366 g_hdi->SetCachedTemplates(templateIdList);
367 IAM_LOGI("end");
368 }
369
FuzzSendMessage(Parcel & parcel)370 void FuzzSendMessage(Parcel &parcel)
371 {
372 IAM_LOGI("begin");
373 IAM_LOGI("end");
374 }
375
FuzzTriggerSaCommandCallback(Parcel & parcel)376 void FuzzTriggerSaCommandCallback(Parcel &parcel)
377 {
378 IAM_LOGI("begin");
379 g_proxy->FuzzTriggerSaCommandCallback(parcel);
380 IAM_LOGI("end");
381 }
382
SetProxyParcel(Parcel & parcel)383 void SetProxyParcel(Parcel &parcel)
384 {
385 if (g_proxy == nullptr) {
386 IAM_LOGE("g_proxy is nullptr");
387 return;
388 }
389 g_proxy->SetParcel(parcel);
390 }
391
ClearProxyParcel()392 void ClearProxyParcel()
393 {
394 if (g_proxy == nullptr) {
395 IAM_LOGE("g_proxy is nullptr");
396 return;
397 }
398 g_proxy->ClearParcel();
399 }
400
401 using FuzzFunc = decltype(FuzzGetExecutorInfo);
402 FuzzFunc *g_fuzzFuncs[] = { FuzzGetExecutorInfo, FuzzOnRegisterFinish, FuzzEnroll, FuzzAuthenticate, FuzzIdentify,
403 FuzzDelete, FuzzCancel, FuzzSendCommand, FuzzGetProperty, FuzzSetCachedTemplates, FuzzTriggerSaCommandCallback,
404 FuzzSendMessage };
405
FingerprintAuthServiceFuzzTest(const uint8_t * data,size_t size)406 void FingerprintAuthServiceFuzzTest(const uint8_t *data, size_t size)
407 {
408 Parcel parcel;
409 parcel.WriteBuffer(data, size);
410 parcel.RewindRead(0);
411 uint32_t index = parcel.ReadUint32() % (sizeof(g_fuzzFuncs) / sizeof(FuzzFunc *));
412 auto fuzzFunc = g_fuzzFuncs[index];
413 SetProxyParcel(parcel);
414 fuzzFunc(parcel);
415 ClearProxyParcel();
416 return;
417 }
418 } // namespace
419 } // namespace FingerprintAuth
420 } // namespace UserIam
421 } // namespace OHOS
422
423 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)424 extern "C" int32_t LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
425 {
426 OHOS::UserIam::FingerprintAuth::FingerprintAuthServiceFuzzTest(data, size);
427 return 0;
428 }
429