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