1 #include "fuzz.h"
2
3 #define MODULE_NAME "Type1 Read/Write"
4
5 enum {
6 SUB_TYPE_PRESENCE_CHECK,
7 SUB_TYPE_RID,
8 SUB_TYPE_READ_ALL,
9 SUB_TYPE_READ,
10 SUB_TYPE_WRITE_ERASE,
11 SUB_TYPE_WRITE_NO_ERASE,
12 SUB_TYPE_READ_SEG,
13 SUB_TYPE_READ_8,
14 SUB_TYPE_WRITE_ERASE_8,
15 SUB_TYPE_WRITE_NO_ERASE_8,
16 SUB_TYPE_FORMAT_NDEF,
17 SUB_TYPE_LOCATE_TLV,
18 SUB_TYPE_READ_NDEF,
19 SUB_TYPE_WRITE_NDEF,
20 SUB_TYPE_SET_READONLY,
21
22 SUB_TYPE_MAX
23 };
24
rw_cback(tRW_EVENT event,tRW_DATA * p_rw_data)25 static void rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
26 FUZZLOG(MODULE_NAME ": rw_cback: event=0x%02x, p_rw_data=%p", event,
27 p_rw_data);
28
29 if (event == RW_T1T_RAW_FRAME_EVT || event == RW_T1T_RID_EVT ||
30 event == RW_T1T_RALL_CPLT_EVT || event == RW_T1T_READ_CPLT_EVT ||
31 event == RW_T1T_RSEG_CPLT_EVT || event == RW_T1T_READ8_CPLT_EVT) {
32 if (p_rw_data->data.p_data) {
33 GKI_freebuf(p_rw_data->data.p_data);
34 p_rw_data->data.p_data = nullptr;
35 }
36 }
37 }
38
39 #define TEST_NFCID_VALUE \
40 { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }
41
Init(Fuzz_Context &)42 static bool Init(Fuzz_Context& /*ctx*/) {
43 tNFC_ACTIVATE_DEVT activate_params = {
44 .protocol = NFC_PROTOCOL_T1T,
45 .rf_tech_param = {.mode = NFC_DISCOVERY_TYPE_POLL_A,
46 .param = {.pa = {
47 .hr = {T1T_NDEF_SUPPORTED, 0x01},
48 .nfcid1 = TEST_NFCID_VALUE,
49 }}}};
50
51 rw_init();
52 if (NFC_STATUS_OK != RW_SetActivatedTagType(&activate_params, rw_cback)) {
53 FUZZLOG(MODULE_NAME ": RW_SetActivatedTagType failed");
54 return false;
55 }
56
57 return true;
58 }
59
Init_PresenceCheck(Fuzz_Context &)60 static bool Init_PresenceCheck(Fuzz_Context& /*ctx*/) {
61 return NFC_STATUS_OK == RW_T1tPresenceCheck();
62 }
63
Init_Rid(Fuzz_Context &)64 static bool Init_Rid(Fuzz_Context& /*ctx*/) {
65 return NFC_STATUS_OK == RW_T1tRid();
66 }
67
Init_ReadAll(Fuzz_Context &)68 static bool Init_ReadAll(Fuzz_Context& /*ctx*/) {
69 return NFC_STATUS_OK == RW_T1tReadAll();
70 }
71
Init_Read(Fuzz_Context &)72 static bool Init_Read(Fuzz_Context& /*ctx*/) {
73 return NFC_STATUS_OK == RW_T1tRead(0, 0x10);
74 }
75
Init_WriteErase(Fuzz_Context &)76 static bool Init_WriteErase(Fuzz_Context& /*ctx*/) {
77 return NFC_STATUS_OK == RW_T1tWriteErase(0, 0x10, 0x20);
78 }
79
Init_WriteNoErase(Fuzz_Context &)80 static bool Init_WriteNoErase(Fuzz_Context& /*ctx*/) {
81 return NFC_STATUS_OK == RW_T1tWriteNoErase(0, 0x10, 0x20);
82 }
83
Init_ReadSeg(Fuzz_Context &)84 static bool Init_ReadSeg(Fuzz_Context& /*ctx*/) {
85 return NFC_STATUS_OK == RW_T1tReadSeg(0);
86 }
87
Init_Read8(Fuzz_Context &)88 static bool Init_Read8(Fuzz_Context& /*ctx*/) {
89 return NFC_STATUS_OK == RW_T1tRead8(0);
90 }
91
Init_WriteErase8(Fuzz_Context & ctx)92 static bool Init_WriteErase8(Fuzz_Context& ctx) {
93 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
94 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
95
96 auto scratch = ctx.GetBuffer(sizeof(data), data);
97 return NFC_STATUS_OK == RW_T1tWriteErase8(0, scratch);
98 }
99
Init_WriteNoErase8(Fuzz_Context & ctx)100 static bool Init_WriteNoErase8(Fuzz_Context& ctx) {
101 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
102 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
103
104 auto scratch = ctx.GetBuffer(sizeof(data), data);
105 return NFC_STATUS_OK == RW_T1tWriteNoErase8(0, scratch);
106 }
107
Init_FormatNdef(Fuzz_Context &)108 static bool Init_FormatNdef(Fuzz_Context& /*ctx*/) {
109 return NFC_STATUS_OK == RW_T1tFormatNDef();
110 }
Init_LocateTlv(Fuzz_Context &)111 static bool Init_LocateTlv(Fuzz_Context& /*ctx*/) {
112 return NFC_STATUS_OK == RW_T1tLocateTlv(TAG_NDEF_TLV);
113 }
Init_ReadNdef(Fuzz_Context & ctx)114 static bool Init_ReadNdef(Fuzz_Context& ctx) {
115 tRW_T1T_CB* p_t1t = &rw_cb.tcb.t1t;
116 p_t1t->tag_attribute = RW_T1_TAG_ATTRB_READ_WRITE;
117 p_t1t->ndef_msg_len = 256;
118
119 auto scratch = ctx.GetBuffer(4096);
120 return NFC_STATUS_OK == RW_T1tReadNDef(scratch, 4096);
121 }
Init_WriteNdef(Fuzz_Context & ctx)122 static bool Init_WriteNdef(Fuzz_Context& ctx) {
123 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
124 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
125
126 auto scratch = ctx.GetBuffer(sizeof(data), data);
127 return NFC_STATUS_OK == RW_T1tWriteNDef(sizeof(data), scratch);
128 }
Init_SetReadOnly(Fuzz_Context &)129 static bool Init_SetReadOnly(Fuzz_Context& /*ctx*/) {
130 return NFC_STATUS_OK == RW_T1tSetTagReadOnly(true);
131 }
132
Fuzz_Init(Fuzz_Context & ctx)133 static bool Fuzz_Init(Fuzz_Context& ctx) {
134 if (!Init(ctx)) {
135 FUZZLOG(MODULE_NAME ": initialization failed");
136 return false;
137 }
138
139 bool result = false;
140 switch (ctx.SubType) {
141 case SUB_TYPE_PRESENCE_CHECK:
142 result = Init_PresenceCheck(ctx);
143 break;
144 case SUB_TYPE_RID:
145 result = Init_Rid(ctx);
146 break;
147 case SUB_TYPE_READ_ALL:
148 result = Init_ReadAll(ctx);
149 break;
150 case SUB_TYPE_READ:
151 result = Init_Read(ctx);
152 break;
153 case SUB_TYPE_WRITE_ERASE:
154 result = Init_WriteErase(ctx);
155 break;
156 case SUB_TYPE_WRITE_NO_ERASE:
157 result = Init_WriteNoErase(ctx);
158 break;
159 case SUB_TYPE_READ_SEG:
160 result = Init_ReadSeg(ctx);
161 break;
162 case SUB_TYPE_READ_8:
163 result = Init_Read8(ctx);
164 break;
165 case SUB_TYPE_WRITE_ERASE_8:
166 result = Init_WriteErase8(ctx);
167 break;
168 case SUB_TYPE_WRITE_NO_ERASE_8:
169 result = Init_WriteNoErase8(ctx);
170 break;
171 case SUB_TYPE_FORMAT_NDEF:
172 result = Init_FormatNdef(ctx);
173 break;
174 case SUB_TYPE_LOCATE_TLV:
175 result = Init_LocateTlv(ctx);
176 break;
177 case SUB_TYPE_READ_NDEF:
178 result = Init_ReadNdef(ctx);
179 break;
180 case SUB_TYPE_WRITE_NDEF:
181 result = Init_WriteNdef(ctx);
182 break;
183 case SUB_TYPE_SET_READONLY:
184 result = Init_SetReadOnly(ctx);
185 break;
186
187 default:
188 FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType);
189 result = false;
190 break;
191 }
192
193 if (!result) {
194 FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType);
195 }
196
197 return result;
198 }
199
Fuzz_Deinit(Fuzz_Context &)200 static void Fuzz_Deinit(Fuzz_Context& /*ctx*/) {
201 if (rf_cback) {
202 tNFC_CONN conn = {
203 .deactivate = {.status = NFC_STATUS_OK,
204 .type = NFC_DEACTIVATE_TYPE_IDLE,
205 .is_ntf = true,
206 .reason = NFC_DEACTIVATE_REASON_DH_REQ_FAILED}};
207
208 rf_cback(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, &conn);
209 }
210 }
211
Fuzz_Run(Fuzz_Context & ctx)212 static void Fuzz_Run(Fuzz_Context& ctx) {
213 for (auto it = ctx.Data.cbegin() + 1; it != ctx.Data.cend(); ++it) {
214 NFC_HDR* p_msg;
215 p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size());
216 if (p_msg == nullptr || it->size() < 1) {
217 FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size());
218 return;
219 }
220
221 /* Initialize NFC_HDR */
222 p_msg->len = it->size() - 1;
223 p_msg->offset = 0;
224
225 uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
226 memcpy(p, it->data(), it->size());
227
228 tNFC_CONN conn = {.data = {
229 .status = NFC_STATUS_OK,
230 .p_data = p_msg,
231 }};
232
233 FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zd]=%s", ctx.SubType,
234 it - ctx.Data.cbegin(), ctx.Data.size() - 1,
235 BytesToHex(*it).c_str());
236
237 rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn);
238 }
239 }
240
Type1_FixPackets(uint8_t,std::vector<bytes_t> &)241 void Type1_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& /*Data*/) {}
242
Type1_Fuzz(uint8_t SubType,const std::vector<bytes_t> & Data)243 void Type1_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Data) {
244 Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Data);
245 if (Fuzz_Init(ctx)) {
246 Fuzz_Run(ctx);
247 }
248 Fuzz_Deinit(ctx);
249 }
250