1 #include "fuzz.h"
2
3 #define MODULE_NAME "Type2 Read/Write"
4
5 enum {
6 SUB_TYPE_PRESENCE_CHECK,
7 SUB_TYPE_READ,
8 SUB_TYPE_WRITE,
9 SUB_TYPE_SECTOR_SELECT,
10 SUB_TYPE_SET_TAG_READONLY,
11 SUB_TYPE_WRITE_NDEF,
12 SUB_TYPE_READ_NDEF,
13 SUB_TYPE_DETECT_NDEF,
14 SUB_TYPE_LOCATE_TLV,
15 SUB_TYPE_FORMAT_NDEF,
16 SUB_TYPE_MAX
17 };
18
rw_cback(tRW_EVENT event,tRW_DATA * p_rw_data)19 static void rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
20 FUZZLOG(MODULE_NAME ": rw_cback: event=0x%02x, p_rw_data=%p", event,
21 p_rw_data);
22
23 if (event == RW_T2T_READ_CPLT_EVT || event == RW_T2T_RAW_FRAME_EVT) {
24 if (p_rw_data->data.p_data) {
25 GKI_freebuf(p_rw_data->data.p_data);
26 p_rw_data->data.p_data = nullptr;
27 }
28 }
29 }
30
31 #define TEST_NFCID_VALUE \
32 { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }
33
Init(Fuzz_Context &)34 static bool Init(Fuzz_Context& /*ctx*/) {
35 tNFC_ACTIVATE_DEVT activate_params = {
36 .protocol = NFC_PROTOCOL_T2T,
37 .rf_tech_param = {.mode = NFC_DISCOVERY_TYPE_POLL_A,
38 .param = {.pa = {
39 .sel_rsp = NFC_SEL_RES_NFC_FORUM_T2T,
40 }}}};
41
42 rw_init();
43 if (NFC_STATUS_OK != RW_SetActivatedTagType(&activate_params, rw_cback)) {
44 FUZZLOG(MODULE_NAME ": RW_SetActivatedTagType failed");
45 return false;
46 }
47
48 return true;
49 }
50
Init_PresenceCheck(Fuzz_Context &)51 static bool Init_PresenceCheck(Fuzz_Context& /*ctx*/) {
52 return NFC_STATUS_OK == RW_T2tPresenceCheck();
53 }
54
Init_Read(Fuzz_Context &)55 static bool Init_Read(Fuzz_Context& /*ctx*/) {
56 return NFC_STATUS_OK == RW_T2tRead(0);
57 }
58
Init_Write(Fuzz_Context & ctx)59 static bool Init_Write(Fuzz_Context& ctx) {
60 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
61 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
62
63 auto scratch = ctx.GetBuffer(sizeof(data), data);
64 return NFC_STATUS_OK == RW_T2tWrite(0, scratch);
65 }
66
Init_SectorSelect(Fuzz_Context &)67 static bool Init_SectorSelect(Fuzz_Context& /*ctx*/) {
68 return NFC_STATUS_OK == RW_T2tSectorSelect(0);
69 }
70
Init_SetTagReadOnly(Fuzz_Context &)71 static bool Init_SetTagReadOnly(Fuzz_Context& /*ctx*/) {
72 return NFC_STATUS_OK == RW_T2tSetTagReadOnly(true);
73 }
74
Init_WriteNDef(Fuzz_Context & ctx)75 static bool Init_WriteNDef(Fuzz_Context& ctx) {
76 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
77 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
78
79 auto scratch = ctx.GetBuffer(sizeof(data), data);
80 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
81
82 p_t2t->ndef_status = T2T_NDEF_DETECTED;
83 return NFC_STATUS_OK == RW_T2tWriteNDef(sizeof(data), scratch);
84 }
85
Init_ReadNDef(Fuzz_Context & ctx)86 static bool Init_ReadNDef(Fuzz_Context& ctx) {
87 auto scratch = ctx.GetBuffer(256);
88 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
89
90 p_t2t->ndef_status = T2T_NDEF_DETECTED;
91 p_t2t->ndef_msg_len = 128;
92 p_t2t->bytes_count = 128;
93 return NFC_STATUS_OK == RW_T2tReadNDef(scratch, 256);
94 }
95
Init_DetectNDef(Fuzz_Context &)96 static bool Init_DetectNDef(Fuzz_Context& /*ctx*/) {
97 return NFC_STATUS_OK == RW_T2tDetectNDef(true);
98 }
99
Init_LocateTlv(Fuzz_Context &)100 static bool Init_LocateTlv(Fuzz_Context& /*ctx*/) {
101 return NFC_STATUS_OK == RW_T2tLocateTlv(TAG_LOCK_CTRL_TLV);
102 }
103
Init_FormatNDef(Fuzz_Context &)104 static bool Init_FormatNDef(Fuzz_Context& /*ctx*/) {
105 return NFC_STATUS_OK == RW_T2tFormatNDef();
106 }
107
Fuzz_Init(Fuzz_Context & ctx)108 static bool Fuzz_Init(Fuzz_Context& ctx) {
109 if (!Init(ctx)) {
110 FUZZLOG(MODULE_NAME ": initialization failed");
111 return false;
112 }
113
114 bool result = false;
115 switch (ctx.SubType) {
116 case SUB_TYPE_PRESENCE_CHECK:
117 result = Init_PresenceCheck(ctx);
118 break;
119 case SUB_TYPE_READ:
120 result = Init_Read(ctx);
121 break;
122 case SUB_TYPE_WRITE:
123 result = Init_Write(ctx);
124 break;
125 case SUB_TYPE_SECTOR_SELECT:
126 result = Init_SectorSelect(ctx);
127 break;
128 case SUB_TYPE_SET_TAG_READONLY:
129 result = Init_SetTagReadOnly(ctx);
130 break;
131 case SUB_TYPE_WRITE_NDEF:
132 result = Init_WriteNDef(ctx);
133 break;
134 case SUB_TYPE_READ_NDEF:
135 result = Init_ReadNDef(ctx);
136 break;
137 case SUB_TYPE_DETECT_NDEF:
138 result = Init_DetectNDef(ctx);
139 break;
140 case SUB_TYPE_LOCATE_TLV:
141 result = Init_LocateTlv(ctx);
142 break;
143 case SUB_TYPE_FORMAT_NDEF:
144 result = Init_FormatNDef(ctx);
145 break;
146 default:
147 FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType);
148 result = false;
149 break;
150 }
151
152 if (!result) {
153 FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType);
154 }
155
156 return result;
157 }
158
Fuzz_Deinit(Fuzz_Context &)159 static void Fuzz_Deinit(Fuzz_Context& /*ctx*/) {
160 if (rf_cback) {
161 tNFC_CONN conn = {
162 .deactivate = {.status = NFC_STATUS_OK,
163 .type = NFC_DEACTIVATE_TYPE_IDLE,
164 .is_ntf = true,
165 .reason = NFC_DEACTIVATE_REASON_DH_REQ_FAILED}};
166
167 rf_cback(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, &conn);
168 }
169 }
170
Fuzz_Run(Fuzz_Context & ctx)171 static void Fuzz_Run(Fuzz_Context& ctx) {
172 for (auto it = ctx.Data.cbegin() + 1; it != ctx.Data.cend(); ++it) {
173 NFC_HDR* p_msg;
174 p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size());
175 if (p_msg == nullptr || it->size() < 1) {
176 FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size());
177 return;
178 }
179
180 /* Initialize NFC_HDR */
181 p_msg->len = it->size() - 1;
182 p_msg->offset = 0;
183
184 uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
185 memcpy(p, it->data(), it->size());
186
187 tNFC_CONN conn = {.data = {
188 .status = NFC_STATUS_OK,
189 .p_data = p_msg,
190 }};
191
192 FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zd]=%s", ctx.SubType,
193 it - ctx.Data.cbegin(), ctx.Data.size() - 1,
194 BytesToHex(*it).c_str());
195
196 rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn);
197 }
198 }
199
Type2_FixPackets(uint8_t,std::vector<bytes_t> &)200 void Type2_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& /*Data*/) {}
201
Type2_Fuzz(uint8_t SubType,const std::vector<bytes_t> & Data)202 void Type2_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Data) {
203 Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Data);
204 if (Fuzz_Init(ctx)) {
205 Fuzz_Run(ctx);
206 }
207
208 Fuzz_Deinit(ctx);
209 }
210