1 #include "fuzz.h"
2
3 #define MODULE_NAME "Type4 Read/Write"
4
5 enum {
6 SUB_TYPE_DETECT_NDEF,
7 SUB_TYPE_READ_NDEF,
8 SUB_TYPE_UPDATE_NDEF,
9 SUB_TYPE_PRESENCE_CHECK,
10 SUB_TYPE_SET_READ_ONLY,
11 SUB_TYPE_FORMAT_NDEF,
12
13 SUB_TYPE_MAX
14 };
15
rw_cback(tRW_EVENT event,tRW_DATA * p_rw_data)16 static void rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
17 FUZZLOG(MODULE_NAME ": rw_cback: event=0x%02x, p_rw_data=%p", event,
18 p_rw_data);
19
20 if (event == RW_T4T_RAW_FRAME_EVT) {
21 if (p_rw_data->raw_frame.p_data) {
22 GKI_freebuf(p_rw_data->raw_frame.p_data);
23 p_rw_data->raw_frame.p_data = nullptr;
24 }
25 } else if (event == RW_T4T_NDEF_READ_EVT ||
26 event == RW_T4T_NDEF_READ_CPLT_EVT) {
27 if (p_rw_data->data.p_data) {
28 GKI_freebuf(p_rw_data->data.p_data);
29 p_rw_data->data.p_data = nullptr;
30 }
31 }
32 }
33
34 #define TEST_NFCID_VALUE \
35 { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }
36
Init(Fuzz_Context &)37 static bool Init(Fuzz_Context& /*ctx*/) {
38 tNFC_ACTIVATE_DEVT activate_params = {.protocol = NFC_PROTOCOL_ISO_DEP,
39 .rf_tech_param = {
40 .mode = NFC_DISCOVERY_TYPE_POLL_A,
41 }};
42
43 rw_init();
44 if (NFC_STATUS_OK != RW_SetActivatedTagType(&activate_params, rw_cback)) {
45 FUZZLOG(MODULE_NAME ": RW_SetActivatedTagType failed");
46 return false;
47 }
48
49 return true;
50 }
51
Init_PresenceCheck(Fuzz_Context &)52 static bool Init_PresenceCheck(Fuzz_Context& /*ctx*/) {
53 return NFC_STATUS_OK == RW_T4tPresenceCheck(1);
54 }
55
Init_DetectNDef(Fuzz_Context &)56 static bool Init_DetectNDef(Fuzz_Context& /*ctx*/) {
57 return NFC_STATUS_OK == RW_T4tDetectNDef();
58 }
59
Init_ReadNDef(Fuzz_Context &)60 static bool Init_ReadNDef(Fuzz_Context& /*ctx*/) {
61 return NFC_STATUS_OK == RW_T4tReadNDef();
62 }
63
Init_UpdateNDef(Fuzz_Context & ctx)64 static bool Init_UpdateNDef(Fuzz_Context& ctx) {
65 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
66 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
67
68 auto scratch = ctx.GetBuffer(sizeof(data), data);
69 return NFC_STATUS_OK == RW_T4tUpdateNDef(sizeof(data), scratch);
70 }
71
Init_FormatNDef(Fuzz_Context &)72 static bool Init_FormatNDef(Fuzz_Context& /*ctx*/) {
73 return NFC_STATUS_OK == RW_T4tFormatNDef();
74 }
75
Init_SetNDefReadOnly(Fuzz_Context &)76 static bool Init_SetNDefReadOnly(Fuzz_Context& /*ctx*/) {
77 return NFC_STATUS_OK == RW_T4tSetNDefReadOnly();
78 }
79
Fuzz_Init(Fuzz_Context & ctx)80 static bool Fuzz_Init(Fuzz_Context& ctx) {
81 if (!Init(ctx)) {
82 FUZZLOG(MODULE_NAME ": initialization failed");
83 return false;
84 }
85
86 bool result = false;
87 switch (ctx.SubType) {
88 case SUB_TYPE_DETECT_NDEF:
89 result = Init_DetectNDef(ctx);
90 break;
91 case SUB_TYPE_UPDATE_NDEF:
92 result = Init_UpdateNDef(ctx);
93 break;
94 case SUB_TYPE_PRESENCE_CHECK:
95 result = Init_PresenceCheck(ctx);
96 break;
97 case SUB_TYPE_READ_NDEF:
98 result = Init_ReadNDef(ctx);
99 break;
100 case SUB_TYPE_FORMAT_NDEF:
101 result = Init_FormatNDef(ctx);
102 break;
103 case SUB_TYPE_SET_READ_ONLY:
104 result = Init_SetNDefReadOnly(ctx);
105 break;
106 default:
107 FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType);
108 result = false;
109 break;
110 }
111
112 if (!result) {
113 FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType);
114 }
115
116 return result;
117 }
118
Fuzz_Deinit(Fuzz_Context &)119 static void Fuzz_Deinit(Fuzz_Context& /*ctx*/) {
120 if (rf_cback) {
121 tNFC_CONN conn = {
122 .deactivate = {.status = NFC_STATUS_OK,
123 .type = NFC_DEACTIVATE_TYPE_IDLE,
124 .is_ntf = true,
125 .reason = NFC_DEACTIVATE_REASON_DH_REQ_FAILED}};
126
127 rf_cback(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, &conn);
128 }
129 }
130
Fuzz_Run(Fuzz_Context & ctx)131 static void Fuzz_Run(Fuzz_Context& ctx) {
132 for (auto it = ctx.Data.cbegin() + 1; it != ctx.Data.cend(); ++it) {
133 NFC_HDR* p_msg;
134 p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size());
135 if (p_msg == nullptr) {
136 FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size());
137 return;
138 }
139
140 /* Initialize NFC_HDR */
141 p_msg->len = it->size();
142 p_msg->offset = 0;
143
144 uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
145 memcpy(p, it->data(), it->size());
146
147 tNFC_CONN conn = {.data = {
148 .status = NFC_STATUS_OK,
149 .p_data = p_msg,
150 }};
151
152 FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zd]=%s", ctx.SubType,
153 it - ctx.Data.cbegin(), ctx.Data.size() - 1,
154 BytesToHex(*it).c_str());
155
156 rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn);
157 }
158 }
159
Type4_FixPackets(uint8_t,std::vector<bytes_t> &)160 void Type4_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& /*Data*/) {}
161
Type4_Fuzz(uint8_t SubType,const std::vector<bytes_t> & Data)162 void Type4_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Data) {
163 Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Data);
164 if (Fuzz_Init(ctx)) {
165 Fuzz_Run(ctx);
166 }
167
168 Fuzz_Deinit(ctx);
169 }
170