1 #include "fuzz.h"
2
3 #define MODULE_NAME "Type5 Read/Write"
4
5 enum {
6 SUB_TYPE_INVENTORY,
7 SUB_TYPE_STAY_QUIET,
8 SUB_TYPE_READ_SINGLEBLOCK,
9 SUB_TYPE_WRITE_SINGLEBLOCK,
10 SUB_TYPE_LOCK_BLOCK,
11 SUB_TYPE_READ_MULTIPLEBLOCKS,
12 SUB_TYPE_WRITE_MULTIPLEBLOCKS,
13 SUB_TYPE_SELECT,
14 SUB_TYPE_RESET_TO_READY,
15 SUB_TYPE_WRITE_AFI,
16 SUB_TYPE_LOCK_AFI,
17 SUB_TYPE_WRITE_DSFID,
18 SUB_TYPE_LOCK_DSFID,
19 SUB_TYPE_GET_SYS_INFO,
20 SUB_TYPE_GET_MULTI_BLOCK_SECURITY_STATUS,
21 SUB_TYPE_DETECT_NDEF,
22 SUB_TYPE_READ_NDEF,
23 SUB_TYPE_UPDATE_NDEF,
24 SUB_TYPE_FORMAT_NDEF,
25 SUB_TYPE_SET_TAG_READONLY,
26 SUB_TYPE_PRESENCE_CHECK,
27
28 SUB_TYPE_MAX
29 };
30
31 #define TEST_UID_VALUE \
32 { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }
33 // const uint8_t TEST_UID[] = TEST_UID_VALUE;
34
rw_cback(tRW_EVENT event,tRW_DATA * p_rw_data)35 static void rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
36 FUZZLOG(MODULE_NAME ": rw_cback: event=0x%02x, p_rw_data=%p", event,
37 p_rw_data);
38 if (event == RW_I93_DATA_EVT || event == RW_I93_NDEF_READ_EVT ||
39 event == RW_I93_NDEF_READ_CPLT_EVT) {
40 if (p_rw_data->i93_data.p_data) {
41 GKI_freebuf(p_rw_data->i93_data.p_data);
42 p_rw_data->i93_data.p_data = nullptr;
43 }
44 } else if (event == RW_I93_RAW_FRAME_EVT) {
45 if (p_rw_data->raw_frame.p_data) {
46 GKI_freebuf(p_rw_data->raw_frame.p_data);
47 p_rw_data->raw_frame.p_data = nullptr;
48 }
49 }
50 }
51
Init(Fuzz_Context &)52 static bool Init(Fuzz_Context& /*ctx*/) {
53 tNFC_ACTIVATE_DEVT activate_params = {
54 .protocol = static_cast<tNFC_PROTOCOL>(NFC_PROTOCOL_T5T),
55 .rf_tech_param = {.mode = NFC_DISCOVERY_TYPE_POLL_V,
56 .param = {.pi93 = {
57 .uid = TEST_UID_VALUE,
58 }}}};
59
60 rw_init();
61 if (NFC_STATUS_OK != RW_SetActivatedTagType(&activate_params, rw_cback)) {
62 FUZZLOG(MODULE_NAME ": RW_SetActivatedTagType failed");
63 return false;
64 }
65
66 return true;
67 }
68
Init_Inventory(Fuzz_Context &)69 static bool Init_Inventory(Fuzz_Context& /*ctx*/) {
70 uint8_t uid[] = TEST_UID_VALUE;
71 return NFC_STATUS_OK == RW_I93Inventory(false, 0, uid);
72 }
73
Init_StayQuiet(Fuzz_Context &)74 static bool Init_StayQuiet(Fuzz_Context& /*ctx*/) {
75 return NFC_STATUS_OK == RW_I93StayQuiet();
76 }
77
Init_ReadSingleBlock(Fuzz_Context &)78 static bool Init_ReadSingleBlock(Fuzz_Context& /*ctx*/) {
79 return NFC_STATUS_OK == RW_I93ReadSingleBlock(0);
80 }
81
Init_WriteSingleBlock(Fuzz_Context & ctx)82 static bool Init_WriteSingleBlock(Fuzz_Context& ctx) {
83 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
84 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
85
86 auto scratch = ctx.GetBuffer(sizeof(data), data);
87 return NFC_STATUS_OK == RW_I93WriteSingleBlock(0, scratch);
88 }
89
Init_LockBlock(Fuzz_Context &)90 static bool Init_LockBlock(Fuzz_Context& /*ctx*/) {
91 return NFC_STATUS_OK == RW_I93LockBlock(0);
92 }
93
Init_ReadMultipleBlocks(Fuzz_Context &)94 static bool Init_ReadMultipleBlocks(Fuzz_Context& /*ctx*/) {
95 return NFC_STATUS_OK == RW_I93ReadMultipleBlocks(0, 10);
96 }
97
Init_WriteMultipleBlocks(Fuzz_Context & ctx)98 static bool Init_WriteMultipleBlocks(Fuzz_Context& ctx) {
99 auto scratch = ctx.GetBuffer(16 * 10);
100 return NFC_STATUS_OK == RW_I93WriteMultipleBlocks(0, 10, scratch);
101 }
102
Init_Select(Fuzz_Context &)103 static bool Init_Select(Fuzz_Context& /*ctx*/) {
104 uint8_t uid[] = TEST_UID_VALUE;
105 return NFC_STATUS_OK == RW_I93Select(uid);
106 }
107
Init_ResetToReady(Fuzz_Context &)108 static bool Init_ResetToReady(Fuzz_Context& /*ctx*/) {
109 return NFC_STATUS_OK == RW_I93ResetToReady();
110 }
111
Init_WriteAFI(Fuzz_Context &)112 static bool Init_WriteAFI(Fuzz_Context& /*ctx*/) {
113 return NFC_STATUS_OK == RW_I93WriteAFI(0x11);
114 }
115
Init_LockAFI(Fuzz_Context &)116 static bool Init_LockAFI(Fuzz_Context& /*ctx*/) {
117 return NFC_STATUS_OK == RW_I93LockAFI();
118 }
119
Init_WriteDSFID(Fuzz_Context &)120 static bool Init_WriteDSFID(Fuzz_Context& /*ctx*/) {
121 return NFC_STATUS_OK == RW_I93WriteDSFID(0x22);
122 }
123
Init_LockDSFID(Fuzz_Context &)124 static bool Init_LockDSFID(Fuzz_Context& /*ctx*/) {
125 return NFC_STATUS_OK == RW_I93LockDSFID();
126 }
127
Init_GetSysInfo(Fuzz_Context &)128 static bool Init_GetSysInfo(Fuzz_Context& /*ctx*/) {
129 uint8_t uid[] = TEST_UID_VALUE;
130 return NFC_STATUS_OK == RW_I93GetSysInfo(uid);
131 }
132
Init_GetMultiBlockSecurityStatus(Fuzz_Context &)133 static bool Init_GetMultiBlockSecurityStatus(Fuzz_Context& /*ctx*/) {
134 return NFC_STATUS_OK == RW_I93GetMultiBlockSecurityStatus(0, 10);
135 }
136
Init_DetectNDef(Fuzz_Context &)137 static bool Init_DetectNDef(Fuzz_Context& /*ctx*/) {
138 return NFC_STATUS_OK == RW_I93DetectNDef();
139 }
140
Init_ReadNDef(Fuzz_Context &)141 static bool Init_ReadNDef(Fuzz_Context& /*ctx*/) {
142 return NFC_STATUS_OK == RW_I93ReadNDef();
143 }
144
Init_UpdateNDef(Fuzz_Context & ctx)145 static bool Init_UpdateNDef(Fuzz_Context& ctx) {
146 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
147 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
148
149 auto scratch = ctx.GetBuffer(sizeof(data), data);
150 return NFC_STATUS_OK == RW_I93UpdateNDef(sizeof(data), scratch);
151 }
152
Init_FormatNDef(Fuzz_Context &)153 static bool Init_FormatNDef(Fuzz_Context& /*ctx*/) {
154 return NFC_STATUS_OK == RW_I93FormatNDef();
155 }
156
Init_SetTagReadOnly(Fuzz_Context &)157 static bool Init_SetTagReadOnly(Fuzz_Context& /*ctx*/) {
158 return NFC_STATUS_OK == RW_I93SetTagReadOnly();
159 }
160
Init_PresenceCheck(Fuzz_Context &)161 static bool Init_PresenceCheck(Fuzz_Context& /*ctx*/) {
162 return NFC_STATUS_OK == RW_I93PresenceCheck();
163 }
164
Fuzz_Init(Fuzz_Context & ctx)165 static bool Fuzz_Init(Fuzz_Context& ctx) {
166 if (!Init(ctx)) {
167 FUZZLOG(MODULE_NAME ": initialization failed");
168 return false;
169 }
170
171 bool result = false;
172 switch (ctx.SubType) {
173 case SUB_TYPE_INVENTORY:
174 result = Init_Inventory(ctx);
175 break;
176
177 case SUB_TYPE_STAY_QUIET:
178 result = Init_StayQuiet(ctx);
179 break;
180
181 case SUB_TYPE_READ_SINGLEBLOCK:
182 result = Init_ReadSingleBlock(ctx);
183 break;
184
185 case SUB_TYPE_WRITE_SINGLEBLOCK:
186 result = Init_WriteSingleBlock(ctx);
187 break;
188
189 case SUB_TYPE_LOCK_BLOCK:
190 result = Init_LockBlock(ctx);
191 break;
192
193 case SUB_TYPE_READ_MULTIPLEBLOCKS:
194 result = Init_ReadMultipleBlocks(ctx);
195 break;
196
197 case SUB_TYPE_WRITE_MULTIPLEBLOCKS:
198 result = Init_WriteMultipleBlocks(ctx);
199 break;
200
201 case SUB_TYPE_SELECT:
202 result = Init_Select(ctx);
203 break;
204
205 case SUB_TYPE_RESET_TO_READY:
206 result = Init_ResetToReady(ctx);
207 break;
208
209 case SUB_TYPE_WRITE_AFI:
210 result = Init_WriteAFI(ctx);
211 break;
212
213 case SUB_TYPE_LOCK_AFI:
214 result = Init_LockAFI(ctx);
215 break;
216
217 case SUB_TYPE_WRITE_DSFID:
218 result = Init_WriteDSFID(ctx);
219 break;
220
221 case SUB_TYPE_LOCK_DSFID:
222 result = Init_LockDSFID(ctx);
223 break;
224
225 case SUB_TYPE_GET_SYS_INFO:
226 result = Init_GetSysInfo(ctx);
227 break;
228
229 case SUB_TYPE_GET_MULTI_BLOCK_SECURITY_STATUS:
230 result = Init_GetMultiBlockSecurityStatus(ctx);
231 break;
232
233 case SUB_TYPE_DETECT_NDEF:
234 result = Init_DetectNDef(ctx);
235 break;
236
237 case SUB_TYPE_READ_NDEF:
238 result = Init_ReadNDef(ctx);
239 break;
240
241 case SUB_TYPE_UPDATE_NDEF:
242 result = Init_UpdateNDef(ctx);
243 break;
244
245 case SUB_TYPE_FORMAT_NDEF:
246 result = Init_FormatNDef(ctx);
247 break;
248
249 case SUB_TYPE_SET_TAG_READONLY:
250 result = Init_SetTagReadOnly(ctx);
251 break;
252
253 case SUB_TYPE_PRESENCE_CHECK:
254 result = Init_PresenceCheck(ctx);
255 break;
256
257 default:
258 FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType);
259 result = false;
260 break;
261 }
262
263 if (!result) {
264 FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType);
265 }
266
267 return result;
268 }
269
Fuzz_Deinit(Fuzz_Context &)270 static void Fuzz_Deinit(Fuzz_Context& /*ctx*/) {
271 if (rf_cback) {
272 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93;
273 if (p_i93->p_update_data) {
274 GKI_freebuf(p_i93->p_update_data);
275 p_i93->p_update_data = nullptr;
276 }
277
278 tNFC_CONN conn = {
279 .deactivate = {.status = NFC_STATUS_OK,
280 .type = NFC_DEACTIVATE_TYPE_IDLE,
281 .is_ntf = true,
282 .reason = NFC_DEACTIVATE_REASON_DH_REQ_FAILED}};
283
284 rf_cback(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, &conn);
285 }
286 }
287
Fuzz_Run(Fuzz_Context & ctx)288 static void Fuzz_Run(Fuzz_Context& ctx) {
289 for (auto it = ctx.Data.cbegin() + 1; it != ctx.Data.cend(); ++it) {
290 NFC_HDR* p_msg;
291 p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size());
292 if (p_msg == nullptr) {
293 FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size());
294 return;
295 }
296
297 /* Initialize NFC_HDR */
298 p_msg->len = it->size();
299 p_msg->offset = 0;
300
301 uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
302 memcpy(p, it->data(), it->size());
303
304 tNFC_CONN conn = {.data = {
305 .status = NFC_STATUS_OK,
306 .p_data = p_msg,
307 }};
308
309 FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zd]=%s", ctx.SubType,
310 it - ctx.Data.cbegin(), ctx.Data.size() - 1,
311 BytesToHex(*it).c_str());
312
313 rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn);
314 }
315 }
316
Type5_FixPackets(uint8_t,std::vector<bytes_t> &)317 void Type5_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& /*Data*/) {}
318
Type5_Fuzz(uint8_t SubType,const std::vector<bytes_t> & Data)319 void Type5_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Data) {
320 Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Data);
321 if (Fuzz_Init(ctx)) {
322 Fuzz_Run(ctx);
323 }
324
325 Fuzz_Deinit(ctx);
326 }
327