1 #include "fuzz.h"
2
3 #define MODULE_NAME "MiFare Read/Write:"
4
5 enum {
6 SUB_TYPE_DETECT_NDEF,
7 SUB_TYPE_READ_NDEF,
8 SUB_TYPE_WRITE_NDEF,
9 SUB_TYPE_FORMAT_NDEF,
10
11 SUB_TYPE_MAX
12 };
13
14 // ========= Constants copied from rw_mfc.cc ================
15 #define RW_MFC_4K_Support 0x10
16 // ===========================================================
17
rw_cback(tRW_EVENT event,tRW_DATA * p_rw_data)18 static void rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
19 FUZZLOG(MODULE_NAME ": event=0x%02x, p_rw_data=%p", event, p_rw_data);
20
21 if (event == RW_MFC_RAW_FRAME_EVT) {
22 if (p_rw_data->raw_frame.p_data) {
23 GKI_freebuf(p_rw_data->raw_frame.p_data);
24 p_rw_data->raw_frame.p_data = nullptr;
25 }
26 } else if (event == RW_MFC_NDEF_READ_CPLT_EVT) {
27 if (p_rw_data->data.p_data) {
28 GKI_freebuf(p_rw_data->data.p_data);
29 p_rw_data->data.p_data = nullptr;
30 }
31 }
32 }
33
34 #define TEST_NFCID_VALUE \
35 { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA }
36
Init(Fuzz_Context &)37 static bool Init(Fuzz_Context& /*ctx*/) {
38 tNFC_ACTIVATE_DEVT activate_params = {
39 .protocol = NFC_PROTOCOL_MIFARE,
40 .rf_tech_param = {.mode = NFC_DISCOVERY_TYPE_POLL_A,
41 .param = {.pa = {
42 .sel_rsp = RW_MFC_4K_Support,
43 .nfcid1 = TEST_NFCID_VALUE,
44 .nfcid1_len = 10,
45 }}}};
46
47 rw_init();
48 if (NFC_STATUS_OK != RW_SetActivatedTagType(&activate_params, rw_cback)) {
49 FUZZLOG(MODULE_NAME ": RW_SetActivatedTagType failed");
50 return false;
51 }
52
53 return true;
54 }
55
Init_DetectNDef(Fuzz_Context &)56 static bool Init_DetectNDef(Fuzz_Context& /*ctx*/) {
57 return NFC_STATUS_OK == RW_MfcDetectNDef();
58 }
59
Init_ReadNDef(Fuzz_Context & ctx)60 static bool Init_ReadNDef(Fuzz_Context& ctx) {
61 auto scratch = ctx.GetBuffer(256);
62 return NFC_STATUS_OK == RW_MfcReadNDef(scratch, 256);
63 }
64
Init_WriteNDef(Fuzz_Context & ctx)65 static bool Init_WriteNDef(Fuzz_Context& ctx) {
66 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
67 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04};
68
69 auto scratch = ctx.GetBuffer(sizeof(data), data);
70 ;
71 return NFC_STATUS_OK == RW_MfcWriteNDef(sizeof(data), scratch);
72 }
73
Init_FormatNDef(Fuzz_Context &)74 static bool Init_FormatNDef(Fuzz_Context& /*ctx*/) {
75 return NFC_STATUS_OK == RW_MfcFormatNDef();
76 }
77
Fuzz_Init(Fuzz_Context & ctx)78 static bool Fuzz_Init(Fuzz_Context& ctx) {
79 if (!Init(ctx)) {
80 FUZZLOG(MODULE_NAME ": initialization failed");
81 return false;
82 }
83
84 bool result = false;
85 switch (ctx.SubType) {
86 case SUB_TYPE_DETECT_NDEF:
87 result = Init_DetectNDef(ctx);
88 break;
89 case SUB_TYPE_WRITE_NDEF:
90 result = Init_WriteNDef(ctx);
91 break;
92 case SUB_TYPE_READ_NDEF:
93 result = Init_ReadNDef(ctx);
94 break;
95 case SUB_TYPE_FORMAT_NDEF:
96 result = Init_FormatNDef(ctx);
97 break;
98 default:
99 FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType);
100 result = false;
101 break;
102 }
103
104 if (!result) {
105 FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType);
106 }
107
108 return result;
109 }
110
Fuzz_Deinit(Fuzz_Context &)111 static void Fuzz_Deinit(Fuzz_Context& /*ctx*/) {
112 if (rf_cback) {
113 tNFC_CONN conn = {
114 .deactivate = {.status = NFC_STATUS_OK,
115 .type = NFC_DEACTIVATE_TYPE_IDLE,
116 .is_ntf = true,
117 .reason = NFC_DEACTIVATE_REASON_DH_REQ_FAILED}};
118
119 rf_cback(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, &conn);
120 }
121 }
122
Fuzz_Run(Fuzz_Context & ctx)123 static void Fuzz_Run(Fuzz_Context& ctx) {
124 for (auto it = ctx.Data.cbegin() + 1; it != ctx.Data.cend(); ++it) {
125 NFC_HDR* p_msg;
126 p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size());
127 if (p_msg == nullptr) {
128 FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size());
129 return;
130 }
131
132 /* Initialize NFC_HDR */
133 p_msg->len = it->size();
134 p_msg->offset = 0;
135
136 uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
137 memcpy(p, it->data(), it->size());
138
139 tNFC_CONN conn = {.data = {
140 .status = NFC_STATUS_OK,
141 .p_data = p_msg,
142 }};
143
144 FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zu]=%s", ctx.SubType,
145 it - ctx.Data.cbegin() + 1, ctx.Data.size(),
146 BytesToHex(*it).c_str());
147
148 rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn);
149 }
150 }
151
Mfc_FixPackets(uint8_t,std::vector<bytes_t> &)152 void Mfc_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& /*Data*/) {}
153
Mfc_Fuzz(uint8_t SubType,const std::vector<bytes_t> & Data)154 void Mfc_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Data) {
155 Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Data);
156 if (Fuzz_Init(ctx)) {
157 Fuzz_Run(ctx);
158 }
159
160 Fuzz_Deinit(ctx);
161 }
162