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