• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "fuzz.h"
2 
3 #define MODULE_NAME "Type3 Emulator:"
4 
5 // Copied from ce_t3t.cc
6 enum {
7   CE_T3T_COMMAND_INVALID,
8   CE_T3T_COMMAND_NFC_FORUM,
9   CE_T3T_COMMAND_FELICA
10 };
11 
12 enum {
13   SUB_TYPE_READONLY,
14   SUB_TYPE_READWRITE,
15 
16   SUB_TYPE_MAX
17 };
18 
ce_cback(tCE_EVENT event,tCE_DATA * p_ce_data)19 static void ce_cback(tCE_EVENT event, tCE_DATA* p_ce_data) {
20   FUZZLOG(MODULE_NAME ": event=0x%02x, p_ce_data=%p", event, p_ce_data);
21 }
22 
23 #define TEST_NFCID_VALUE \
24   { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }
25 const uint8_t TEST_NFCID[] = TEST_NFCID_VALUE;
26 
Init(Fuzz_Context &)27 static bool Init(Fuzz_Context& /*ctx*/) {
28   tNFC_ACTIVATE_DEVT activate_params = {
29       .protocol = NFC_PROTOCOL_T3T,
30       .rf_tech_param = {.param = {.lf = {
31                                       .nfcid2 = TEST_NFCID_VALUE,
32                                   }}}};
33 
34   ce_init();
35   if (NFC_STATUS_OK != CE_SetActivatedTagType(&activate_params,
36                                               T3T_SYSTEM_CODE_NDEF, ce_cback)) {
37     FUZZLOG(MODULE_NAME ": CE_SetActivatedTagType failed");
38     return false;
39   }
40 
41   return true;
42 }
43 
Init_ReadOnly(Fuzz_Context & ctx)44 static bool Init_ReadOnly(Fuzz_Context& ctx) {
45   const uint32_t size_max = 1024;
46   const uint32_t size_current = 256;
47 
48   auto p_buf = ctx.GetBuffer(size_max);
49 
50   return NFC_STATUS_OK ==
51          CE_T3tSetLocalNDEFMsg(true, size_max, size_current, p_buf, nullptr);
52 }
53 
Init_ReadWrite(Fuzz_Context & ctx)54 static bool Init_ReadWrite(Fuzz_Context& ctx) {
55   const uint32_t size_max = 1024;
56   const uint32_t size_current = 256;
57 
58   auto p_buf = ctx.GetBuffer(size_max);
59   auto p_scratch = ctx.GetBuffer(size_max);
60 
61   return NFC_STATUS_OK ==
62          CE_T3tSetLocalNDEFMsg(false, size_max, size_current, p_buf, p_scratch);
63 }
64 
Fuzz_Init(Fuzz_Context & ctx)65 static bool Fuzz_Init(Fuzz_Context& ctx) {
66   if (!Init(ctx)) {
67     FUZZLOG(MODULE_NAME ": initialization failed");
68     return false;
69   }
70 
71   bool result = false;
72   switch (ctx.SubType) {
73     case SUB_TYPE_READONLY:
74       result = Init_ReadOnly(ctx);
75       break;
76     case SUB_TYPE_READWRITE:
77       result = Init_ReadWrite(ctx);
78       break;
79     default:
80       FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType);
81       result = false;
82       break;
83   }
84 
85   if (!result) {
86     FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType);
87   }
88 
89   return result;
90 }
91 
Fuzz_Run(Fuzz_Context & ctx)92 static void Fuzz_Run(Fuzz_Context& ctx) {
93   for (auto it = ctx.Data.cbegin(); it != ctx.Data.cend(); ++it) {
94     NFC_HDR* p_msg;
95     p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size());
96     if (p_msg == nullptr || it->size() < 1) {
97       FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size());
98       return;
99     }
100 
101     /* Initialize NFC_HDR */
102     p_msg->len = it->size() - 1;
103     p_msg->offset = 0;
104 
105     uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
106     memcpy(p, it->data(), it->size());
107 
108     tNFC_CONN conn = {.data = {
109                           .status = NFC_STATUS_OK,
110                           .p_data = p_msg,
111                       }};
112 
113     FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zu]=%s", ctx.SubType,
114             it - ctx.Data.cbegin() + 1, ctx.Data.size(),
115             BytesToHex(*it).c_str());
116 
117     rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn);
118   }
119 }
120 
Type3_FixPackets(uint8_t,std::vector<bytes_t> & Packets)121 void Type3_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& Packets) {
122   for (auto it = Packets.begin() + 1; it != Packets.end(); ++it) {
123     if (it->size() < T3T_MSG_CMD_COMMON_HDR_LEN) {
124       it->resize(T3T_MSG_CMD_COMMON_HDR_LEN);
125       memset(it->data(), 0, it->size());
126     }
127 
128     auto p = it->data();
129     p[0] = it->size();
130 
131     if (p[1] != CE_T3T_COMMAND_FELICA) {
132       memcpy(&p[2], TEST_NFCID, sizeof(TEST_NFCID));
133     }
134   }
135 }
136 
Type3_Fuzz(uint8_t SubType,const std::vector<bytes_t> & Packets)137 void Type3_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Packets) {
138   Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Packets);
139   if (Fuzz_Init(ctx)) {
140     Fuzz_Run(ctx);
141   }
142 }
143