• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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