1 #include "fuzz.h" 2 3 #define MODULE_NAME "Type5 Read/Write" 4 5 enum { 6 SUB_TYPE_INVENTORY, 7 SUB_TYPE_STAY_QUIET, 8 SUB_TYPE_READ_SINGLEBLOCK, 9 SUB_TYPE_WRITE_SINGLEBLOCK, 10 SUB_TYPE_LOCK_BLOCK, 11 SUB_TYPE_READ_MULTIPLEBLOCKS, 12 SUB_TYPE_WRITE_MULTIPLEBLOCKS, 13 SUB_TYPE_SELECT, 14 SUB_TYPE_RESET_TO_READY, 15 SUB_TYPE_WRITE_AFI, 16 SUB_TYPE_LOCK_AFI, 17 SUB_TYPE_WRITE_DSFID, 18 SUB_TYPE_LOCK_DSFID, 19 SUB_TYPE_GET_SYS_INFO, 20 SUB_TYPE_GET_MULTI_BLOCK_SECURITY_STATUS, 21 SUB_TYPE_DETECT_NDEF, 22 SUB_TYPE_READ_NDEF, 23 SUB_TYPE_UPDATE_NDEF, 24 SUB_TYPE_FORMAT_NDEF, 25 SUB_TYPE_SET_TAG_READONLY, 26 SUB_TYPE_PRESENCE_CHECK, 27 28 SUB_TYPE_MAX 29 }; 30 31 #define TEST_UID_VALUE \ 32 { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 } 33 // const uint8_t TEST_UID[] = TEST_UID_VALUE; 34 rw_cback(tRW_EVENT event,tRW_DATA * p_rw_data)35 static void rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) { 36 FUZZLOG(MODULE_NAME ": rw_cback: event=0x%02x, p_rw_data=%p", event, 37 p_rw_data); 38 if (event == RW_I93_DATA_EVT || event == RW_I93_NDEF_READ_EVT || 39 event == RW_I93_NDEF_READ_CPLT_EVT) { 40 if (p_rw_data->i93_data.p_data) { 41 GKI_freebuf(p_rw_data->i93_data.p_data); 42 p_rw_data->i93_data.p_data = nullptr; 43 } 44 } else if (event == RW_I93_RAW_FRAME_EVT) { 45 if (p_rw_data->raw_frame.p_data) { 46 GKI_freebuf(p_rw_data->raw_frame.p_data); 47 p_rw_data->raw_frame.p_data = nullptr; 48 } 49 } 50 } 51 Init(Fuzz_Context &)52 static bool Init(Fuzz_Context& /*ctx*/) { 53 tNFC_ACTIVATE_DEVT activate_params = { 54 .protocol = static_cast<tNFC_PROTOCOL>(NFC_PROTOCOL_T5T), 55 .rf_tech_param = {.mode = NFC_DISCOVERY_TYPE_POLL_V, 56 .param = {.pi93 = { 57 .uid = TEST_UID_VALUE, 58 }}}}; 59 60 rw_init(); 61 if (NFC_STATUS_OK != RW_SetActivatedTagType(&activate_params, rw_cback)) { 62 FUZZLOG(MODULE_NAME ": RW_SetActivatedTagType failed"); 63 return false; 64 } 65 66 return true; 67 } 68 Init_Inventory(Fuzz_Context &)69 static bool Init_Inventory(Fuzz_Context& /*ctx*/) { 70 uint8_t uid[] = TEST_UID_VALUE; 71 return NFC_STATUS_OK == RW_I93Inventory(false, 0, uid); 72 } 73 Init_StayQuiet(Fuzz_Context &)74 static bool Init_StayQuiet(Fuzz_Context& /*ctx*/) { 75 uint8_t uid[] = TEST_UID_VALUE; 76 return NFC_STATUS_OK == RW_I93StayQuiet(uid); 77 } 78 Init_ReadSingleBlock(Fuzz_Context &)79 static bool Init_ReadSingleBlock(Fuzz_Context& /*ctx*/) { 80 return NFC_STATUS_OK == RW_I93ReadSingleBlock(0); 81 } 82 Init_WriteSingleBlock(Fuzz_Context & ctx)83 static bool Init_WriteSingleBlock(Fuzz_Context& ctx) { 84 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 85 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}; 86 87 auto scratch = ctx.GetBuffer(sizeof(data), data); 88 return NFC_STATUS_OK == RW_I93WriteSingleBlock(0, scratch); 89 } 90 Init_LockBlock(Fuzz_Context &)91 static bool Init_LockBlock(Fuzz_Context& /*ctx*/) { 92 return NFC_STATUS_OK == RW_I93LockBlock(0); 93 } 94 Init_ReadMultipleBlocks(Fuzz_Context &)95 static bool Init_ReadMultipleBlocks(Fuzz_Context& /*ctx*/) { 96 return NFC_STATUS_OK == RW_I93ReadMultipleBlocks(0, 10); 97 } 98 Init_WriteMultipleBlocks(Fuzz_Context & ctx)99 static bool Init_WriteMultipleBlocks(Fuzz_Context& ctx) { 100 auto scratch = ctx.GetBuffer(16 * 10); 101 return NFC_STATUS_OK == RW_I93WriteMultipleBlocks(0, 10, scratch); 102 } 103 Init_Select(Fuzz_Context &)104 static bool Init_Select(Fuzz_Context& /*ctx*/) { 105 uint8_t uid[] = TEST_UID_VALUE; 106 return NFC_STATUS_OK == RW_I93Select(uid); 107 } 108 Init_ResetToReady(Fuzz_Context &)109 static bool Init_ResetToReady(Fuzz_Context& /*ctx*/) { 110 return NFC_STATUS_OK == RW_I93ResetToReady(); 111 } 112 Init_WriteAFI(Fuzz_Context &)113 static bool Init_WriteAFI(Fuzz_Context& /*ctx*/) { 114 return NFC_STATUS_OK == RW_I93WriteAFI(0x11); 115 } 116 Init_LockAFI(Fuzz_Context &)117 static bool Init_LockAFI(Fuzz_Context& /*ctx*/) { 118 return NFC_STATUS_OK == RW_I93LockAFI(); 119 } 120 Init_WriteDSFID(Fuzz_Context &)121 static bool Init_WriteDSFID(Fuzz_Context& /*ctx*/) { 122 return NFC_STATUS_OK == RW_I93WriteDSFID(0x22); 123 } 124 Init_LockDSFID(Fuzz_Context &)125 static bool Init_LockDSFID(Fuzz_Context& /*ctx*/) { 126 return NFC_STATUS_OK == RW_I93LockDSFID(); 127 } 128 Init_GetSysInfo(Fuzz_Context &)129 static bool Init_GetSysInfo(Fuzz_Context& /*ctx*/) { 130 uint8_t uid[] = TEST_UID_VALUE; 131 return NFC_STATUS_OK == RW_I93GetSysInfo(uid); 132 } 133 Init_GetMultiBlockSecurityStatus(Fuzz_Context &)134 static bool Init_GetMultiBlockSecurityStatus(Fuzz_Context& /*ctx*/) { 135 return NFC_STATUS_OK == RW_I93GetMultiBlockSecurityStatus(0, 10); 136 } 137 Init_DetectNDef(Fuzz_Context &)138 static bool Init_DetectNDef(Fuzz_Context& /*ctx*/) { 139 return NFC_STATUS_OK == RW_I93DetectNDef(); 140 } 141 Init_ReadNDef(Fuzz_Context &)142 static bool Init_ReadNDef(Fuzz_Context& /*ctx*/) { 143 return NFC_STATUS_OK == RW_I93ReadNDef(); 144 } 145 Init_UpdateNDef(Fuzz_Context & ctx)146 static bool Init_UpdateNDef(Fuzz_Context& ctx) { 147 const uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 148 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}; 149 150 auto scratch = ctx.GetBuffer(sizeof(data), data); 151 return NFC_STATUS_OK == RW_I93UpdateNDef(sizeof(data), scratch); 152 } 153 Init_FormatNDef(Fuzz_Context &)154 static bool Init_FormatNDef(Fuzz_Context& /*ctx*/) { 155 return NFC_STATUS_OK == RW_I93FormatNDef(); 156 } 157 Init_SetTagReadOnly(Fuzz_Context &)158 static bool Init_SetTagReadOnly(Fuzz_Context& /*ctx*/) { 159 return NFC_STATUS_OK == RW_I93SetTagReadOnly(); 160 } 161 Init_PresenceCheck(Fuzz_Context &)162 static bool Init_PresenceCheck(Fuzz_Context& /*ctx*/) { 163 return NFC_STATUS_OK == RW_I93PresenceCheck(); 164 } 165 Fuzz_Init(Fuzz_Context & ctx)166 static bool Fuzz_Init(Fuzz_Context& ctx) { 167 if (!Init(ctx)) { 168 FUZZLOG(MODULE_NAME ": initialization failed"); 169 return false; 170 } 171 172 bool result = false; 173 switch (ctx.SubType) { 174 case SUB_TYPE_INVENTORY: 175 result = Init_Inventory(ctx); 176 break; 177 178 case SUB_TYPE_STAY_QUIET: 179 result = Init_StayQuiet(ctx); 180 break; 181 182 case SUB_TYPE_READ_SINGLEBLOCK: 183 result = Init_ReadSingleBlock(ctx); 184 break; 185 186 case SUB_TYPE_WRITE_SINGLEBLOCK: 187 result = Init_WriteSingleBlock(ctx); 188 break; 189 190 case SUB_TYPE_LOCK_BLOCK: 191 result = Init_LockBlock(ctx); 192 break; 193 194 case SUB_TYPE_READ_MULTIPLEBLOCKS: 195 result = Init_ReadMultipleBlocks(ctx); 196 break; 197 198 case SUB_TYPE_WRITE_MULTIPLEBLOCKS: 199 result = Init_WriteMultipleBlocks(ctx); 200 break; 201 202 case SUB_TYPE_SELECT: 203 result = Init_Select(ctx); 204 break; 205 206 case SUB_TYPE_RESET_TO_READY: 207 result = Init_ResetToReady(ctx); 208 break; 209 210 case SUB_TYPE_WRITE_AFI: 211 result = Init_WriteAFI(ctx); 212 break; 213 214 case SUB_TYPE_LOCK_AFI: 215 result = Init_LockAFI(ctx); 216 break; 217 218 case SUB_TYPE_WRITE_DSFID: 219 result = Init_WriteDSFID(ctx); 220 break; 221 222 case SUB_TYPE_LOCK_DSFID: 223 result = Init_LockDSFID(ctx); 224 break; 225 226 case SUB_TYPE_GET_SYS_INFO: 227 result = Init_GetSysInfo(ctx); 228 break; 229 230 case SUB_TYPE_GET_MULTI_BLOCK_SECURITY_STATUS: 231 result = Init_GetMultiBlockSecurityStatus(ctx); 232 break; 233 234 case SUB_TYPE_DETECT_NDEF: 235 result = Init_DetectNDef(ctx); 236 break; 237 238 case SUB_TYPE_READ_NDEF: 239 result = Init_ReadNDef(ctx); 240 break; 241 242 case SUB_TYPE_UPDATE_NDEF: 243 result = Init_UpdateNDef(ctx); 244 break; 245 246 case SUB_TYPE_FORMAT_NDEF: 247 result = Init_FormatNDef(ctx); 248 break; 249 250 case SUB_TYPE_SET_TAG_READONLY: 251 result = Init_SetTagReadOnly(ctx); 252 break; 253 254 case SUB_TYPE_PRESENCE_CHECK: 255 result = Init_PresenceCheck(ctx); 256 break; 257 258 default: 259 FUZZLOG(MODULE_NAME ": Unknown command %d", ctx.SubType); 260 result = false; 261 break; 262 } 263 264 if (!result) { 265 FUZZLOG(MODULE_NAME ": Initializing command %02X failed", ctx.SubType); 266 } 267 268 return result; 269 } 270 Fuzz_Deinit(Fuzz_Context &)271 static void Fuzz_Deinit(Fuzz_Context& /*ctx*/) { 272 if (rf_cback) { 273 tRW_I93_CB* p_i93 = &rw_cb.tcb.i93; 274 if (p_i93->p_update_data) { 275 GKI_freebuf(p_i93->p_update_data); 276 p_i93->p_update_data = nullptr; 277 } 278 279 tNFC_CONN conn = { 280 .deactivate = {.status = NFC_STATUS_OK, 281 .type = NFC_DEACTIVATE_TYPE_IDLE, 282 .is_ntf = true, 283 .reason = NFC_DEACTIVATE_REASON_DH_REQ_FAILED}}; 284 285 rf_cback(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, &conn); 286 } 287 } 288 Fuzz_Run(Fuzz_Context & ctx)289 static void Fuzz_Run(Fuzz_Context& ctx) { 290 for (auto it = ctx.Data.cbegin() + 1; it != ctx.Data.cend(); ++it) { 291 NFC_HDR* p_msg; 292 p_msg = (NFC_HDR*)GKI_getbuf(sizeof(NFC_HDR) + it->size()); 293 if (p_msg == nullptr || it->size() < 1) { 294 FUZZLOG(MODULE_NAME ": GKI_getbuf returns null, size=%zu", it->size()); 295 return; 296 } 297 298 /* Initialize NFC_HDR */ 299 p_msg->len = it->size() - 1; 300 p_msg->offset = 0; 301 302 uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset; 303 memcpy(p, it->data(), it->size()); 304 305 tNFC_CONN conn = {.data = { 306 .status = NFC_STATUS_OK, 307 .p_data = p_msg, 308 }}; 309 310 FUZZLOG(MODULE_NAME ": SubType=%02X, Response[%zd/%zd]=%s", ctx.SubType, 311 it - ctx.Data.cbegin(), ctx.Data.size() - 1, 312 BytesToHex(*it).c_str()); 313 314 rf_cback(NFC_RF_CONN_ID, NFC_DATA_CEVT, &conn); 315 } 316 } 317 Type5_FixPackets(uint8_t,std::vector<bytes_t> &)318 void Type5_FixPackets(uint8_t /*SubType*/, std::vector<bytes_t>& /*Data*/) {} 319 Type5_Fuzz(uint8_t SubType,const std::vector<bytes_t> & Data)320 void Type5_Fuzz(uint8_t SubType, const std::vector<bytes_t>& Data) { 321 Fuzz_Context ctx(SubType % SUB_TYPE_MAX, Data); 322 if (Fuzz_Init(ctx)) { 323 Fuzz_Run(ctx); 324 } 325 326 Fuzz_Deinit(ctx); 327 } 328