1*7eba2f3bSAndroid Build Coastguard Worker #include "fuzz.h"
2*7eba2f3bSAndroid Build Coastguard Worker
3*7eba2f3bSAndroid Build Coastguard Worker #define MODULE_NAME "Type4 Emulator:"
4*7eba2f3bSAndroid Build Coastguard Worker
5*7eba2f3bSAndroid Build Coastguard Worker enum {
6*7eba2f3bSAndroid Build Coastguard Worker SUB_TYPE_READONLY,
7*7eba2f3bSAndroid Build Coastguard Worker SUB_TYPE_READWRITE,
8*7eba2f3bSAndroid Build Coastguard Worker
9*7eba2f3bSAndroid Build Coastguard Worker SUB_TYPE_MAX
10*7eba2f3bSAndroid Build Coastguard Worker };
11*7eba2f3bSAndroid Build Coastguard Worker
ce_cback(tCE_EVENT event,tCE_DATA * p_ce_data)12*7eba2f3bSAndroid Build Coastguard Worker static void ce_cback(tCE_EVENT event, tCE_DATA* p_ce_data) {
13*7eba2f3bSAndroid Build Coastguard Worker FUZZLOG(MODULE_NAME ": event=0x%02x, p_ce_data=%p", event, p_ce_data);
14*7eba2f3bSAndroid Build Coastguard Worker
15*7eba2f3bSAndroid Build Coastguard Worker if (event == CE_T4T_RAW_FRAME_EVT) {
16*7eba2f3bSAndroid Build Coastguard Worker if (p_ce_data->raw_frame.p_data) {
17*7eba2f3bSAndroid Build Coastguard Worker GKI_freebuf(p_ce_data->raw_frame.p_data);
18*7eba2f3bSAndroid Build Coastguard Worker p_ce_data->raw_frame.p_data = nullptr;
19*7eba2f3bSAndroid Build Coastguard Worker }
20*7eba2f3bSAndroid Build Coastguard Worker }
21*7eba2f3bSAndroid Build Coastguard Worker }
22*7eba2f3bSAndroid Build Coastguard Worker
Init(Fuzz_Context &)23*7eba2f3bSAndroid Build Coastguard Worker static bool Init(Fuzz_Context& /*ctx*/) {
24*7eba2f3bSAndroid Build Coastguard Worker tNFC_ACTIVATE_DEVT activate_params = {
25*7eba2f3bSAndroid Build Coastguard Worker .protocol = NFC_PROTOCOL_ISO_DEP,
26*7eba2f3bSAndroid Build Coastguard Worker };
27*7eba2f3bSAndroid Build Coastguard Worker
28*7eba2f3bSAndroid Build Coastguard Worker ce_init();
29*7eba2f3bSAndroid Build Coastguard Worker if (NFC_STATUS_OK != CE_SetActivatedTagType(&activate_params, 0, ce_cback)) {
30*7eba2f3bSAndroid Build Coastguard Worker FUZZLOG(MODULE_NAME ": CE_SetActivatedTagType failed");
31*7eba2f3bSAndroid Build Coastguard Worker return false;
32*7eba2f3bSAndroid Build Coastguard Worker }
33*7eba2f3bSAndroid Build Coastguard Worker
34*7eba2f3bSAndroid Build Coastguard Worker if (CE_T4T_AID_HANDLE_INVALID == CE_T4tRegisterAID(0, nullptr, ce_cback)) {
35*7eba2f3bSAndroid Build Coastguard Worker return false;
36*7eba2f3bSAndroid Build Coastguard Worker }
37*7eba2f3bSAndroid Build Coastguard Worker
38*7eba2f3bSAndroid Build Coastguard Worker uint8_t AID[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
39*7eba2f3bSAndroid Build Coastguard Worker if (CE_T4T_AID_HANDLE_INVALID ==
40*7eba2f3bSAndroid Build Coastguard Worker CE_T4tRegisterAID(sizeof(AID), AID, ce_cback)) {
41*7eba2f3bSAndroid Build Coastguard Worker return false;
42*7eba2f3bSAndroid Build Coastguard Worker }
43*7eba2f3bSAndroid Build Coastguard Worker
44*7eba2f3bSAndroid Build Coastguard Worker return true;
45*7eba2f3bSAndroid Build Coastguard Worker }
46*7eba2f3bSAndroid Build Coastguard Worker
Init_ReadOnly(Fuzz_Context & ctx)47*7eba2f3bSAndroid Build Coastguard Worker static bool Init_ReadOnly(Fuzz_Context& ctx) {
48*7eba2f3bSAndroid Build Coastguard Worker const uint16_t size_max = 1024;
49*7eba2f3bSAndroid Build Coastguard Worker const uint16_t ndef_len = 256;
50*7eba2f3bSAndroid Build Coastguard Worker
51*7eba2f3bSAndroid Build Coastguard Worker auto ndef_msg = ctx.GetBuffer(size_max);
52*7eba2f3bSAndroid Build Coastguard Worker
53*7eba2f3bSAndroid Build Coastguard Worker return NFC_STATUS_OK ==
54*7eba2f3bSAndroid Build Coastguard Worker CE_T4tSetLocalNDEFMsg(true, size_max, ndef_len, ndef_msg, nullptr);
55*7eba2f3bSAndroid Build Coastguard Worker }
56*7eba2f3bSAndroid Build Coastguard Worker
Init_ReadWrite(Fuzz_Context & ctx)57*7eba2f3bSAndroid Build Coastguard Worker static bool Init_ReadWrite(Fuzz_Context& ctx) {
58*7eba2f3bSAndroid Build Coastguard Worker const uint16_t size_max = 1024;
59*7eba2f3bSAndroid Build Coastguard Worker const uint16_t ndef_len = 256;
60*7eba2f3bSAndroid Build Coastguard Worker
61*7eba2f3bSAndroid Build Coastguard Worker auto ndef_msg = ctx.GetBuffer(size_max);
62*7eba2f3bSAndroid Build Coastguard Worker auto scratch_buf = ctx.GetBuffer(size_max);
63*7eba2f3bSAndroid Build Coastguard Worker
64*7eba2f3bSAndroid Build Coastguard Worker return NFC_STATUS_OK == CE_T4tSetLocalNDEFMsg(false, size_max, ndef_len,
65*7eba2f3bSAndroid Build Coastguard Worker ndef_msg, scratch_buf);
66*7eba2f3bSAndroid Build Coastguard Worker }
67*7eba2f3bSAndroid Build Coastguard Worker
Fuzz_Init(Fuzz_Context & ctx)68*7eba2f3bSAndroid Build Coastguard Worker static bool Fuzz_Init(Fuzz_Context& ctx) {
69*7eba2f3bSAndroid Build Coastguard Worker if (!Init(ctx)) {
70*7eba2f3bSAndroid Build Coastguard Worker FUZZLOG(MODULE_NAME ": initialization failed");
71*7eba2f3bSAndroid Build Coastguard Worker return false;
72*7eba2f3bSAndroid Build Coastguard Worker }
73*7eba2f3bSAndroid Build Coastguard Worker
74*7eba2f3bSAndroid Build Coastguard Worker bool result = true;
75*7eba2f3bSAndroid Build Coastguard Worker switch (ctx.SubType) {
76*7eba2f3bSAndroid Build Coastguard Worker case SUB_TYPE_READONLY:
77*7eba2f3bSAndroid Build Coastguard Worker result = Init_ReadOnly(ctx);
78*7eba2f3bSAndroid Build Coastguard Worker break;
79*7eba2f3bSAndroid Build Coastguard Worker case SUB_TYPE_READWRITE:
80*7eba2f3bSAndroid Build Coastguard Worker result = Init_ReadWrite(ctx);
81*7eba2f3bSAndroid Build Coastguard Worker break;
82*7eba2f3bSAndroid Build Coastguard Worker default:
83*7eba2f3bSAndroid Build Coastguard Worker FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType);
84*7eba2f3bSAndroid Build Coastguard Worker result = false;
85*7eba2f3bSAndroid Build Coastguard Worker break;
86*7eba2f3bSAndroid Build Coastguard Worker }
87*7eba2f3bSAndroid Build Coastguard Worker
88*7eba2f3bSAndroid Build Coastguard Worker if (!result) {
89*7eba2f3bSAndroid Build Coastguard Worker FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType);
90*7eba2f3bSAndroid Build Coastguard Worker }
91*7eba2f3bSAndroid Build Coastguard Worker
92*7eba2f3bSAndroid Build Coastguard Worker return result;
93*7eba2f3bSAndroid Build Coastguard Worker }
94*7eba2f3bSAndroid Build Coastguard Worker
Fuzz_Run(Fuzz_Context & ctx)95*7eba2f3bSAndroid Build Coastguard Worker static void Fuzz_Run(Fuzz_Context& ctx) {
96*7eba2f3bSAndroid Build Coastguard Worker for (auto it = ctx.Data.cbegin(); it != ctx.Data.cend(); ++it) {
97*7eba2f3bSAndroid Build Coastguard Worker NFC_HDR* p_msg;
98*7eba2f3bSAndroid Build Coastguard Worker p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size());
99*7eba2f3bSAndroid Build Coastguard Worker if (p_msg == nullptr) {
100*7eba2f3bSAndroid Build Coastguard Worker FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size());
101*7eba2f3bSAndroid Build Coastguard Worker return;
102*7eba2f3bSAndroid Build Coastguard Worker }
103*7eba2f3bSAndroid Build Coastguard Worker
104*7eba2f3bSAndroid Build Coastguard Worker /* Initialize NFC_HDR */
105*7eba2f3bSAndroid Build Coastguard Worker p_msg->len = it->size();
106*7eba2f3bSAndroid Build Coastguard Worker p_msg->offset = 0;
107*7eba2f3bSAndroid Build Coastguard Worker
108*7eba2f3bSAndroid Build Coastguard Worker uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
109*7eba2f3bSAndroid Build Coastguard Worker memcpy(p, it->data(), it->size());
110*7eba2f3bSAndroid Build Coastguard Worker
111*7eba2f3bSAndroid Build Coastguard Worker tNFC_CONN conn = {.data = {
112*7eba2f3bSAndroid Build Coastguard Worker .status = NFC_STATUS_OK,
113*7eba2f3bSAndroid Build Coastguard Worker .p_data = p_msg,
114*7eba2f3bSAndroid Build Coastguard Worker }};
115*7eba2f3bSAndroid Build Coastguard Worker
116*7eba2f3bSAndroid Build Coastguard Worker FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zu]=%s", ctx.SubType,
117*7eba2f3bSAndroid Build Coastguard Worker it - ctx.Data.cbegin() + 1, ctx.Data.size(),
118*7eba2f3bSAndroid Build Coastguard Worker BytesToHex(*it).c_str());
119*7eba2f3bSAndroid Build Coastguard Worker
120*7eba2f3bSAndroid Build Coastguard Worker rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn);
121*7eba2f3bSAndroid Build Coastguard Worker }
122*7eba2f3bSAndroid Build Coastguard Worker }
123*7eba2f3bSAndroid Build Coastguard Worker
Type4_FixPackets(uint8_t,std::vector<bytes_t> & Packets)124*7eba2f3bSAndroid Build Coastguard Worker void Type4_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& Packets) {
125*7eba2f3bSAndroid Build Coastguard Worker const uint8_t valid_cmds[] = {T4T_CMD_INS_SELECT, T4T_CMD_INS_READ_BINARY,
126*7eba2f3bSAndroid Build Coastguard Worker T4T_CMD_INS_UPDATE_BINARY};
127*7eba2f3bSAndroid Build Coastguard Worker
128*7eba2f3bSAndroid Build Coastguard Worker for (auto it = Packets.begin() + 1; it != Packets.end(); ++it) {
129*7eba2f3bSAndroid Build Coastguard Worker if (it->size() < T4T_CMD_MIN_HDR_SIZE) {
130*7eba2f3bSAndroid Build Coastguard Worker it->resize(T4T_CMD_MIN_HDR_SIZE);
131*7eba2f3bSAndroid Build Coastguard Worker }
132*7eba2f3bSAndroid Build Coastguard Worker
133*7eba2f3bSAndroid Build Coastguard Worker auto p = it->data();
134*7eba2f3bSAndroid Build Coastguard Worker p[0] = T4T_CMD_CLASS;
135*7eba2f3bSAndroid Build Coastguard Worker p[1] = valid_cmds[p[1] % sizeof(valid_cmds)];
136*7eba2f3bSAndroid Build Coastguard Worker }
137*7eba2f3bSAndroid Build Coastguard Worker }
138*7eba2f3bSAndroid Build Coastguard Worker
Type4_Fuzz(uint8_t SubType,const std::vector<bytes_t> & Packets)139*7eba2f3bSAndroid Build Coastguard Worker void Type4_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Packets) {
140*7eba2f3bSAndroid Build Coastguard Worker Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Packets);
141*7eba2f3bSAndroid Build Coastguard Worker if (Fuzz_Init(ctx)) {
142*7eba2f3bSAndroid Build Coastguard Worker Fuzz_Run(ctx);
143*7eba2f3bSAndroid Build Coastguard Worker }
144*7eba2f3bSAndroid Build Coastguard Worker }
145