1 /*
2 * Copyright (c) 2024 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 #include "hcesessionstub_fuzzer.h"
16
17 #include <cstddef>
18 #include <cstdint>
19 #include <securec.h>
20 #include <string>
21
22 #include "hce_session_stub.h"
23 #include "hce_session.h"
24 #include "nfc_sdk_common.h"
25 #include "nfc_service_ipc_interface_code.h"
26 #include "nfc_access_token_mock.h"
27
28 namespace OHOS {
29 using namespace OHOS::NFC::KITS;
30 using namespace OHOS::NFC::HCE;
31
32 constexpr uint32_t MESSAGE_SIZE = NFC::NfcServiceIpcInterfaceCode::COMMAND_CE_HCE_SESSION_BOTTOM;
33 constexpr const auto FUZZER_THRESHOLD = 6;
34
ConvertToUint32s(const uint8_t * ptr,uint32_t * outPara,uint16_t outParaLen)35 void ConvertToUint32s(const uint8_t* ptr, uint32_t* outPara, uint16_t outParaLen)
36 {
37 for (uint16_t i = 0 ; i < outParaLen ; i++) {
38 // 4 uint8s compose 1 uint32 , 8 16 24 is bit operation, 2 3 4 are array subscripts.
39 outPara[i] = (ptr[i * 4] << 24) | (ptr[(i * 4) + 1 ] << 16) | (ptr[(i * 4) + 2] << 8) | (ptr[(i * 4) + 3]);
40 }
41 }
42
GetU32Data(const uint8_t * data)43 uint32_t GetU32Data(const uint8_t* data)
44 {
45 /*
46 * Move the 0th digit to the left by 24 bits, the 1st digit to the left by 16 bits,
47 * the 2nd digit to the left by 8 bits, and the 3rd digit not to the left
48 */
49 return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]);
50 }
51
BuildAddressString(const uint8_t * data)52 std::string BuildAddressString(const uint8_t* data)
53 {
54 std::string addr("00:00:00:00:00:00");
55 char temp[18] = {0};
56 int ret = sprintf_s(temp, sizeof(temp), "%02X:%02X:%02X:%02X:%02X:%02X",
57 data[0], data[1], data[2], data[3], data[4], data[5]);
58 if (ret != -1) {
59 addr = std::string(temp);
60 }
61 return addr;
62 }
63
DoHceSessionStubFuzzTest(const uint8_t * data,size_t size)64 bool DoHceSessionStubFuzzTest(const uint8_t* data, size_t size)
65 {
66 uint32_t code = (GetU32Data(data) % MESSAGE_SIZE);
67 auto addr = BuildAddressString(data);
68
69 MessageParcel datas;
70 std::u16string descriptor = HceSessionStub::GetDescriptor();
71 datas.WriteInterfaceToken(descriptor);
72 datas.WriteInt32(*(reinterpret_cast<const int32_t *>(data)));
73 datas.WriteString(addr.c_str());
74 datas.RewindRead(0);
75 MessageParcel reply;
76 MessageOption option;
77
78 std::shared_ptr<OHOS::NFC::NfcService> nfcService = std::make_shared<OHOS::NFC::NfcService>();
79 std::shared_ptr<NFC::HCE::HceSession> hceSession = std::make_shared<NFC::HCE::HceSession>(nfcService);
80 hceSession->OnRemoteRequest(code, datas, reply, option);
81 return true;
82 }
83
84 }
85
86 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)87 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
88 {
89 if (size < OHOS::FUZZER_THRESHOLD) {
90 return 0;
91 }
92
93 /* Run your code on data */
94 OHOS::NFC::NfcAccessTokenMock::SetNativeTokenInfo();
95 OHOS::DoHceSessionStubFuzzTest(data, size);
96 return 0;
97 }
98
99