1 #include "nfc_integration_fuzzer_impl.h"
2
3 #include <android-base/logging.h>
4 #include <android-base/stringprintf.h>
5 #include <fuzzer/FuzzedDataProvider.h>
6
7 #include "nfa_ce_api.h"
8 #include "nfa_ee_api.h"
9 #include "nfa_rw_api.h"
10 #include "nfa_sys.h"
11 #include "nfc_api.h"
12 #include "nfc_int.h"
13 #include "nfc_task_helpers.h"
14 #include "rw_int.h"
15
16 extern uint32_t g_tick_count;
17 extern tRW_CB rw_cb;
18
19 FuzzedDataProvider* g_fuzzed_data;
20
21 static bool g_saw_event = false;
22 static tNFA_EE_DISCOVER_REQ g_ee_info;
23
fuzz_cback(tRW_EVENT event,tRW_DATA * p_rw_data)24 void fuzz_cback(tRW_EVENT event, tRW_DATA *p_rw_data) {
25 (void)event;
26 (void)p_rw_data;
27 }
28 constexpr int32_t kMaxFramesSize =
29 USHRT_MAX - NFC_HDR_SIZE - NCI_MSG_OFFSET_SIZE - NCI_DATA_HDR_SIZE - 3;
30
nfa_dm_callback(uint8_t event,tNFA_DM_CBACK_DATA *)31 static void nfa_dm_callback(uint8_t event, tNFA_DM_CBACK_DATA*) {
32 g_saw_event = true;
33 LOG(INFO) << android::base::StringPrintf("nfa_dm_callback got event %d",
34 event);
35 }
36
nfa_conn_callback(uint8_t event,tNFA_CONN_EVT_DATA *)37 static void nfa_conn_callback(uint8_t event, tNFA_CONN_EVT_DATA*) {
38 LOG(INFO) << android::base::StringPrintf("nfa_conn_callback got event %d",
39 event);
40 g_saw_event = true;
41 }
42
nfa_ee_callback(tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * p_data)43 static void nfa_ee_callback(tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* p_data) {
44 switch (event) {
45 case NFA_EE_DISCOVER_REQ_EVT: {
46 memcpy(&g_ee_info, &p_data->discover_req, sizeof(g_ee_info));
47 break;
48 }
49 }
50 }
51
52 // From packages/apps/Nfc/nci/jni/PeerToPeer.cpp
53 #define LLCP_DATA_LINK_TIMEOUT 2000
54
55 void nfc_process_timer_evt(void);
56
GetProtocol(const Protocol & protocol)57 static tNFC_PROTOCOL GetProtocol(const Protocol& protocol) {
58 switch (protocol.value()) {
59 case Protocol::FUZZER_PROTOCOL_UNKNOWN: {
60 return NFC_PROTOCOL_UNKNOWN;
61 }
62 case Protocol::FUZZER_PROTOCOL_T1T: {
63 return NFC_PROTOCOL_T1T;
64 }
65 case Protocol::FUZZER_PROTOCOL_T2T: {
66 return NFC_PROTOCOL_T2T;
67 }
68 case Protocol::FUZZER_PROTOCOL_T3T: {
69 return NFC_PROTOCOL_T3T;
70 }
71 case Protocol::FUZZER_PROTOCOL_T5T: {
72 return NFC_PROTOCOL_T5T;
73 }
74 case Protocol::FUZZER_PROTOCOL_ISO_DEP: {
75 return NFC_PROTOCOL_ISO_DEP;
76 }
77 case Protocol::FUZZER_PROTOCOL_NFC_DEP: {
78 return NFC_PROTOCOL_NFC_DEP;
79 }
80 case Protocol::FUZZER_PROTOCOL_MIFARE: {
81 return NFC_PROTOCOL_MIFARE;
82 }
83 case Protocol::FUZZER_PROTOCOL_ISO15693: {
84 return NFC_PROTOCOL_ISO15693;
85 }
86 case Protocol::FUZZER_PROTOCOL_B_PRIME: {
87 return NFC_PROTOCOL_B_PRIME;
88 }
89 case Protocol::FUZZER_PROTOCOL_KOVIO: {
90 return NFC_PROTOCOL_KOVIO;
91 }
92 }
93 }
94
GetDiscovery(const DiscoveryType & type)95 static tNFC_DISCOVERY_TYPE GetDiscovery(const DiscoveryType& type) {
96 switch (type.value()) {
97 case DiscoveryType::FUZZER_DISCOVERY_TYPE_POLL_A: {
98 return NFC_DISCOVERY_TYPE_POLL_A;
99 }
100 case DiscoveryType::FUZZER_DISCOVERY_TYPE_POLL_B: {
101 return NFC_DISCOVERY_TYPE_POLL_B;
102 }
103 case DiscoveryType::FUZZER_DISCOVERY_TYPE_POLL_F: {
104 return NFC_DISCOVERY_TYPE_POLL_F;
105 }
106 case DiscoveryType::FUZZER_DISCOVERY_TYPE_POLL_V: {
107 return NFC_DISCOVERY_TYPE_POLL_V;
108 }
109 case DiscoveryType::FUZZER_DISCOVERY_TYPE_LISTEN_A: {
110 return NFC_DISCOVERY_TYPE_LISTEN_A;
111 }
112 case DiscoveryType::FUZZER_DISCOVERY_TYPE_LISTEN_B: {
113 return NFC_DISCOVERY_TYPE_LISTEN_B;
114 }
115 case DiscoveryType::FUZZER_DISCOVERY_TYPE_LISTEN_F: {
116 return NFC_DISCOVERY_TYPE_LISTEN_F;
117 }
118 case DiscoveryType::FUZZER_DISCOVERY_TYPE_LISTEN_ISO15693: {
119 return NFC_DISCOVERY_TYPE_LISTEN_ISO15693;
120 }
121 case DiscoveryType::FUZZER_DISCOVERY_TYPE_POLL_B_PRIME: {
122 return NFC_DISCOVERY_TYPE_POLL_B_PRIME;
123 }
124 case DiscoveryType::FUZZER_DISCOVERY_TYPE_POLL_KOVIO: {
125 return NFC_DISCOVERY_TYPE_POLL_KOVIO;
126 }
127 case DiscoveryType::FUZZER_DISCOVERY_TYPE_LISTEN_B_PRIME: {
128 return NFC_DISCOVERY_TYPE_LISTEN_B_PRIME;
129 }
130 }
131 }
132
SerializeTechParameters(const tNFC_RF_TECH_PARAMS & params)133 std::vector<uint8_t> SerializeTechParameters(
134 const tNFC_RF_TECH_PARAMS& params) {
135 std::vector<uint8_t> vec;
136
137 switch (params.mode) {
138 case NCI_DISCOVERY_TYPE_POLL_A: {
139 const tNFC_RF_PA_PARAMS* pa = ¶ms.param.pa;
140 vec.push_back(pa->sens_res[0]);
141 vec.push_back(pa->sens_res[1]);
142 vec.push_back(pa->nfcid1_len);
143 vec.insert(vec.end(), pa->nfcid1, pa->nfcid1 + pa->nfcid1_len);
144
145 // sel_rsp of 0 is the same as not having it, so we just always send it
146 vec.push_back(1);
147 vec.push_back(pa->sel_rsp);
148
149 vec.push_back(pa->hr_len);
150 vec.insert(vec.end(), pa->hr, pa->hr + pa->hr_len);
151 break;
152 }
153 default: {
154 abort();
155 }
156 }
157
158 return vec;
159 }
160
161 // Serialize an NFC Activation event back to the spec wire format
SerializeNfcActivate(const tNFC_ACTIVATE_DEVT & activate,uint8_t buff_size,uint8_t num_buff,const std::string & rf_tech_param_buffer,const std::string & intf_param_buffer)162 std::vector<uint8_t> SerializeNfcActivate(
163 const tNFC_ACTIVATE_DEVT& activate, uint8_t buff_size, uint8_t num_buff,
164 const std::string& rf_tech_param_buffer,
165 const std::string& intf_param_buffer) {
166 std::vector<uint8_t> packet;
167 packet.push_back(activate.rf_disc_id);
168 packet.push_back(activate.intf_param.type);
169 packet.push_back(activate.protocol);
170 packet.push_back(activate.rf_tech_param.mode);
171 packet.push_back(buff_size);
172 packet.push_back(num_buff);
173
174 std::vector<uint8_t> tech_parameters(
175 rf_tech_param_buffer.begin(),
176 rf_tech_param_buffer
177 .end()); // = SerializeTechParameters(activate.rf_tech_param);
178 if (tech_parameters.size() > 256) {
179 tech_parameters.resize(256);
180 }
181 packet.push_back(tech_parameters.size());
182 packet.insert(packet.end(), tech_parameters.begin(), tech_parameters.end());
183
184 packet.push_back(activate.data_mode);
185 packet.push_back(activate.tx_bitrate);
186 packet.push_back(activate.rx_bitrate);
187
188 std::vector<uint8_t> activation_parameters(intf_param_buffer.begin(),
189 intf_param_buffer.end());
190 if (activation_parameters.size() > 256) {
191 activation_parameters.resize(256);
192 }
193
194 packet.push_back(activation_parameters.size());
195 packet.insert(packet.end(), activation_parameters.begin(),
196 activation_parameters.end());
197 return packet;
198 }
199
DoRfManageIntfActivated(const RfManageIntfActivated & activated)200 void DoRfManageIntfActivated(const RfManageIntfActivated& activated) {
201 // The event we want to generate
202 tNFC_ACTIVATE_DEVT activate_event = {};
203 activate_event.rf_disc_id = activated.rf_discovery_id();
204 activate_event.protocol = GetProtocol(activated.rf_protocol());
205 activate_event.data_mode = GetDiscovery(activated.data_mode());
206 activate_event.tx_bitrate = activated.tx_bitrate();
207 activate_event.rx_bitrate = activated.rx_bitrate();
208 uint8_t buff_size = activated.buff_size();
209 uint8_t num_buff = activated.num_buff();
210
211 std::vector<uint8_t> packet = SerializeNfcActivate(
212 activate_event, buff_size, num_buff, activated.rf_tech_param_buffer(),
213 activated.intf_param_buffer());
214
215 g_fake_hal->SimulatePacketArrival(NCI_MT_NTF, 0, NCI_GID_RF_MANAGE,
216 NCI_MSG_RF_INTF_ACTIVATED, packet.data(),
217 packet.size());
218 }
219
DoRfManagementNtf(const RfManagementNtf & ntf)220 void DoRfManagementNtf(const RfManagementNtf& ntf) {
221 switch (ntf.opcode_case()) {
222 case RfManagementNtf::kIntfActivated: {
223 DoRfManageIntfActivated(ntf.intf_activated());
224 break;
225 }
226 case RfManagementNtf::OPCODE_NOT_SET: {
227 break;
228 }
229 }
230 }
231
DoMtNtf(const MtNtf & ntf)232 void DoMtNtf(const MtNtf& ntf) {
233 switch (ntf.gid_case()) {
234 case MtNtf::kRfManage: {
235 DoRfManagementNtf(ntf.rf_manage());
236 break;
237 }
238 case MtNtf::GID_NOT_SET: {
239 break;
240 }
241 }
242 }
243
DoStructuredPacket(const SimulateStructuredPacket & packet)244 void DoStructuredPacket(const SimulateStructuredPacket& packet) {
245 switch (packet.packet_case()) {
246 case SimulateStructuredPacket::kNtf: {
247 DoMtNtf(packet.ntf());
248 break;
249 }
250 case SimulateStructuredPacket::PACKET_NOT_SET: {
251 break;
252 }
253 }
254 }
255
DoPacket(const SimulatePacketArrival & packet)256 void DoPacket(const SimulatePacketArrival& packet) {
257 uint8_t mt = packet.mt();
258 uint8_t pbf = packet.pbf();
259 uint8_t gid = packet.gid();
260 uint8_t opcode = static_cast<uint8_t>(packet.opcode());
261 bool need_flush = false;
262 if (mt == NCI_MT_DATA) {
263 // The gid field will be used as the connection ID. We should handle this
264 // a lot better but for now we let the existing gid enum get interpreted
265 // as a connection ID.
266 // gid = 0;
267 opcode = 0;
268 }
269
270 g_fake_hal->SimulatePacketArrival(mt, pbf, gid, opcode,
271 (unsigned char*)packet.packet().data(),
272 packet.packet().size());
273 if (need_flush) {
274 DoAllTasks(false);
275 }
276 }
277
DoOneCommand(std::vector<std::vector<uint8_t>> & bytes_container,const Command & command)278 void NfcIntegrationFuzzer::DoOneCommand(
279 std::vector<std::vector<uint8_t>>& bytes_container,
280 const Command& command) {
281 switch (command.command_case()) {
282 case Command::kSimulatePacketArrival: {
283 DoPacket(command.simulate_packet_arrival());
284 break;
285 }
286 case Command::kSimulateHalEvent: {
287 g_fake_hal->SimulateHALEvent(command.simulate_hal_event().hal_event(),
288 command.simulate_hal_event().hal_status());
289 break;
290 }
291 case Command::kSimulateStructuredPacket: {
292 DoStructuredPacket(command.simulate_structured_packet());
293 break;
294 }
295 case Command::kSendRawFrame: {
296 std::vector<uint8_t> frame(
297 command.send_raw_frame().data(),
298 command.send_raw_frame().data() + command.send_raw_frame().size());
299 uint16_t frameSize =
300 frame.size() <= kMaxFramesSize ? frame.size() : kMaxFramesSize;
301 NFA_SendRawFrame(frame.data(), frameSize,
302 /*presence check start delay*/ 0);
303 break;
304 }
305 case Command::kDoNciMessages: {
306 nfc_process_nci_messages();
307 break;
308 }
309 case Command::kDoNfaTasks: {
310 nfc_process_nfa_messages();
311 break;
312 }
313 case Command::kSimulateTimerEvent: {
314 nfc_process_timer_evt();
315 break;
316 }
317 case Command::kSimulateQuickTimerEvent: {
318 nfc_process_quick_timer_evt();
319 break;
320 }
321 case Command::kSelect: {
322 NFA_Select(command.select().rf_select_id(),
323 GetProtocol(command.select().protocol()),
324 command.select().rf_interface());
325 break;
326 }
327 case Command::kConfigureUiccListenTech: {
328 if (g_ee_info.num_ee > 0) {
329 uint8_t handle = command.configure_uicc_listen_tech().ee_handle();
330 handle = g_ee_info.ee_disc_info[handle % g_ee_info.num_ee].ee_handle;
331 NFA_CeConfigureUiccListenTech(
332 handle, command.configure_uicc_listen_tech().tech_mask());
333 NFA_EeClearDefaultTechRouting(handle, 0xFF);
334 NFA_EeSetDefaultTechRouting(handle, 0xFF, 0, 0, 0, 0, 0);
335 }
336 break;
337 }
338 case Command::kRegisterT3T: {
339 uint8_t nfcid2[NCI_RF_F_UID_LEN] = {};
340 uint8_t t3tPmm[NCI_T3T_PMM_LEN] = {};
341 NFA_CeRegisterFelicaSystemCodeOnDH(0, nfcid2, t3tPmm, nfa_conn_callback);
342 const uint8_t SYS_CODE_PWR_STATE_HOST = 0x01;
343 NFA_EeAddSystemCodeRouting(0, NCI_DH_ID, SYS_CODE_PWR_STATE_HOST);
344 break;
345 }
346 case Command::kStartRfDiscovery: {
347 NFA_StartRfDiscovery();
348 break;
349 }
350 case Command::kStopRfDiscovery: {
351 NFA_StopRfDiscovery();
352 break;
353 }
354 case Command::kSetIsoListenTech: {
355 NFA_CeSetIsoDepListenTech(
356 fuzzed_data_.ConsumeIntegralInRange<uint8_t>(0, 0xFF));
357 NFA_CeRegisterAidOnDH(nullptr, 0, nfa_conn_callback);
358 break;
359 }
360 case Command::kRwFormatTag: {
361 NFA_RwFormatTag();
362 break;
363 }
364 case Command::kRwPresenceCheck: {
365 NFA_RwPresenceCheck(command.rw_presence_check().option());
366 break;
367 }
368 case Command::kRwSetTagReadOnly: {
369 NFA_RwSetTagReadOnly(command.rw_set_tag_read_only());
370 break;
371 }
372 case Command::kEeUpdateNow: {
373 NFA_EeUpdateNow();
374 break;
375 }
376 case Command::kEeAddAidRouting: {
377 uint8_t handle = command.ee_add_aid_routing().ee_handle();
378 if (g_ee_info.num_ee) {
379 handle = g_ee_info.ee_disc_info[handle % g_ee_info.num_ee].ee_handle;
380 }
381 std::vector<uint8_t> aid(command.ee_add_aid_routing().aid().data(),
382 command.ee_add_aid_routing().aid().data() +
383 command.ee_add_aid_routing().aid().size());
384 tNFA_EE_PWR_STATE power_state =
385 command.ee_add_aid_routing().power_state();
386 uint8_t aidInfo = command.ee_add_aid_routing().aid_info();
387 NFA_EeAddAidRouting(handle, aid.size(), aid.data(), power_state, aidInfo);
388 break;
389 }
390 case Command::kReadNdef: {
391 NFA_RwReadNDef();
392 break;
393 }
394 case Command::kDetectNdef: {
395 NFA_RwDetectNDef();
396 break;
397 }
398 case Command::kWriteNdef: {
399 bytes_container.emplace_back(command.write_ndef().size() % 1024);
400 NFA_RwWriteNDef(bytes_container.back().data(),
401 bytes_container.back().size());
402 break;
403 }
404 case Command::COMMAND_NOT_SET: {
405 break;
406 }
407 }
408 }
409
NfcIntegrationFuzzer(const Session * session)410 NfcIntegrationFuzzer::NfcIntegrationFuzzer(const Session* session)
411 : session_(session),
412 fuzzed_data_(
413 reinterpret_cast<const uint8_t*>(session->data_provider().data()),
414 session->data_provider().size()) {
415 g_fuzzed_data = &fuzzed_data_;
416 }
417
Setup()418 bool NfcIntegrationFuzzer::Setup() {
419 g_tick_count = 0;
420 memset(&g_ee_info, 0, sizeof(g_ee_info));
421 NFA_Init(&fuzzed_hal_entry);
422
423 rw_cb.p_cback = &fuzz_cback;
424 NFA_Enable(nfa_dm_callback, nfa_conn_callback);
425 DoAllTasks(false);
426
427 NFA_EeRegister(nfa_ee_callback);
428 NFA_EeSetDefaultProtoRouting(NFC_DH_ID, NFA_PROTOCOL_MASK_ISO_DEP, 0, 0, 0, 0,
429 0);
430
431 DoPacket(session_->setup_packet());
432 g_saw_event = false;
433 DoAllTasks(false);
434 if (!g_saw_event) {
435 return false;
436 }
437
438 NFA_EnableListening();
439 NFA_EnablePolling(NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B |
440 NFA_TECHNOLOGY_MASK_F | NFA_TECHNOLOGY_MASK_V |
441 NFA_TECHNOLOGY_MASK_B_PRIME | NFA_TECHNOLOGY_MASK_A_ACTIVE |
442 NFA_TECHNOLOGY_MASK_F_ACTIVE | NFA_TECHNOLOGY_MASK_KOVIO);
443
444 NFA_EnableDtamode(static_cast<tNFA_eDtaModes>(session_->dta_mode()));
445 NFA_StartRfDiscovery();
446
447 DoAllTasks(false);
448 return true;
449 }
450
RunCommands()451 void NfcIntegrationFuzzer::RunCommands() {
452 for (const Command& command : session_->commands()) {
453 DoOneCommand(bytes_container_, command);
454 }
455 }
456
TearDown()457 void NfcIntegrationFuzzer::TearDown() {
458 // Do any remaining tasks including pending timers
459 DoAllTasks(true);
460
461 // Issue a disable command then clear pending tasks
462 // and timers again
463 NFA_Disable(false);
464 DoAllTasks(true);
465 }
466