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