• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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