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