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_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_executor_hdi.h"
29
30 #define LOG_LABEL UserIam::Common::LABEL_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 IExecutor {
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
GetTemplateInfo(uint64_t templateId,TemplateInfo & templateInfo)58 int32_t GetTemplateInfo(uint64_t templateId, TemplateInfo &templateInfo)
59 {
60 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
61 FillFuzzHdiTemplateInfo(*fuzzParcel_, templateInfo);
62 return (*fuzzParcel_).ReadInt32();
63 }
64
OnRegisterFinish(const std::vector<uint64_t> & templateIdList,const std::vector<uint8_t> & frameworkPublicKey,const std::vector<uint8_t> & extraInfo)65 int32_t OnRegisterFinish(const std::vector<uint64_t> &templateIdList,
66 const std::vector<uint8_t> &frameworkPublicKey, const std::vector<uint8_t> &extraInfo)
67 {
68 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
69 return (*fuzzParcel_).ReadInt32();
70 }
71
Enroll(uint64_t scheduleId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)72 int32_t Enroll(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo,
73 const sptr<IExecutorCallback> &callbackObj)
74 {
75 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
76 return (*fuzzParcel_).ReadInt32();
77 }
78
Authenticate(uint64_t scheduleId,const std::vector<uint64_t> & templateIdList,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)79 int32_t Authenticate(uint64_t scheduleId, const std::vector<uint64_t> &templateIdList,
80 const std::vector<uint8_t> &extraInfo, const sptr<IExecutorCallback> &callbackObj)
81 {
82 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
83 return (*fuzzParcel_).ReadInt32();
84 }
85
AuthenticateV1_1(uint64_t scheduleId,const std::vector<uint64_t> & templateIdList,bool endAfterFirstFail,const std::vector<uint8_t> & extraInfo,const sptr<OHOS::HDI::FingerprintAuth::V1_0::IExecutorCallback> & callbackObj)86 int32_t AuthenticateV1_1(uint64_t scheduleId, const std::vector<uint64_t>& templateIdList,
87 bool endAfterFirstFail, const std::vector<uint8_t>& extraInfo,
88 const sptr<OHOS::HDI::FingerprintAuth::V1_0::IExecutorCallback>& callbackObj)
89 {
90 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
91 return (*fuzzParcel_).ReadInt32();
92 }
93
Identify(uint64_t scheduleId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)94 int32_t Identify(uint64_t scheduleId, const std::vector<uint8_t> &extraInfo,
95 const sptr<IExecutorCallback> &callbackObj)
96 {
97 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
98 return (*fuzzParcel_).ReadInt32();
99 }
100
Delete(const std::vector<uint64_t> & templateIdList)101 int32_t Delete(const std::vector<uint64_t> &templateIdList)
102 {
103 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
104 return (*fuzzParcel_).ReadInt32();
105 }
106
Cancel(uint64_t scheduleId)107 int32_t Cancel(uint64_t scheduleId)
108 {
109 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
110 return (*fuzzParcel_).ReadInt32();
111 }
112
SendCommand(int32_t commandId,const std::vector<uint8_t> & extraInfo,const sptr<IExecutorCallback> & callbackObj)113 int32_t SendCommand(int32_t commandId, const std::vector<uint8_t> &extraInfo,
114 const sptr<IExecutorCallback> &callbackObj)
115 {
116 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
117 return (*fuzzParcel_).ReadInt32();
118 }
119
GetProperty(const std::vector<uint64_t> & templateIdList,const std::vector<GetPropertyType> & propertyTypes,Property & property)120 int32_t GetProperty(const std::vector<uint64_t> &templateIdList, const std::vector<GetPropertyType> &propertyTypes,
121 Property &property)
122 {
123 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
124 FillFuzzHdiProperty(*fuzzParcel_, property);
125 return (*fuzzParcel_).ReadInt32();
126 }
127
SetCachedTemplates(const std::vector<uint64_t> & templateIdList)128 int32_t SetCachedTemplates(const std::vector<uint64_t> &templateIdList)
129 {
130 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
131 return (*fuzzParcel_).ReadInt32();
132 }
133
RegisterSaCommandCallback(const sptr<ISaCommandCallback> & callbackObj)134 int32_t RegisterSaCommandCallback(const sptr<ISaCommandCallback> &callbackObj)
135 {
136 IF_FALSE_LOGE_AND_RETURN_VAL(fuzzParcel_ != nullptr, 0);
137 callbackObj_ = callbackObj;
138 return (*fuzzParcel_).ReadInt32();
139 }
140
SetParcel(Parcel & parcel)141 void SetParcel(Parcel &parcel)
142 {
143 fuzzParcel_ = &parcel;
144 }
145
ClearParcel()146 void ClearParcel()
147 {
148 fuzzParcel_ = nullptr;
149 }
150
FuzzTriggerSaCommandCallback(Parcel & parcel)151 void FuzzTriggerSaCommandCallback(Parcel &parcel)
152 {
153 if (callbackObj_ == nullptr) {
154 return;
155 }
156
157 std::vector<SaCommand> commands;
158 FillFuzzSaCommandVector(parcel, commands);
159 callbackObj_->OnSaCommands(commands);
160 }
161
162 private:
FillFuzzHdiExecutorInfo(Parcel & parcel,ExecutorInfo & executorInfo)163 void FillFuzzHdiExecutorInfo(Parcel &parcel, ExecutorInfo &executorInfo)
164 {
165 executorInfo.sensorId = parcel.ReadUint16();
166 executorInfo.executorType = parcel.ReadUint32();
167 executorInfo.executorRole = static_cast<ExecutorRole>(parcel.ReadInt32());
168 executorInfo.authType = static_cast<AuthType>(parcel.ReadInt32());
169 executorInfo.esl = static_cast<ExecutorSecureLevel>(parcel.ReadInt32());
170 FillFuzzUint8Vector(parcel, executorInfo.publicKey);
171 FillFuzzUint8Vector(parcel, executorInfo.extraInfo);
172 IAM_LOGI("success");
173 }
174
FillFuzzHdiTemplateInfo(Parcel & parcel,TemplateInfo & templateInfo)175 void FillFuzzHdiTemplateInfo(Parcel &parcel, TemplateInfo &templateInfo)
176 {
177 templateInfo.executorType = parcel.ReadUint32();
178 templateInfo.lockoutDuration = parcel.ReadInt32();
179 templateInfo.remainAttempts = parcel.ReadInt32();
180 FillFuzzUint8Vector(parcel, templateInfo.extraInfo);
181 IAM_LOGI("success");
182 }
183
FillFuzzHdiProperty(Parcel & parcel,Property & property)184 void FillFuzzHdiProperty(Parcel &parcel, Property &property)
185 {
186 property.authSubType = parcel.ReadUint64();
187 property.lockoutDuration = parcel.ReadInt32();
188 property.remainAttempts = parcel.ReadInt32();
189 FillFuzzString(parcel, property.enrollmentProgress);
190 FillFuzzString(parcel, property.sensorInfo);
191
192 IAM_LOGI("success");
193 }
194
FillFuzzSaCommand(Parcel & parcel,SaCommand & command)195 void FillFuzzSaCommand(Parcel &parcel, SaCommand &command)
196 {
197 command.id = static_cast<SaCommandId>(parcel.ReadInt32());
198 IAM_LOGI("success");
199 }
200
FillFuzzSaCommandVector(Parcel & parcel,std::vector<SaCommand> & commands)201 void FillFuzzSaCommandVector(Parcel &parcel, std::vector<SaCommand> &commands)
202 {
203 uint32_t len = parcel.ReadUint32() % MAX_VECTOR_LEN;
204 commands.resize(len);
205 for (uint32_t i = 0; i < parcel.ReadUint32() % MAX_VECTOR_LEN; i++) {
206 FillFuzzSaCommand(parcel, commands[i]);
207 }
208 IAM_LOGI("success");
209 }
210
211 Parcel *fuzzParcel_;
212 sptr<ISaCommandCallback> callbackObj_ {nullptr};
213 };
214
215 class DummyExecuteCallback : public UserAuth::IExecuteCallback {
216 public:
217 virtual ~DummyExecuteCallback() = default;
218
OnResult(ResultCode result,const std::vector<uint8_t> & extraInfo)219 void OnResult(ResultCode result, const std::vector<uint8_t> &extraInfo)
220 {
221 }
222
OnResult(ResultCode result)223 void OnResult(ResultCode result)
224 {
225 }
226
OnAcquireInfo(int32_t acquire,const std::vector<uint8_t> & extraInfo)227 void OnAcquireInfo(int32_t acquire, const std::vector<uint8_t> &extraInfo)
228 {
229 }
230 };
231
232 auto g_proxy = new (nothrow) DummyExecutorProxy();
233 auto g_hdi = Common::MakeShared<FingerprintAuthExecutorHdi>(g_proxy);
234
FillFuzzExecutorInfo(Parcel & parcel,UserAuth::ExecutorInfo & executorInfo)235 void FillFuzzExecutorInfo(Parcel &parcel, UserAuth::ExecutorInfo &executorInfo)
236 {
237 executorInfo.executorSensorHint = parcel.ReadInt32();
238 executorInfo.authType = static_cast<UserAuth::AuthType>(parcel.ReadInt32());
239 executorInfo.executorRole = static_cast<UserAuth::ExecutorRole>(parcel.ReadInt32());
240 executorInfo.executorMatcher = parcel.ReadInt32();
241 executorInfo.esl = static_cast<UserAuth::ExecutorSecureLevel>(parcel.ReadInt32());
242 FillFuzzUint8Vector(parcel, executorInfo.publicKey);
243 IAM_LOGI("success");
244 }
245
FillFuzzIExecuteCallback(Parcel & parcel,std::shared_ptr<UserAuth::IExecuteCallback> & callback)246 void FillFuzzIExecuteCallback(Parcel &parcel, std::shared_ptr<UserAuth::IExecuteCallback> &callback)
247 {
248 callback = nullptr;
249 if (parcel.ReadBool()) {
250 callback = MakeShared<DummyExecuteCallback>();
251 if (callback == nullptr) {
252 IAM_LOGE("callback is nullptr");
253 }
254 }
255 IAM_LOGI("success");
256 }
257
FillFuzzAttributeKeyVector(Parcel & parcel,std::vector<UserAuth::Attributes::AttributeKey> & keys)258 void FillFuzzAttributeKeyVector(Parcel &parcel, std::vector<UserAuth::Attributes::AttributeKey> &keys)
259 {
260 std::vector<uint32_t> vals;
261 FillFuzzUint32Vector(parcel, vals);
262 for (const auto& val : vals) {
263 keys.push_back(static_cast<UserAuth::Attributes::AttributeKey>(val));
264 }
265
266 IAM_LOGI("success");
267 }
268
FuzzGetExecutorInfo(Parcel & parcel)269 void FuzzGetExecutorInfo(Parcel &parcel)
270 {
271 IAM_LOGI("begin");
272 UserAuth::ExecutorInfo info;
273 FillFuzzExecutorInfo(parcel, info);
274 g_hdi->GetExecutorInfo(info);
275 IAM_LOGI("end");
276 }
277
FuzzOnRegisterFinish(Parcel & parcel)278 void FuzzOnRegisterFinish(Parcel &parcel)
279 {
280 IAM_LOGI("begin");
281 std::vector<uint64_t> templateIdList;
282 FillFuzzUint64Vector(parcel, templateIdList);
283 std::vector<uint8_t> frameworkPublicKey;
284 FillFuzzUint8Vector(parcel, frameworkPublicKey);
285 std::vector<uint8_t> extraInfo;
286 FillFuzzUint8Vector(parcel, extraInfo);
287 g_hdi->OnRegisterFinish(templateIdList, frameworkPublicKey, extraInfo);
288 IAM_LOGI("end");
289 }
290
FuzzEnroll(Parcel & parcel)291 void FuzzEnroll(Parcel &parcel)
292 {
293 IAM_LOGI("begin");
294 uint64_t scheduleId = parcel.ReadUint64();
295 uint32_t tokenId = parcel.ReadUint32();
296 std::vector<uint8_t> extraInfo;
297 FillFuzzUint8Vector(parcel, extraInfo);
298 std::shared_ptr<UserAuth::IExecuteCallback> callbackObj;
299 FillFuzzIExecuteCallback(parcel, callbackObj);
300 g_hdi->Enroll(scheduleId, EnrollParam{ tokenId, extraInfo }, callbackObj);
301 IAM_LOGI("end");
302 }
303
FuzzAuthenticate(Parcel & parcel)304 void FuzzAuthenticate(Parcel &parcel)
305 {
306 IAM_LOGI("begin");
307 uint64_t scheduleId = parcel.ReadUint64();
308 uint32_t tokenId = parcel.ReadUint32();
309 std::vector<uint64_t> templateIdList;
310 FillFuzzUint64Vector(parcel, templateIdList);
311 std::vector<uint8_t> extraInfo;
312 FillFuzzUint8Vector(parcel, extraInfo);
313 std::shared_ptr<UserAuth::IExecuteCallback> callbackObj;
314 FillFuzzIExecuteCallback(parcel, callbackObj);
315 bool endAfterFirstFail = parcel.ReadBool();
316 g_hdi->Authenticate(scheduleId, AuthenticateParam{ tokenId, templateIdList, extraInfo, endAfterFirstFail },
317 callbackObj);
318 IAM_LOGI("end");
319 }
320
FuzzIdentify(Parcel & parcel)321 void FuzzIdentify(Parcel &parcel)
322 {
323 IAM_LOGI("begin");
324 uint64_t scheduleId = parcel.ReadUint64();
325 uint32_t tokenId = parcel.ReadUint32();
326 std::vector<uint8_t> extraInfo;
327 FillFuzzUint8Vector(parcel, extraInfo);
328 std::shared_ptr<UserAuth::IExecuteCallback> callbackObj;
329 FillFuzzIExecuteCallback(parcel, callbackObj);
330 g_hdi->Identify(scheduleId, IdentifyParam{ tokenId, extraInfo }, callbackObj);
331 IAM_LOGI("end");
332 }
333
FuzzDelete(Parcel & parcel)334 void FuzzDelete(Parcel &parcel)
335 {
336 IAM_LOGI("begin");
337 std::vector<uint64_t> templateIdList;
338 FillFuzzUint64Vector(parcel, templateIdList);
339 g_hdi->Delete(templateIdList);
340 IAM_LOGI("end");
341 }
342
FuzzCancel(Parcel & parcel)343 void FuzzCancel(Parcel &parcel)
344 {
345 IAM_LOGI("begin");
346 uint64_t scheduleId = parcel.ReadUint64();
347 g_hdi->Cancel(scheduleId);
348 IAM_LOGI("end");
349 }
350
FuzzSendCommand(Parcel & parcel)351 void FuzzSendCommand(Parcel &parcel)
352 {
353 IAM_LOGI("begin");
354 PropertyMode commandId = static_cast<PropertyMode>(parcel.ReadInt32());
355 std::vector<uint8_t> extraInfo;
356 FillFuzzUint8Vector(parcel, extraInfo);
357 std::shared_ptr<UserAuth::IExecuteCallback> callbackObj;
358 FillFuzzIExecuteCallback(parcel, callbackObj);
359 g_hdi->SendCommand(commandId, extraInfo, callbackObj);
360 IAM_LOGI("end");
361 }
362
FuzzGetProperty(Parcel & parcel)363 void FuzzGetProperty(Parcel &parcel)
364 {
365 IAM_LOGI("begin");
366 std::vector<uint64_t> templateIdList;
367 FillFuzzUint64Vector(parcel, templateIdList);
368 std::vector<UserAuth::Attributes::AttributeKey> keys;
369 FillFuzzAttributeKeyVector(parcel, keys);
370 UserAuth::Property property;
371 g_hdi->GetProperty(templateIdList, keys, property);
372 IAM_LOGI("end");
373 }
374
FuzzSetCachedTemplates(Parcel & parcel)375 void FuzzSetCachedTemplates(Parcel &parcel)
376 {
377 IAM_LOGI("begin");
378 std::vector<uint64_t> templateIdList;
379 FillFuzzUint64Vector(parcel, templateIdList);
380 g_hdi->SetCachedTemplates(templateIdList);
381 IAM_LOGI("end");
382 }
383
FuzzTriggerSaCommandCallback(Parcel & parcel)384 void FuzzTriggerSaCommandCallback(Parcel &parcel)
385 {
386 IAM_LOGI("begin");
387
388 IAM_LOGI("end");
389 }
390
SetProxyParcel(Parcel & parcel)391 void SetProxyParcel(Parcel &parcel)
392 {
393 if (g_proxy == nullptr) {
394 IAM_LOGE("g_proxy is nullptr");
395 return;
396 }
397 g_proxy->SetParcel(parcel);
398 }
399
ClearProxyParcel()400 void ClearProxyParcel()
401 {
402 if (g_proxy == nullptr) {
403 IAM_LOGE("g_proxy is nullptr");
404 return;
405 }
406 g_proxy->ClearParcel();
407 }
408
409 using FuzzFunc = decltype(FuzzGetExecutorInfo);
410 FuzzFunc *g_fuzzFuncs[] = { FuzzGetExecutorInfo, FuzzOnRegisterFinish, FuzzEnroll,
411 FuzzAuthenticate, FuzzIdentify, FuzzDelete, FuzzCancel, FuzzSendCommand,
412 FuzzGetProperty, FuzzSetCachedTemplates, FuzzTriggerSaCommandCallback };
413
FingerprintAuthServiceFuzzTest(const uint8_t * data,size_t size)414 void FingerprintAuthServiceFuzzTest(const uint8_t *data, size_t size)
415 {
416 Parcel parcel;
417 parcel.WriteBuffer(data, size);
418 parcel.RewindRead(0);
419 uint32_t index = parcel.ReadUint32() % (sizeof(g_fuzzFuncs) / sizeof(FuzzFunc *));
420 auto fuzzFunc = g_fuzzFuncs[index];
421 SetProxyParcel(parcel);
422 fuzzFunc(parcel);
423 ClearProxyParcel();
424 return;
425 }
426 } // namespace
427 } // namespace FingerprintAuth
428 } // namespace UserIam
429 } // namespace OHOS
430
431 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)432 extern "C" int32_t LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
433 {
434 OHOS::UserIam::FingerprintAuth::FingerprintAuthServiceFuzzTest(data, size);
435 return 0;
436 }
437