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