diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index 9a562e38..628b18ae 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -523,11 +523,11 @@ static data_frame_tx_t *cmd_processor_hf14a_set_field_on(uint16_t cmd, uint16_t if (mode != DEVICE_MODE_READER) { return data_frame_make(cmd, STATUS_DEVICE_MODE_ERROR, 0, NULL); } - + // Reset and turn on the antenna pcd_14a_reader_reset(); pcd_14a_reader_antenna_on(); - + return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL); } @@ -536,10 +536,10 @@ static data_frame_tx_t *cmd_processor_hf14a_set_field_off(uint16_t cmd, uint16_t if (mode != DEVICE_MODE_READER) { return data_frame_make(cmd, STATUS_DEVICE_MODE_ERROR, 0, NULL); } - + // Turn off the antenna pcd_14a_reader_antenna_off(); - + return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL); } @@ -724,11 +724,11 @@ static data_frame_tx_t *cmd_processor_hidprox_write_to_t55xx(uint16_t cmd, uint1 } uint8_t format = payload->id[0]; - uint32_t fc = bytes_to_num(payload->id+1, 4); + uint32_t fc = bytes_to_num(payload->id + 1, 4); uint64_t cn = payload->id[5]; - cn = (cn << 32) | (bytes_to_num(payload->id+6, 4)); + cn = (cn << 32) | (bytes_to_num(payload->id + 6, 4)); uint32_t il = payload->id[10]; - uint32_t oem = bytes_to_num(payload->id+11, 2); + uint32_t oem = bytes_to_num(payload->id + 11, 2); status = write_hidprox_to_t55xx(format, fc, cn, il, oem, payload->old_key, payload->new_keys, (length - offsetof(payload_t, new_keys)) / sizeof(payload->new_keys)); return data_frame_make(cmd, status, 0, NULL); } @@ -756,7 +756,7 @@ static data_frame_tx_t *cmd_processor_ioprox_scan(uint16_t cmd, uint16_t status, static data_frame_tx_t *cmd_processor_ioprox_write_to_t55xx(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { typedef struct { uint8_t card_data[16]; // ioprox_codec_t->data layout: version, facility code, card number, raw8 - uint8_t new_key[4]; + uint8_t new_key[4]; uint8_t old_keys[4]; // we can have more than one... struct just to compute offsets with min 1 key } PACKED payload_t; @@ -764,7 +764,7 @@ static data_frame_tx_t *cmd_processor_ioprox_write_to_t55xx(uint16_t cmd, uint16 // Validate packet length if (length < sizeof(payload_t) || - (length - offsetof(payload_t, old_keys)) % sizeof(payload->old_keys) != 0) { + (length - offsetof(payload_t, old_keys)) % sizeof(payload->old_keys) != 0) { return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL); } @@ -772,11 +772,11 @@ static data_frame_tx_t *cmd_processor_ioprox_write_to_t55xx(uint16_t cmd, uint16 // Pass card_data (including raw8 at index 4-11) directly to the T55xx writer. status = write_ioprox_to_t55xx( - payload->card_data, - payload->new_key, - payload->old_keys, - old_cnt - ); + payload->card_data, + payload->new_key, + payload->old_keys, + old_cnt + ); return data_frame_make(cmd, status, 0, NULL); } @@ -791,14 +791,14 @@ static data_frame_tx_t *cmd_processor_ioprox_write_to_t55xx(uint16_t cmd, uint16 */ static data_frame_tx_t *cmd_processor_ioprox_decode_raw(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { if (length != 8) return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL); - + uint8_t output[16]; uint8_t result = decode_ioprox_raw(data, output); - + if (result != STATUS_SUCCESS) { return data_frame_make(cmd, STATUS_CMD_ERR, 0, NULL); } - + return data_frame_make(cmd, STATUS_SUCCESS, 16, output); } @@ -812,11 +812,11 @@ static data_frame_tx_t *cmd_processor_ioprox_decode_raw(uint16_t cmd, uint16_t s */ static data_frame_tx_t *cmd_processor_ioprox_compose_id(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { if (length != 4) return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL); - + uint8_t output[16]; memset(output, 0, sizeof(output)); uint8_t result = encode_ioprox_params(data[0], data[1], (data[2] << 8) | data[3], output); - + if (result != STATUS_SUCCESS) { return data_frame_make(cmd, STATUS_CMD_ERR, 0, NULL); } @@ -904,7 +904,7 @@ static data_frame_tx_t *cmd_processor_lf_t55xx_write(uint16_t cmd, uint16_t stat #define GENERIC_READ_LEN 800 #define GENERIC_READ_TIMEOUT_MS 500 static data_frame_tx_t *cmd_processor_generic_read(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { - uint8_t *outdata = malloc(GENERIC_READ_LEN); + uint8_t *outdata = malloc(GENERIC_READ_LEN); if (outdata == NULL) { return data_frame_make(cmd, STATUS_MEM_ERR, 0, NULL); @@ -1279,7 +1279,7 @@ static data_frame_tx_t *cmd_processor_mf1_write_emu_block_data(uint16_t cmd, uin uint8_t block_index = data[0]; uint8_t block_count = (length - 1) / NFC_TAG_MF1_DATA_SIZE; if (block_index + block_count > NFC_TAG_MF1_BLOCK_MAX) { - return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL); + return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL); } tag_data_buffer_t *buffer = get_buffer_by_tag_type(TAG_TYPE_MIFARE_4096); nfc_tag_mf1_information_t *info = (nfc_tag_mf1_information_t *)buffer->buffer; @@ -2032,7 +2032,7 @@ static uint8_t auth_trace_do_auth(picc_14a_tag_t *tag, uint8_t type, uint8_t blo /* Capture NT — 32 bits, card→reader */ auth_trace_store(answer, 32, true); uint32_t nt = ((uint32_t)answer[0] << 24) | ((uint32_t)answer[1] << 16) - | ((uint32_t)answer[2] << 8) | (uint32_t)answer[3]; + | ((uint32_t)answer[2] << 8) | (uint32_t)answer[3]; /* Initialise Crypto1 with key (LSB-first, MIFARE convention) */ uint64_t ui64Key = 0; @@ -2071,7 +2071,7 @@ static uint8_t auth_trace_do_auth(picc_14a_tag_t *tag, uint8_t type, uint8_t blo /* Verify AT == prng_successor(nt, 64) ^ ks3 */ uint32_t at_recv = ((uint32_t)answer[0] << 24) | ((uint32_t)answer[1] << 16) - | ((uint32_t)answer[2] << 8) | (uint32_t)answer[3]; + | ((uint32_t)answer[2] << 8) | (uint32_t)answer[3]; uint32_t ntpp = prng_successor(nt_succ, 32) ^ crypto1_word(&pcs, 0, 0); status = (ntpp == at_recv) ? STATUS_HF_TAG_OK : STATUS_MF_ERR_AUTH; @@ -2276,11 +2276,16 @@ static data_frame_tx_t *cmd_processor_hf14a_4_set_anti_coll(uint16_t cmd, uint16 nfc_tag_14a_coll_res_reference_t *info = get_coll_res_data(true); if (info == NULL) return data_frame_make(cmd, STATUS_HF_TAG_NO, 0, NULL); uint16_t offset = 0; - *(info->size) = (nfc_tag_14a_uid_size)data[offset]; offset++; - memcpy(info->uid, &data[offset], *(info->size)); offset += *(info->size); - memcpy(info->atqa, &data[offset], 2); offset += 2; - info->sak[0] = data[offset]; offset++; - info->ats->length = data[offset]; offset++; + *(info->size) = (nfc_tag_14a_uid_size)data[offset]; + offset++; + memcpy(info->uid, &data[offset], *(info->size)); + offset += *(info->size); + memcpy(info->atqa, &data[offset], 2); + offset += 2; + info->sak[0] = data[offset]; + offset++; + info->ats->length = data[offset]; + offset++; memcpy(info->ats->data, &data[offset], info->ats->length); return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL); } @@ -2319,11 +2324,14 @@ static data_frame_tx_t *cmd_processor_hf14a_scan_keep(uint16_t cmd, uint16_t sta uint8_t payload[1 + sizeof(taginfo.uid) + sizeof(taginfo.atqa) + sizeof(taginfo.sak) + 1 + 254]; uint16_t offset = 0; payload[offset++] = taginfo.uid_len; - memcpy(&payload[offset], taginfo.uid, taginfo.uid_len); offset += taginfo.uid_len; - memcpy(&payload[offset], taginfo.atqa, sizeof(taginfo.atqa)); offset += sizeof(taginfo.atqa); + memcpy(&payload[offset], taginfo.uid, taginfo.uid_len); + offset += taginfo.uid_len; + memcpy(&payload[offset], taginfo.atqa, sizeof(taginfo.atqa)); + offset += sizeof(taginfo.atqa); payload[offset++] = taginfo.sak; payload[offset++] = taginfo.ats_len; - memcpy(&payload[offset], taginfo.ats, taginfo.ats_len); offset += taginfo.ats_len; + memcpy(&payload[offset], taginfo.ats, taginfo.ats_len); + offset += taginfo.ats_len; return data_frame_make(cmd, STATUS_HF_TAG_OK, offset, payload); } @@ -2367,7 +2375,7 @@ static data_frame_tx_t *cmd_processor_hf14a_4_reader_apdu(uint16_t cmd, uint16_t return data_frame_make(cmd, STATUS_HF_TAG_NO, 2, dbg); } NRF_LOG_INFO("14A4_READER_APDU: scan_auto OK sak=%02x ats_len=%d", - taginfo.sak, taginfo.ats_len); + taginfo.sak, taginfo.ats_len); /* Step 3: wrap APDU in I-block (PCB=0x02) and send */ uint8_t frame_buf[64]; @@ -2381,14 +2389,15 @@ static data_frame_tx_t *cmd_processor_hf14a_4_reader_apdu(uint16_t cmd, uint16_t pcd_14a_reader_timeout_set(600); resp_bits = 0; status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, - frame_buf, frame_len, resp_buf, &resp_bits, U8ARR_BIT_LEN(resp_buf)); + frame_buf, frame_len, resp_buf, &resp_bits, U8ARR_BIT_LEN(resp_buf)); pcd_14a_reader_timeout_set(DEF_COM_TIMEOUT); NRF_LOG_INFO("14A4_READER_APDU: APDU transfer status=%d resp_bits=%d", status, resp_bits); if (status != STATUS_HF_TAG_OK || resp_bits < 8) { uint8_t dbg[6] = {0x03, status, (uint8_t)frame_len, - frame_buf[0], frame_buf[1], frame_buf[2]}; + frame_buf[0], frame_buf[1], frame_buf[2] + }; return data_frame_make(cmd, STATUS_HF_TAG_NO, 6, dbg); } @@ -2401,7 +2410,7 @@ static data_frame_tx_t *cmd_processor_hf14a_4_reader_apdu(uint16_t cmd, uint16_t /* Verify first block CRC and begin chaining reassembly */ uint8_t crc_calc[2]; crc_14a_calculate(resp_buf, resp_bytes - 2, crc_calc); - if (resp_buf[resp_bytes-2] != crc_calc[0] || resp_buf[resp_bytes-1] != crc_calc[1]) { + if (resp_buf[resp_bytes - 2] != crc_calc[0] || resp_buf[resp_bytes - 1] != crc_calc[1]) { return data_frame_make(cmd, STATUS_HF_ERR_CRC, resp_bytes, resp_buf); } @@ -2424,12 +2433,12 @@ static data_frame_tx_t *cmd_processor_hf14a_4_reader_apdu(uint16_t cmd, uint16_t resp_bits = 0; pcd_14a_reader_timeout_set(600); status = pcd_14a_reader_bytes_transfer(PCD_TRANSCEIVE, - rack_frame, 3, resp_buf, &resp_bits, U8ARR_BIT_LEN(resp_buf)); + rack_frame, 3, resp_buf, &resp_bits, U8ARR_BIT_LEN(resp_buf)); pcd_14a_reader_timeout_set(DEF_COM_TIMEOUT); if (status != STATUS_HF_TAG_OK || resp_bits < 24) break; resp_bytes = resp_bits / 8; crc_14a_calculate(resp_buf, resp_bytes - 2, crc_calc); - if (resp_buf[resp_bytes-2] != crc_calc[0] || resp_buf[resp_bytes-1] != crc_calc[1]) break; + if (resp_buf[resp_bytes - 2] != crc_calc[0] || resp_buf[resp_bytes - 1] != crc_calc[1]) break; resp_pcb = resp_buf[0]; dlen = resp_bytes - 3; if (dlen > 0 && resp_chain_len + dlen < sizeof(resp_chain)) { @@ -2447,11 +2456,10 @@ static data_frame_tx_t *cmd_processor_hf14a_4_reader_apdu(uint16_t cmd, uint16_t * Sends one I-block, receives full response handling card-side chaining. * ----------------------------------------------------------------------- */ static bool tcl_apdu_( - const uint8_t *apdu, uint8_t apdu_sz, - uint8_t **rdata_ptr, uint16_t *rlen_ptr, - uint8_t *abuf, uint8_t *rbuf, uint8_t *chain_buf, - uint16_t *rbits_p, uint8_t *blk_p) -{ + const uint8_t *apdu, uint8_t apdu_sz, + uint8_t **rdata_ptr, uint16_t *rlen_ptr, + uint8_t *abuf, uint8_t *rbuf, uint8_t *chain_buf, + uint16_t *rbits_p, uint8_t *blk_p) { /* Build I-block: PCB + APDU + CRC */ abuf[0] = 0x02 | (*blk_p & 0x01); memcpy(&abuf[1], apdu, apdu_sz); @@ -2466,13 +2474,13 @@ static bool tcl_apdu_( pcd_14a_reader_timeout_set(600); uint16_t rbits = 0; uint8_t st = pcd_14a_reader_bytes_transfer( - PCD_TRANSCEIVE, abuf, frame_len, rbuf, &rbits, 270u * 8u); + PCD_TRANSCEIVE, abuf, frame_len, rbuf, &rbits, 270u * 8u); if (st != STATUS_HF_TAG_OK || rbits < 24u) return false; uint16_t rb = rbits / 8u; uint8_t crc[2]; crc_14a_calculate(rbuf, rb - 2u, crc); - if (rbuf[rb-2] != crc[0] || rbuf[rb-1] != crc[1]) return false; + if (rbuf[rb - 2] != crc[0] || rbuf[rb - 1] != crc[1]) return false; *blk_p ^= 1; uint8_t resp_pcb = rbuf[0]; @@ -2502,11 +2510,11 @@ static bool tcl_apdu_( pcd_14a_reader_timeout_set(600); chain_rbits = 0; chain_st = pcd_14a_reader_bytes_transfer( - PCD_TRANSCEIVE, wtx_r, 4, rbuf, &chain_rbits, 270u * 8u); + PCD_TRANSCEIVE, wtx_r, 4, rbuf, &chain_rbits, 270u * 8u); if (chain_st != STATUS_HF_TAG_OK || chain_rbits < 24u) break; rb = chain_rbits / 8u; crc_14a_calculate(rbuf, rb - 2u, crc); - if (rbuf[rb-2] != crc[0] || rbuf[rb-1] != crc[1]) break; + if (rbuf[rb - 2] != crc[0] || rbuf[rb - 1] != crc[1]) break; resp_pcb = rbuf[0]; dlen = (uint8_t)(rb - 3u); if (dlen > 0u && chain_len + dlen < 512u) { @@ -2528,12 +2536,12 @@ static bool tcl_apdu_( pcd_14a_reader_timeout_set(600); chain_rbits = 0; chain_st = pcd_14a_reader_bytes_transfer( - PCD_TRANSCEIVE, rf, 3, rbuf, &chain_rbits, 270u * 8u); + PCD_TRANSCEIVE, rf, 3, rbuf, &chain_rbits, 270u * 8u); if (chain_st != STATUS_HF_TAG_OK || chain_rbits < 24u) break; rb = chain_rbits / 8u; /* bytes_transfer returns BIT count */ crc_14a_calculate(rbuf, rb - 2u, crc); - if (rbuf[rb-2] != crc[0] || rbuf[rb-1] != crc[1]) break; + if (rbuf[rb - 2] != crc[0] || rbuf[rb - 1] != crc[1]) break; resp_pcb = rbuf[0]; dlen = (uint8_t)(rb - 3u); @@ -2576,12 +2584,12 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st uint8_t blk = 0; /* alternating block number */ /* SEND_APDU: thin wrapper that calls the static tcl_apdu_ helper. */ - #define SEND_APDU(ap, asz, rd, rl) tcl_apdu_((ap),(asz),(rd),(rl),abuf,rbuf,chain_buf,&rbits,&blk) +#define SEND_APDU(ap, asz, rd, rl) tcl_apdu_((ap),(asz),(rd),(rl),abuf,rbuf,chain_buf,&rbits,&blk) /* Append a cmd+resp pair to out buffer */ - #define APPEND_PAIR(cmd_ptr, cmd_sz, resp_ptr, resp_sz) do { if (out_len + 1 + (cmd_sz) + 2 + (resp_sz) < NETDATA_MAX_DATA_LENGTH) { out[out_len++] = (uint8_t)(cmd_sz); memcpy(&out[out_len], (cmd_ptr), (cmd_sz)); out_len += (cmd_sz); out[out_len++] = (uint8_t)((resp_sz) & 0xFF); out[out_len++] = (uint8_t)((resp_sz) >> 8); memcpy(&out[out_len], (resp_ptr), (resp_sz)); out_len += (resp_sz); } } while(0) +#define APPEND_PAIR(cmd_ptr, cmd_sz, resp_ptr, resp_sz) do { if (out_len + 1 + (cmd_sz) + 2 + (resp_sz) < NETDATA_MAX_DATA_LENGTH) { out[out_len++] = (uint8_t)(cmd_sz); memcpy(&out[out_len], (cmd_ptr), (cmd_sz)); out_len += (cmd_sz); out[out_len++] = (uint8_t)((resp_sz) & 0xFF); out[out_len++] = (uint8_t)((resp_sz) >> 8); memcpy(&out[out_len], (resp_ptr), (resp_sz)); out_len += (resp_sz); } } while(0) /* ---- Step 1: scan_auto ----------------------------------------- */ bsp_delay_ms(10); @@ -2626,11 +2634,14 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st /* ---- Pack tag info ------------------------------------------- */ out[out_len++] = tag.uid_len; - memcpy(&out[out_len], tag.uid, tag.uid_len); out_len += tag.uid_len; - memcpy(&out[out_len], tag.atqa, 2); out_len += 2; + memcpy(&out[out_len], tag.uid, tag.uid_len); + out_len += tag.uid_len; + memcpy(&out[out_len], tag.atqa, 2); + out_len += 2; out[out_len++] = tag.sak; out[out_len++] = tag.ats_len; - memcpy(&out[out_len], tag.ats, tag.ats_len); out_len += tag.ats_len; + memcpy(&out[out_len], tag.ats, tag.ats_len); + out_len += tag.ats_len; /* Placeholder for num_apdus — fill in at end */ uint16_t num_apdus_offset = out_len; @@ -2645,7 +2656,8 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st 0x32, 0x50, 0x41, 0x59, 0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46, 0x30, 0x31, 0x00 }; - uint8_t *ppse_resp = NULL; uint16_t ppse_rlen = 0; + uint8_t *ppse_resp = NULL; + uint16_t ppse_rlen = 0; { bool _ppse_ok = SEND_APDU(ppse_cmd, sizeof(ppse_cmd), &ppse_resp, &ppse_rlen); if (!_ppse_ok) { @@ -2673,11 +2685,12 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st blk = 0; /* new T=CL session: block number restarts at 0 */ /* ---- Extract first AID from PPSE ----------------------------- */ - uint8_t aid[16]; uint8_t aid_len = 0; + uint8_t aid[16]; + uint8_t aid_len = 0; for (uint8_t i = 0; i + 1 < ppse_rlen; i++) { - if (ppse_resp[i] == 0x4F && ppse_resp[i+1] > 0 && ppse_resp[i+1] <= 16) { - aid_len = ppse_resp[i+1]; - memcpy(aid, &ppse_resp[i+2], aid_len); + if (ppse_resp[i] == 0x4F && ppse_resp[i + 1] > 0 && ppse_resp[i + 1] <= 16) { + aid_len = ppse_resp[i + 1]; + memcpy(aid, &ppse_resp[i + 2], aid_len); break; } } @@ -2686,13 +2699,17 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st /* ---- Step 3: SELECT AID -------------------------------------- */ uint8_t sel_cmd[32]; uint8_t sel_len = 0; - sel_cmd[sel_len++] = 0x00; sel_cmd[sel_len++] = 0xA4; - sel_cmd[sel_len++] = 0x04; sel_cmd[sel_len++] = 0x00; + sel_cmd[sel_len++] = 0x00; + sel_cmd[sel_len++] = 0xA4; + sel_cmd[sel_len++] = 0x04; + sel_cmd[sel_len++] = 0x00; sel_cmd[sel_len++] = aid_len; - memcpy(&sel_cmd[sel_len], aid, aid_len); sel_len += aid_len; + memcpy(&sel_cmd[sel_len], aid, aid_len); + sel_len += aid_len; sel_cmd[sel_len++] = 0x00; - uint8_t *sel_resp; uint16_t sel_rlen; + uint8_t *sel_resp; + uint16_t sel_rlen; if (!SEND_APDU(sel_cmd, sel_len, &sel_resp, &sel_rlen)) goto done; APPEND_PAIR(sel_cmd, sel_len, sel_resp, sel_rlen); num_apdus++; @@ -2704,8 +2721,8 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st for (uint8_t pi = 0; pi + 2 < sel_rlen; pi++) { /* 2-byte tag detection: first byte has bits[4:0] == 0x1F */ uint8_t ptag1 = sel_resp[pi]; - uint8_t ptag2 = (((ptag1 & 0x1F) == 0x1F) && pi+1 < sel_rlen) ? sel_resp[pi+1] : 0; - uint16_t ftag = ((ptag1 & 0x1F) == 0x1F) ? (((uint16_t)ptag1<<8)|ptag2) : ptag1; + uint8_t ptag2 = (((ptag1 & 0x1F) == 0x1F) && pi + 1 < sel_rlen) ? sel_resp[pi + 1] : 0; + uint16_t ftag = ((ptag1 & 0x1F) == 0x1F) ? (((uint16_t)ptag1 << 8) | ptag2) : ptag1; uint8_t flen_off = (((ptag1 & 0x1F) == 0x1F)) ? 2 : 1; if (pi + flen_off >= sel_rlen) break; uint8_t flen = sel_resp[pi + flen_off]; @@ -2721,7 +2738,8 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st } break; } - if (flen_off + flen < 255) pi += flen_off + flen - 1; else break; + if (flen_off + flen < 255) pi += flen_off + flen - 1; + else break; } /* ---- Step 5: GPO ----------------------------------------------- * Build GPO from parsed PDOL. pdol_len from FCI may be 0 if truncated. @@ -2746,9 +2764,10 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st 0x00, 0x00, 0x00 }; uint8_t gpo_len = 0; - uint8_t *gpo_resp = NULL; uint16_t gpo_rlen = 0; + uint8_t *gpo_resp = NULL; + uint16_t gpo_rlen = 0; if (pdol_len > 44) pdol_len = 0; - #define BUILD_GPO(pl) do { \ +#define BUILD_GPO(pl) do { \ gpo_len = 0; \ gpo_buf[gpo_len++]=0x80; gpo_buf[gpo_len++]=0xA8; \ gpo_buf[gpo_len++]=0x00; gpo_buf[gpo_len++]=0x00; \ @@ -2762,58 +2781,62 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st gpo_len += (pl); \ gpo_buf[gpo_len++]=0x00; \ } while(0) - #define GPO_OK(rp,rl) ((rl)>=2 && \ +#define GPO_OK(rp,rl) ((rl)>=2 && \ ((rp)[0]==0x77||(rp)[0]==0x80|| \ ((rp)[(rl)-2]==0x90&&(rp)[(rl)-1]==0x00))) /* Attempt 1: use PDOL length from FCI (may be 0 if truncated) */ BUILD_GPO(pdol_len); if (!SEND_APDU(gpo_buf, gpo_len, &gpo_resp, &gpo_rlen) || - !GPO_OK(gpo_resp, gpo_rlen)) { + !GPO_OK(gpo_resp, gpo_rlen)) { /* Attempt 2: try 4 bytes (TTQ only — some Visa/MC accept this) */ if (pdol_len != 4) { BUILD_GPO(4); if (SEND_APDU(gpo_buf, gpo_len, &gpo_resp, &gpo_rlen) && - GPO_OK(gpo_resp, gpo_rlen)) goto gpo_done; + GPO_OK(gpo_resp, gpo_rlen)) goto gpo_done; } /* Attempt 3: try 29 bytes (common Mastercard/Visa PDOL size) */ if (pdol_len != 29) { BUILD_GPO(29); if (SEND_APDU(gpo_buf, gpo_len, &gpo_resp, &gpo_rlen) && - GPO_OK(gpo_resp, gpo_rlen)) goto gpo_done; + GPO_OK(gpo_resp, gpo_rlen)) goto gpo_done; } /* Attempt 4: try 33 bytes (MC with Amount+Country+Currency fields) */ if (pdol_len != 33) { BUILD_GPO(33); if (SEND_APDU(gpo_buf, gpo_len, &gpo_resp, &gpo_rlen) && - GPO_OK(gpo_resp, gpo_rlen)) goto gpo_done; + GPO_OK(gpo_resp, gpo_rlen)) goto gpo_done; } /* Attempts 5-7: additional MC sizes (+TermType, +DataAuth, +IssuerAppData) */ - { static const uint8_t extra_pl[] = {34, 36, 38}; - for (uint8_t ei = 0; ei < sizeof(extra_pl); ei++) { - uint8_t pl = extra_pl[ei]; - if (pl == pdol_len || pl == 4 || pl == 29 || pl == 33) continue; - BUILD_GPO(pl); - if (SEND_APDU(gpo_buf, gpo_len, &gpo_resp, &gpo_rlen) && - GPO_OK(gpo_resp, gpo_rlen)) goto gpo_done; - } + { + static const uint8_t extra_pl[] = {34, 36, 38}; + for (uint8_t ei = 0; ei < sizeof(extra_pl); ei++) { + uint8_t pl = extra_pl[ei]; + if (pl == pdol_len || pl == 4 || pl == 29 || pl == 33) continue; + BUILD_GPO(pl); + if (SEND_APDU(gpo_buf, gpo_len, &gpo_resp, &gpo_rlen) && + GPO_OK(gpo_resp, gpo_rlen)) goto gpo_done; + } } goto done; /* all attempts failed */ } - gpo_done: - #undef BUILD_GPO - #undef GPO_OK +gpo_done: +#undef BUILD_GPO +#undef GPO_OK APPEND_PAIR(gpo_buf, gpo_len, gpo_resp, gpo_rlen); num_apdus++; - uint8_t *afl = NULL; uint8_t afl_len = 0; + uint8_t *afl = NULL; + uint8_t afl_len = 0; if (gpo_rlen > 0 && gpo_resp[0] == 0x77) { /* Format 2: find tag 94 */ - for (uint8_t i = 2; i + 1 < gpo_rlen; ) { - uint8_t t = gpo_resp[i]; uint8_t l = gpo_resp[i+1]; - if (t == 0x94) { afl = &gpo_resp[i+2]; afl_len = l; break; } + for (uint8_t i = 2; i + 1 < gpo_rlen;) { + uint8_t t = gpo_resp[i]; + uint8_t l = gpo_resp[i + 1]; + if (t == 0x94) { afl = &gpo_resp[i + 2]; afl_len = l; break; } i += 2 + l; } } else if (gpo_rlen > 3 && gpo_resp[0] == 0x80) { - afl = &gpo_resp[3]; afl_len = gpo_rlen - 3 - 2; + afl = &gpo_resp[3]; + afl_len = gpo_rlen - 3 - 2; } if (afl == NULL || afl_len == 0) goto done; @@ -2829,12 +2852,13 @@ static data_frame_tx_t *cmd_processor_hf14a_4_emv_scan(uint16_t cmd, uint16_t st /* READ each record */ for (uint8_t a = 0; a + 3 < afl_len; a += 4) { uint8_t sfi = (afl[a] >> 3) & 0x1F; - uint8_t rec_s = afl[a+1]; - uint8_t rec_e = afl[a+2]; + uint8_t rec_s = afl[a + 1]; + uint8_t rec_e = afl[a + 2]; if (sfi == 0 || rec_s > rec_e) continue; for (uint8_t r = rec_s; r <= rec_e; r++) { uint8_t rr_cmd[5] = {0x00, 0xB2, r, (uint8_t)((sfi << 3) | 4), 0x00}; - uint8_t *rr_resp; uint16_t rr_rlen; + uint8_t *rr_resp; + uint16_t rr_rlen; if (!SEND_APDU(rr_cmd, 5, &rr_resp, &rr_rlen)) { /* RC522 FIFO is 64 bytes — records > 61 bytes fail. * Skip silently rather than aborting the whole scan. */ @@ -2923,7 +2947,7 @@ static cmd_data_map_t m_data_cmd_map[] = { { DATA_CMD_EM410X_SCAN, before_reader_run, cmd_processor_em410x_scan, NULL }, { DATA_CMD_EM410X_WRITE_TO_T55XX, before_reader_run, cmd_processor_em410x_write_to_t55xx, NULL }, - { DATA_CMD_EM410X_ELECTRA_WRITE_TO_T55XX,before_reader_run, cmd_processor_em410x_electra_write_to_t55xx, NULL }, + { DATA_CMD_EM410X_ELECTRA_WRITE_TO_T55XX, before_reader_run, cmd_processor_em410x_electra_write_to_t55xx, NULL }, { DATA_CMD_HIDPROX_SCAN, before_reader_run, cmd_processor_hidprox_scan, NULL }, { DATA_CMD_HIDPROX_WRITE_TO_T55XX, before_reader_run, cmd_processor_hidprox_write_to_t55xx, NULL }, { DATA_CMD_VIKING_SCAN, before_reader_run, cmd_processor_viking_scan, NULL }, @@ -2998,14 +3022,14 @@ static cmd_data_map_t m_data_cmd_map[] = { { DATA_CMD_HIDPROX_SET_EMU_ID, NULL, cmd_processor_hidprox_set_emu_id, NULL }, { DATA_CMD_HIDPROX_GET_EMU_ID, NULL, cmd_processor_hidprox_get_emu_id, NULL }, { DATA_CMD_IOPROX_SET_EMU_ID, NULL, cmd_processor_ioprox_set_emu_id, NULL }, - { DATA_CMD_IOPROX_GET_EMU_ID, NULL, cmd_processor_ioprox_get_emu_id, NULL }, + { DATA_CMD_IOPROX_GET_EMU_ID, NULL, cmd_processor_ioprox_get_emu_id, NULL }, { DATA_CMD_VIKING_SET_EMU_ID, NULL, cmd_processor_viking_set_emu_id, NULL }, { DATA_CMD_VIKING_GET_EMU_ID, NULL, cmd_processor_viking_get_emu_id, NULL }, { DATA_CMD_PAC_SET_EMU_ID, NULL, cmd_processor_pac_set_emu_id, NULL }, { DATA_CMD_PAC_GET_EMU_ID, NULL, cmd_processor_pac_get_emu_id, NULL }, /* ISO14443-4 T=CL emulation */ #if defined(PROJECT_CHAMELEON_ULTRA) -/* ISO14443-4 T=CL emulation */ + /* ISO14443-4 T=CL emulation */ { DATA_CMD_HF14A_4_APDU_RECV, NULL, cmd_processor_hf14a_4_apdu_recv, NULL }, { DATA_CMD_HF14A_4_APDU_SEND, NULL, cmd_processor_hf14a_4_apdu_send, NULL }, { DATA_CMD_HF14A_4_SET_ANTI_COLL, NULL, cmd_processor_hf14a_4_set_anti_coll, NULL }, diff --git a/firmware/application/src/app_main.c b/firmware/application/src/app_main.c index f79dbade..5c09b426 100644 --- a/firmware/application/src/app_main.c +++ b/firmware/application/src/app_main.c @@ -62,7 +62,7 @@ static bool m_is_a_btn_release = false; static bool m_system_off_processing = false; // NFC field generator state -volatile bool m_is_field_on = false; +volatile bool m_is_field_on = false; // cpu reset reason static uint32_t m_reset_source; @@ -156,27 +156,27 @@ static void gpio_te_init(void) { static void field_generator_rainbow_loop(void) { static uint8_t color_index = 0; static uint32_t last_update = 0; - + if (!m_is_field_on) return; - + uint32_t now = app_timer_cnt_get(); - + if (app_timer_cnt_diff_compute(now, last_update) < APP_TIMER_TICKS(100)) { return; } last_update = now; - + // Rainbow colors const uint8_t colors[] = {RGB_RED, RGB_YELLOW, RGB_GREEN, RGB_CYAN, RGB_BLUE, RGB_MAGENTA}; - + set_slot_light_color(colors[color_index]); uint32_t *led_pins = hw_get_led_array(); - + // Light up all LEDs with current color for (int i = 0; i < RGB_LIST_NUM; i++) { nrf_gpio_pin_set(led_pins[i]); } - + color_index = (color_index + 1) % 6; } #endif @@ -204,9 +204,9 @@ static void timer_button_event_handle(void *arg) { NRF_LOG_INFO("BUTTON press during shutdown"); return; } - + nrf_drv_gpiote_pin_t pin = *(nrf_drv_gpiote_pin_t *)arg; - + // Check here if the current GPIO is at the pressed level if (nrf_gpio_pin_read(pin) == 1) { if (pin == BUTTON_1) { @@ -673,11 +673,11 @@ static void btn_fn_copy_lf(uint8_t slot, tag_specific_type_t type) { size = LF_HIDPROX_TAG_ID_SIZE; data = id_buffer; break; - case TAG_TYPE_IOPROX: - status = scan_ioprox(id_buffer, 0); - size = LF_IOPROX_TAG_ID_SIZE; - data = id_buffer; - break; + case TAG_TYPE_IOPROX: + status = scan_ioprox(id_buffer, 0); + size = LF_IOPROX_TAG_ID_SIZE; + data = id_buffer; + break; case TAG_TYPE_EM410X: case TAG_TYPE_EM410X_ELECTRA: { status = scan_em410x(id_buffer); @@ -854,16 +854,16 @@ static void run_button_function_by_settings(settings_button_function_t sbf) { nrf_gpio_pin_set(READER_POWER); // reader power enable nrf_gpio_cfg_output(HF_ANT_SEL); nrf_gpio_pin_clear(HF_ANT_SEL); // hf ant switch to reader mode - + pcd_14a_reader_init(); bsp_delay_ms(10); } - + pcd_14a_reader_reset(); pcd_14a_reader_antenna_on(); m_is_field_on = true; NRF_LOG_INFO("NFC field ON"); - + // Set initial rainbow state set_slot_light_color(RGB_RED); uint32_t *led_pins = hw_get_led_array(); @@ -879,7 +879,7 @@ static void run_button_function_by_settings(settings_button_function_t sbf) { pcd_14a_reader_antenna_off(); m_is_field_on = false; NRF_LOG_INFO("NFC field OFF"); - + // If we're not in reader mode, clean up the hardware device_mode_t current_mode = get_device_mode(); if (current_mode != DEVICE_MODE_READER) { @@ -887,7 +887,7 @@ static void run_button_function_by_settings(settings_button_function_t sbf) { nrf_gpio_pin_clear(READER_POWER); // reader power disable nrf_gpio_pin_set(HF_ANT_SEL); // hf ant switch back to tag mode } - + // Restore normal LED light_up_by_slot(); @@ -1035,17 +1035,17 @@ int main(void) { lesc_event_process(); // Button event process button_press_process(); - + #if defined(PROJECT_CHAMELEON_ULTRA) // Field generator rainbow animation field_generator_rainbow_loop(); #endif - + // Led blink at usb status (only if field generator is off) if (!m_is_field_on) { blink_usb_led_status(); } - + // Data pack process data_frame_process(); // Log print process diff --git a/firmware/application/src/ble_main.c b/firmware/application/src/ble_main.c index cdd444fa..b8ac05ce 100644 --- a/firmware/application/src/ble_main.c +++ b/firmware/application/src/ble_main.c @@ -736,11 +736,11 @@ static void battery_level_meas_timeout_handler(void *p_context) { // if battery service is notification enable, we can send msg to device. err_code = ble_bas_battery_level_update(&m_bas, percentage_batt_lvl, BLE_CONN_HANDLE_ALL); if ((err_code != NRF_SUCCESS) && - (err_code != NRF_ERROR_INVALID_STATE) && - (err_code != NRF_ERROR_RESOURCES) && - (err_code != NRF_ERROR_BUSY) && - (err_code != NRF_ERROR_FORBIDDEN) && - (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) { + (err_code != NRF_ERROR_INVALID_STATE) && + (err_code != NRF_ERROR_RESOURCES) && + (err_code != NRF_ERROR_BUSY) && + (err_code != NRF_ERROR_FORBIDDEN) && + (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)) { APP_ERROR_HANDLER(err_code); } diff --git a/firmware/application/src/rfid/byte_mirror.c b/firmware/application/src/rfid/byte_mirror.c index aa750cd9..c2f8cf4e 100644 --- a/firmware/application/src/rfid/byte_mirror.c +++ b/firmware/application/src/rfid/byte_mirror.c @@ -34,4 +34,4 @@ const uint8_t byte_mirror[256] = { 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, -}; \ No newline at end of file +}; diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_14a.c b/firmware/application/src/rfid/nfctag/hf/nfc_14a.c index c7b9ca69..42023e35 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_14a.c +++ b/firmware/application/src/rfid/nfctag/hf/nfc_14a.c @@ -611,11 +611,11 @@ static inline void nrf_nfct_reset(void) { nrf_nfct_int_enable(int_enabled); // Disable interrupts associated with data exchange. - nrf_nfct_int_disable(NRF_NFCT_INT_RXFRAMESTART_MASK | - NRF_NFCT_INT_RXFRAMEEND_MASK | - NRF_NFCT_INT_RXERROR_MASK | - NRF_NFCT_INT_TXFRAMESTART_MASK | - NRF_NFCT_INT_TXFRAMEEND_MASK); + nrf_nfct_int_disable(NRF_NFCT_INT_RXFRAMESTART_MASK | + NRF_NFCT_INT_RXFRAMEEND_MASK | + NRF_NFCT_INT_RXERROR_MASK | + NRF_NFCT_INT_TXFRAMESTART_MASK | + NRF_NFCT_INT_TXFRAMEEND_MASK); } static inline void nfc_fdt_reset(void) { @@ -668,7 +668,7 @@ void nfc_tag_14a_event_callback(nrfx_nfct_evt_t const *p_event) { if (reset_if_field_lost) { // Fix a bug where certain special conditions prevent triggering TX start events and actually transmit incorrect data to the card reader. - // After more more more testing, I found that simply going into sleep mode and restarting can restore work. + // After more more more testing, I found that simply going into sleep mode and restarting can restore work. // Therefore, I suspect that there may be some issues with the NFC peripheral that require a reset to resolve. nrf_nfct_reset(); } @@ -681,12 +681,12 @@ void nfc_tag_14a_event_callback(nrfx_nfct_evt_t const *p_event) { if (m_tx_sniff_cb != NULL) { uint32_t amt = NRF_NFCT->TXD.AMOUNT; uint16_t tx_bytes = (amt >> NFCT_TXD_AMOUNT_TXDATABYTES_Pos) - & (NFCT_TXD_AMOUNT_TXDATABYTES_Msk >> NFCT_TXD_AMOUNT_TXDATABYTES_Pos); + & (NFCT_TXD_AMOUNT_TXDATABYTES_Msk >> NFCT_TXD_AMOUNT_TXDATABYTES_Pos); uint16_t tx_bits_rem = (amt >> NFCT_TXD_AMOUNT_TXDATABITS_Pos) - & (NFCT_TXD_AMOUNT_TXDATABITS_Msk >> NFCT_TXD_AMOUNT_TXDATABITS_Pos); + & (NFCT_TXD_AMOUNT_TXDATABITS_Msk >> NFCT_TXD_AMOUNT_TXDATABITS_Pos); uint16_t tx_bits = (tx_bits_rem > 0) - ? ((tx_bytes - 1) * 8 + tx_bits_rem) - : (tx_bytes * 8); + ? ((tx_bytes - 1) * 8 + tx_bits_rem) + : (tx_bytes * 8); if (tx_bits > 0 && tx_bytes <= MAX_NFC_TX_BUFFER_SIZE) { m_tx_sniff_cb(m_nfc_tx_buffer, tx_bits); } diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_14a_4.c b/firmware/application/src/rfid/nfctag/hf/nfc_14a_4.c index 8d23c6d3..f15d9f80 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_14a_4.c +++ b/firmware/application/src/rfid/nfctag/hf/nfc_14a_4.c @@ -94,7 +94,7 @@ static uint8_t m_large_resp_count = 0; /* ------------------------------------------------------------------ */ void nfc_tag_14a_4_add_static_response(const uint8_t *cmd, uint8_t cmd_len, - const uint8_t *resp, uint16_t resp_len) { + const uint8_t *resp, uint16_t resp_len) { if (cmd_len > NFC_14A_4_MAX_STATIC_CMD_LEN) cmd_len = NFC_14A_4_MAX_STATIC_CMD_LEN; if (resp_len > NFC_14A_4_MAX_STATIC_RESP_LEN) { @@ -132,7 +132,7 @@ void nfc_tag_14a_4_clear_static_responses(void) { } static bool find_static_response(const uint8_t *apdu, uint16_t apdu_len, - uint8_t **resp_out, uint16_t *resp_len_out) { + uint8_t **resp_out, uint16_t *resp_len_out) { /* Flash-backed table */ for (uint8_t i = 0; i < m_static_resp_count; i++) { nfc_tag_14a_4_static_response_t *e = &m_static_resp[i]; @@ -259,7 +259,7 @@ static void nfc_tag_14a_4_state_handler(uint8_t *data, uint16_t szBytes) { m_dbg_iblocks_rx++; m_dbg_last_rx_pcb = pcb; NRF_LOG_INFO("14A4 I-block #%d: reader_blk=%d m_block_num=%d apdu_len=%d", - m_dbg_iblocks_rx, reader_blknum, m_block_num, apdu_len); + m_dbg_iblocks_rx, reader_blknum, m_block_num, apdu_len); /* Block number check per ISO14443-4 §7.5.3.3: * If block number matches expected, process new APDU. @@ -292,10 +292,10 @@ static void nfc_tag_14a_4_state_handler(uint8_t *data, uint16_t szBytes) { uint8_t *static_resp = NULL; uint16_t static_len = 0; bool _found = find_static_response(m_apdu_buf, apdu_len, - &static_resp, &static_len); + &static_resp, &static_len); m_dbg_last_match = _found ? 1 : 0; NRF_LOG_INFO("14A4 find_static: found=%d static_len=%d resp_count=%d", - _found, static_len, m_static_resp_count); + _found, static_len, m_static_resp_count); if (_found) { m_dbg_iblocks_tx++; memcpy(m_resp_buf, static_resp, static_len); @@ -350,7 +350,7 @@ void nfc_tag_14a_4_reset_handler(void) { } void nfc_tag_14a_4_get_debug_counters(uint8_t *rx, uint8_t *tx, - uint8_t *last_pcb, uint8_t *last_match) { + uint8_t *last_pcb, uint8_t *last_match) { *rx = m_dbg_iblocks_rx; *tx = m_dbg_iblocks_tx; *last_pcb = m_dbg_last_rx_pcb; @@ -379,7 +379,7 @@ int nfc_tag_14a_4_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffe int info_size = sizeof(nfc_tag_14a_4_information_t); if (buffer->length < info_size) { NRF_LOG_ERROR("14A-4 loadcb: buffer too small (%d < %d)", - buffer->length, info_size); + buffer->length, info_size); return info_size; } m_tag_information = (nfc_tag_14a_4_information_t *)buffer->buffer; @@ -398,9 +398,9 @@ int nfc_tag_14a_4_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffe }; nfc_tag_14a_set_handler(&handler); NRF_LOG_INFO("14A-4 loadcb OK: SAK=%02x uid_sz=%d static_resp=%d", - m_tag_information->res_coll.sak[0], - m_tag_information->res_coll.size, - m_static_resp_count); + m_tag_information->res_coll.sak[0], + m_tag_information->res_coll.size, + m_static_resp_count); return info_size; } diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_14a_4.h b/firmware/application/src/rfid/nfctag/hf/nfc_14a_4.h index 3c4a5efc..49b68fe5 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_14a_4.h +++ b/firmware/application/src/rfid/nfctag/hf/nfc_14a_4.h @@ -34,7 +34,8 @@ typedef struct __attribute__((packed)) { uint8_t cmd[NFC_14A_4_MAX_STATIC_CMD_LEN]; uint8_t resp_len; uint8_t resp[NFC_14A_4_MAX_STATIC_RESP_LEN]; -} nfc_tag_14a_4_static_response_t; +} +nfc_tag_14a_4_static_response_t; /** * Per-slot persistent data layout stored in FDS flash. @@ -44,7 +45,8 @@ typedef struct __attribute__((packed)) { nfc_tag_14a_coll_res_entity_t res_coll; uint8_t static_resp_count; nfc_tag_14a_4_static_response_t static_resp[NFC_14A_4_MAX_STATIC_RESPONSES]; -} nfc_tag_14a_4_information_t; +} +nfc_tag_14a_4_information_t; /* Anti-collision resource — used by get_coll_res_data in app_cmd.c */ nfc_tag_14a_coll_res_reference_t *nfc_tag_14a_4_get_coll_res(void); @@ -56,7 +58,7 @@ bool nfc_tag_14a_4_data_factory(uint8_t slot, tag_specific_type_t tag_type); /* Static response table management (called before hw mode -e) */ void nfc_tag_14a_4_add_static_response(const uint8_t *cmd, uint8_t cmd_len, - const uint8_t *resp, uint16_t resp_len); + const uint8_t *resp, uint16_t resp_len); void nfc_tag_14a_4_clear_static_responses(void); /* APDU relay — host-driven responses */ diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_mf0_ntag.c b/firmware/application/src/rfid/nfctag/hf/nfc_mf0_ntag.c index e85f05b1..5cb3d525 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_mf0_ntag.c +++ b/firmware/application/src/rfid/nfctag/hf/nfc_mf0_ntag.c @@ -696,7 +696,7 @@ static bool check_ro_lock_on_page(int block_num) { //the BL bit only freezes the lock bytes ! return (m_tag_information->memory[2][2] & 8) != 0; default: - return (m_tag_information->memory[2][2] & 9) != 0; + return (m_tag_information->memory[2][2] & 9) != 0; } // bits 0 and 3 } else if (block_num <= MF0ICU1_PAGES) { @@ -805,26 +805,25 @@ static bool check_ro_lock_on_page(int block_num) { // the lock configuration. We only check the actual lock bits (L0-L15) in bytes 0-1. return locked_small_range; default: - return locked_small_range | locked_large_range; + return locked_small_range | locked_large_range; } } else { //Check the block locking bits to see if we can touch the dynamic locks bytes for NTAG tags - if(block_num == user_memory_end) - { + if (block_num == user_memory_end) { switch (m_tag_type) { case TAG_TYPE_NTAG_213: case TAG_TYPE_NTAG_215: case TAG_TYPE_NTAG_216: { uint8_t block_bytes = m_tag_information->memory[user_memory_end][2]; uint16_t block_world = 0; - + // Each bit in block_bytes maps to 2 bits in block_world for (int i = 0; i < 8; i++) { if (block_bytes & (0x01 << i)) { block_world |= (0x0003 << (i * 2)); } } - + p_lock_bytes = m_tag_information->memory[user_memory_end]; uint16_t lock_word = (((uint16_t)p_lock_bytes[1]) << 8) | (uint16_t)p_lock_bytes[0]; return (lock_word & block_world) != 0; @@ -864,7 +863,7 @@ static int handle_write_command(uint8_t block_num, uint8_t *p_data) { default: out_of_bounds = block_num >= block_max; break; - } + } // Reject out-of-bounds writes (except config pages) if (out_of_bounds) { NRF_LOG_ERROR("Write failed: block_num %08x >= block_max %08x", block_num, block_max); @@ -1007,10 +1006,10 @@ static void handle_pwd_auth_command(uint8_t *p_data) { if (m_tag_information->config.detection_enable && m_auth_log.count < MF0_NTAG_AUTH_LOG_MAX) { memcpy(m_auth_log.logs[m_auth_log.count].pwd, &p_data[1], 4); m_auth_log.count++; - NRF_LOG_INFO("NTAG password: %02x%02x%02x%02x", + NRF_LOG_INFO("NTAG password: %02x%02x%02x%02x", p_data[1], p_data[2], p_data[3], p_data[4]); } - + if (pwd != supplied_pwd) { if (auth_lim) { cnt_data[MF0_NTAG_AUTHLIM_OFF_IN_CTR] &= ~MF0_NTAG_AUTHLIM_MASK_IN_CTR; diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_mf1.c b/firmware/application/src/rfid/nfctag/hf/nfc_mf1.c index 173b76b5..f890aa5c 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_mf1.c +++ b/firmware/application/src/rfid/nfctag/hf/nfc_mf1.c @@ -339,7 +339,10 @@ void nfc_tag_mf1_random_nonce(uint8_t nonce[4], bool isNested) { uint8_t prng_type = m_tag_information->config.prng_type; if (prng_type == 0) { // STATIC — always return same nonce (clone-card behaviour) - nonce[0] = 0x01; nonce[1] = 0x02; nonce[2] = 0x03; nonce[3] = 0x04; + nonce[0] = 0x01; + nonce[1] = 0x02; + nonce[2] = 0x03; + nonce[3] = 0x04; } else if (prng_type == 1) { // WEAK — real MFC LFSR, advance 32 clocks per call m_prng_state = prng_successor(m_prng_state, 32); diff --git a/firmware/application/src/rfid/nfctag/hf/nfc_mf1.h b/firmware/application/src/rfid/nfctag/hf/nfc_mf1.h index 70c8e1c3..c04b40fc 100644 --- a/firmware/application/src/rfid/nfctag/hf/nfc_mf1.h +++ b/firmware/application/src/rfid/nfctag/hf/nfc_mf1.h @@ -73,7 +73,7 @@ typedef struct { uint8_t mode_gen2_magic: 1; /** * Should the NFC peripheral be reset after losing the RF field? - * This configuration can fix the issue where some card readers cause the CU to enter a strange state of no response/incorrect response. + * This configuration can fix the issue where some card readers cause the CU to enter a strange state of no response/incorrect response. * Once in this state, the device must be restarted to resolve the issue. * Alternatively, enabling this configuration for resetting the NFC after leaving the rf field can also solve the aforementioned problem. */ diff --git a/firmware/application/src/rfid/nfctag/lf/lf_tag_em.c b/firmware/application/src/rfid/nfctag/lf/lf_tag_em.c index 3f5ab03b..1eb4bf67 100644 --- a/firmware/application/src/rfid/nfctag/lf/lf_tag_em.c +++ b/firmware/application/src/rfid/nfctag/lf/lf_tag_em.c @@ -336,7 +336,8 @@ bool lf_tag_data_factory(uint8_t slot, tag_specific_type_t tag_type, uint8_t *ta bool lf_tag_em410x_data_factory(uint8_t slot, tag_specific_type_t tag_type) { static const uint8_t tag_id_base[LF_EM410X_TAG_ID_SIZE] = {0xDE, 0xAD, 0xBE, 0xEF, 0x88}; static const uint8_t tag_id_electra[LF_EM410X_ELECTRA_TAG_ID_SIZE] = {0xDE, 0xAD, 0xBE, 0xEF, 0x88, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; switch (tag_type) { case TAG_TYPE_EM410X_ELECTRA: @@ -365,8 +366,8 @@ bool lf_tag_hidprox_data_factory(uint8_t slot, tag_specific_type_t tag_type) { * @return Whether the format is successful, if the formatting is successful, it will return to True, otherwise False will be returned */ bool lf_tag_ioprox_data_factory(uint8_t slot, tag_specific_type_t tag_type) { - uint8_t tag_id[16] = { - 0x01,0xAA,0x30,0x39,0x00,0x78,0x6A,0xA0,0x33,0x09,0xCF,0xEF,0x00,0x00,0x00,0x00 + uint8_t tag_id[16] = { + 0x01, 0xAA, 0x30, 0x39, 0x00, 0x78, 0x6A, 0xA0, 0x33, 0x09, 0xCF, 0xEF, 0x00, 0x00, 0x00, 0x00 }; return lf_tag_data_factory(slot, tag_type, tag_id, sizeof(tag_id)); } diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/em410x.c b/firmware/application/src/rfid/nfctag/lf/protocols/em410x.c index c6b1892e..6f2e70d5 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/em410x.c +++ b/firmware/application/src/rfid/nfctag/lf/protocols/em410x.c @@ -358,10 +358,10 @@ const protocol em410x_electra = { .get_data = (codec_get_data)em410x_get_data, .modulator = (modulator)em410x_electra_modulator, .decoder = - { - .start = (decoder_start)em410x_electra_decoder_start, - .feed = (decoder_feed)em410x_electra_decoder_feed, - }, + { + .start = (decoder_start)em410x_electra_decoder_start, + .feed = (decoder_feed)em410x_electra_decoder_feed, + }, }; // EM-Micro, EM410x/64 (std) @@ -373,10 +373,10 @@ const protocol em410x_64 = { .get_data = (codec_get_data)em410x_get_data, .modulator = (modulator)em410x_modulator, .decoder = - { - .start = (decoder_start)em410x_decoder_start, - .feed = (decoder_feed)em410x_decoder_feed, - }, + { + .start = (decoder_start)em410x_decoder_start, + .feed = (decoder_feed)em410x_decoder_feed, + }, }; // EM-Micro, EM410x/32 @@ -388,10 +388,10 @@ const protocol em410x_32 = { .get_data = (codec_get_data)em410x_get_data, .modulator = (modulator)em410x_modulator, .decoder = - { - .start = (decoder_start)em410x_decoder_start, - .feed = (decoder_feed)em410x_decoder_feed, - }, + { + .start = (decoder_start)em410x_decoder_start, + .feed = (decoder_feed)em410x_decoder_feed, + }, }; // EM-Micro, EM410x/16 @@ -403,10 +403,10 @@ const protocol em410x_16 = { .get_data = (codec_get_data)em410x_get_data, .modulator = (modulator)em410x_modulator, .decoder = - { - .start = (decoder_start)em410x_decoder_start, - .feed = (decoder_feed)em410x_decoder_feed, - }, + { + .start = (decoder_start)em410x_decoder_start, + .feed = (decoder_feed)em410x_decoder_feed, + }, }; // Encode EM410X card number to T55xx blocks. diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/em410x.h b/firmware/application/src/rfid/nfctag/lf/protocols/em410x.h index f3438f0e..9c3b3123 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/em410x.h +++ b/firmware/application/src/rfid/nfctag/lf/protocols/em410x.h @@ -7,7 +7,7 @@ extern const protocol em410x_32; extern const protocol em410x_16; extern const protocol em410x_electra; -extern const protocol* em410x_protocols[]; +extern const protocol *em410x_protocols[]; extern size_t em410x_protocols_size; uint8_t em410x_t55xx_writer(uint8_t* uid, uint32_t* blks); diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/hidprox.c b/firmware/application/src/rfid/nfctag/lf/protocols/hidprox.c index 9870138e..fa7fb689 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/hidprox.c +++ b/firmware/application/src/rfid/nfctag/lf/protocols/hidprox.c @@ -228,14 +228,14 @@ const protocol hidprox = { .get_data = (codec_get_data)hidprox_get_data, .modulator = (modulator)hidprox_modulator, .decoder = - { - .start = (decoder_start)hidprox_decoder_start, - .feed = (decoder_feed)hidprox_decoder_feed, - }, + { + .start = (decoder_start)hidprox_decoder_start, + .feed = (decoder_feed)hidprox_decoder_feed, + }, }; uint8_t hidprox_t55xx_writer(wiegand_card_t *card, uint32_t *blks) { blks[0] = T5577_HIDPROX_CONFIG; hidprox_raw_data(card, &blks[1], &blks[2], &blks[3]); return HIDPROX_T55XX_BLOCK_COUNT; -} \ No newline at end of file +} diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/hidprox.h b/firmware/application/src/rfid/nfctag/lf/protocols/hidprox.h index 8306954d..5a7e1e0e 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/hidprox.h +++ b/firmware/application/src/rfid/nfctag/lf/protocols/hidprox.h @@ -30,4 +30,4 @@ typedef struct { extern const protocol hidprox; -uint8_t hidprox_t55xx_writer(wiegand_card_t *card, uint32_t *blks); \ No newline at end of file +uint8_t hidprox_t55xx_writer(wiegand_card_t *card, uint32_t *blks); diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/ioprox.c b/firmware/application/src/rfid/nfctag/lf/protocols/ioprox.c index 10d999c4..a24b16df 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/ioprox.c +++ b/firmware/application/src/rfid/nfctag/lf/protocols/ioprox.c @@ -31,8 +31,7 @@ void ioprox_reset_bits(ioprox_codec_t *d) { d->bit_len = 0; } -static inline void push_bit(ioprox_codec_t *d, uint8_t bit) -{ +static inline void push_bit(ioprox_codec_t *d, uint8_t bit) { if (d->bit_len < IOPROX_MAX_BITS) { d->bits[d->bit_len++] = bit; return; @@ -42,15 +41,13 @@ static inline void push_bit(ioprox_codec_t *d, uint8_t bit) d->bits[IOPROX_MAX_BITS - 1] = bit; } -static inline uint8_t get_bit_inv(const uint8_t *bits, uint16_t pos, bool inv) -{ +static inline uint8_t get_bit_inv(const uint8_t *bits, uint16_t pos, bool inv) { uint8_t b = bits[pos] & 1u; return inv ? (uint8_t)(b ^ 1u) : b; } // Converts a bit array to a 32-bit big-endian integer. -static inline uint32_t bytebits_to_byte(const uint8_t *bits, uint16_t len) -{ +static inline uint32_t bytebits_to_byte(const uint8_t *bits, uint16_t len) { uint32_t val = 0; for (uint16_t i = 0; i < len; i++) { val = (val << 1) | (bits[i] & 1u); @@ -59,8 +56,7 @@ static inline uint32_t bytebits_to_byte(const uint8_t *bits, uint16_t len) } // Reads 8 bits MSB-first from bits[start_pos], optionally inverting each bit. -static inline uint8_t bytebits_to_u8_msb_inv(const uint8_t *bits, uint16_t start_pos, bool inv) -{ +static inline uint8_t bytebits_to_u8_msb_inv(const uint8_t *bits, uint16_t start_pos, bool inv) { uint8_t v = 0; for (int i = 0; i < 8; i++) { v = (uint8_t)((v << 1) | get_bit_inv(bits, (uint16_t)(start_pos + i), inv)); @@ -81,16 +77,14 @@ bool ioprox_raw8_to_bits(const uint8_t *raw8, ioprox_codec_t *d) { } // ioProx checksum: 0xFF - (sum(b1..b5) & 0xFF) -static inline uint8_t ioprox_checksum5(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) -{ +static inline uint8_t ioprox_checksum5(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5) { uint16_t sum = (uint16_t)b1 + b2 + b3 + b4 + b5; return (uint8_t)(0xFFu - (uint8_t)(sum & 0xFFu)); } // Returns true if 10 starting bits form a valid ioProx preamble. // Preamble is 9 zeros followed by 1 one (inverted when inv=true). -static bool preamble_match(const uint8_t *d, uint16_t off, bool inv) -{ +static bool preamble_match(const uint8_t *d, uint16_t off, bool inv) { for (int k = 0; k < 9; k++) { if ((d[off + k] & 1u) != (inv ? 1u : 0u)) return false; } @@ -115,8 +109,7 @@ static bool preamble_match(const uint8_t *d, uint16_t off, bool inv) // [2-3] card number (big-endian) // [4-11] raw8 frame bytes (for debugging and storage) // [12-15] reserved (0x00) -static bool decode_and_pack(ioprox_codec_t *d, uint16_t idx, bool inv) -{ +static bool decode_and_pack(ioprox_codec_t *d, uint16_t idx, bool inv) { uint8_t b1, b2, b3, b4, b5, b6; uint16_t number; uint32_t raw_block1; @@ -172,8 +165,7 @@ bool ioprox_decode_raw_to_data(const uint8_t *raw8, uint8_t *output) { } // Writes 8 bits of v MSB-first into bits[] starting at position pos. -static void write_bits_msb(uint8_t *bits, uint16_t pos, uint8_t v) -{ +static void write_bits_msb(uint8_t *bits, uint16_t pos, uint8_t v) { for (uint8_t i = 0; i < 8; i++) { bits[pos + i] = (v >> (7 - i)) & 1; } @@ -182,8 +174,7 @@ static void write_bits_msb(uint8_t *bits, uint16_t pos, uint8_t v) // Encodes ioProx card parameters into the 16-byte output buffer. // The encoded frame uses 8+1 bit framing (8 data bits + 1 separator per group). // Returns false if output pointer is NULL. -bool ioprox_encode_params_to_data(uint8_t version, uint8_t facility, uint16_t number, uint8_t *output) -{ +bool ioprox_encode_params_to_data(uint8_t version, uint8_t facility, uint16_t number, uint8_t *output) { if (!output) return false; uint8_t b0 = 0x00; @@ -197,12 +188,18 @@ bool ioprox_encode_params_to_data(uint8_t version, uint8_t facility, uint16_t nu uint8_t bits[64] = {0}; // Pack 7 data bytes using 8+1 framing (data bits + separator) - write_bits_msb(bits, 0, b0); bits[ 8] = 0; - write_bits_msb(bits, 9, b1); bits[17] = 1; - write_bits_msb(bits, 18, b2); bits[26] = 1; - write_bits_msb(bits, 27, b3); bits[35] = 1; - write_bits_msb(bits, 36, b4); bits[44] = 1; - write_bits_msb(bits, 45, b5); bits[53] = 1; + write_bits_msb(bits, 0, b0); + bits[ 8] = 0; + write_bits_msb(bits, 9, b1); + bits[17] = 1; + write_bits_msb(bits, 18, b2); + bits[26] = 1; + write_bits_msb(bits, 27, b3); + bits[35] = 1; + write_bits_msb(bits, 36, b4); + bits[44] = 1; + write_bits_msb(bits, 45, b5); + bits[53] = 1; write_bits_msb(bits, 54, b6); bits[62] = 1; bits[63] = 1; @@ -227,8 +224,7 @@ bool ioprox_encode_params_to_data(uint8_t version, uint8_t facility, uint16_t nu // Scans the tail of the bit buffer for a valid ioProx frame. // To keep CPU load low, only the last ~5 frames (320 bits) are scanned. // Returns true if a valid frame (checksum OK) was decoded into d->data. -static bool scan_tail(ioprox_codec_t *d) -{ +static bool scan_tail(ioprox_codec_t *d) { // Need at least 128 bits to verify two consecutive 64-bit frames if (d->bit_len < 128) return false; @@ -277,8 +273,7 @@ static bool scan_tail(ioprox_codec_t *d) // --- Protocol callbacks --- -static void *ioprox_codec_alloc(void) -{ +static void *ioprox_codec_alloc(void) { ioprox_codec_t *d = (ioprox_codec_t *)malloc(sizeof(ioprox_codec_t)); if (!d) return NULL; memset(d, 0, sizeof(*d)); @@ -286,8 +281,7 @@ static void *ioprox_codec_alloc(void) return d; } -static void ioprox_codec_free(void *codec) -{ +static void ioprox_codec_free(void *codec) { ioprox_codec_t *d = (ioprox_codec_t *)codec; if (!d) return; if (d->modem) { @@ -297,14 +291,12 @@ static void ioprox_codec_free(void *codec) free(d); } -static uint8_t *ioprox_get_data(void *codec) -{ +static uint8_t *ioprox_get_data(void *codec) { ioprox_codec_t *d = (ioprox_codec_t *)codec; return d->data; } -static void ioprox_decoder_start(void *codec, uint8_t format_hint) -{ +static void ioprox_decoder_start(void *codec, uint8_t format_hint) { (void)format_hint; ioprox_codec_t *d = (ioprox_codec_t *)codec; d->bit_len = 0; @@ -312,8 +304,7 @@ static void ioprox_decoder_start(void *codec, uint8_t format_hint) memset(d->data, 0, sizeof(d->data)); } -static bool ioprox_decoder_feed(void *codec, uint16_t val) -{ +static bool ioprox_decoder_feed(void *codec, uint16_t val) { ioprox_codec_t *d = (ioprox_codec_t *)codec; if (!d || !d->modem) return false; @@ -340,8 +331,7 @@ static bool ioprox_decoder_feed(void *codec, uint16_t val) return false; } -static inline void ioprox_emit_bit(int *k, bool bit) -{ +static inline void ioprox_emit_bit(int *k, bool bit) { if (!bit) { for (int j = 0; j < LF_FSK2a_PWM_HI_FREQ_LOOP; j++) { m_ioprox_pwm_seq_vals[*k].channel_0 = LF_FSK2a_PWM_HI_FREQ_TOP_VALUE / 2; @@ -358,8 +348,7 @@ static inline void ioprox_emit_bit(int *k, bool bit) } // FSK2a modulator: converts the 8 raw card bytes into a PWM sequence for LF transmission. -const nrf_pwm_sequence_t *ioprox_modulator(ioprox_codec_t *d, uint8_t *buf) -{ +const nrf_pwm_sequence_t *ioprox_modulator(ioprox_codec_t *d, uint8_t *buf) { (void)d; // Raw card data starts at buf[4] (bytes 0-3 are decoded fields) diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/ioprox.h b/firmware/application/src/rfid/nfctag/lf/protocols/ioprox.h index 234490f3..1c3ee669 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/ioprox.h +++ b/firmware/application/src/rfid/nfctag/lf/protocols/ioprox.h @@ -27,4 +27,4 @@ extern const protocol ioprox; uint8_t ioprox_t55xx_writer(uint8_t *buf, uint32_t *blks); bool ioprox_decode_raw_to_data(const uint8_t *raw8, uint8_t *output); -bool ioprox_encode_params_to_data(uint8_t ver, uint8_t fc, uint16_t cn, uint8_t *out); \ No newline at end of file +bool ioprox_encode_params_to_data(uint8_t ver, uint8_t fc, uint16_t cn, uint8_t *out); diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/pac.c b/firmware/application/src/rfid/nfctag/lf/protocols/pac.c index 629cc384..ed60d239 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/pac.c +++ b/firmware/application/src/rfid/nfctag/lf/protocols/pac.c @@ -97,7 +97,7 @@ static bool get_bit(pac_codec *d, uint16_t pos) { // Decode a 10-bit UART frame at bit position 'start'. // Frame: start(0) + 7 data bits LSB-first + odd parity + stop(1). static int decode_uart_byte(pac_codec *d, uint16_t start, bool inverted) { - #define RD(pos) (inverted ? !get_bit(d, (pos)) : get_bit(d, (pos))) +#define RD(pos) (inverted ? !get_bit(d, (pos)) : get_bit(d, (pos))) if (RD(start)) { return -1; @@ -123,7 +123,7 @@ static int decode_uart_byte(pac_codec *d, uint16_t start, bool inverted) { return -1; } - #undef RD +#undef RD return byte_val; } @@ -393,8 +393,8 @@ const protocol pac = { .get_data = (codec_get_data)pac_get_data, .modulator = (modulator)pac_modulator, .decoder = - { - .start = (decoder_start)pac_decoder_start, - .feed = (decoder_feed)pac_decoder_feed, - }, + { + .start = (decoder_start)pac_decoder_start, + .feed = (decoder_feed)pac_decoder_feed, + }, }; diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/protocols.h b/firmware/application/src/rfid/nfctag/lf/protocols/protocols.h index 28bac8d3..3791a7dd 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/protocols.h +++ b/firmware/application/src/rfid/nfctag/lf/protocols/protocols.h @@ -7,14 +7,14 @@ #include "nrf_pwm.h" #include "tag_base_type.h" -typedef void* (*codec_alloc)(void); +typedef void *(*codec_alloc)(void); typedef void (*codec_free)(void* codec); -typedef uint8_t* (*codec_get_data)(void* codec); +typedef uint8_t *(*codec_get_data)(void* codec); typedef void (*decoder_start)(void* codec, uint8_t format); typedef bool (*decoder_feed)(void* codec, uint16_t val); -typedef nrf_pwm_sequence_t* (*modulator)(void* d, uint8_t* buf); +typedef nrf_pwm_sequence_t *(*modulator)(void* d, uint8_t* buf); typedef struct { decoder_start start; diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/viking.c b/firmware/application/src/rfid/nfctag/lf/protocols/viking.c index 74d8f871..1af37ff5 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/viking.c +++ b/firmware/application/src/rfid/nfctag/lf/protocols/viking.c @@ -20,7 +20,7 @@ #define VIKING_T55XX_BLOCK_COUNT (3) // config + 2 data blocks -// Duration between falling edges is... +// Duration between falling edges is... #define VIKING_READ_TIME1_BASE (0x20) // on 16, off 16 cycles #define VIKING_READ_TIME2_BASE (0x30) // on 16, off 32 cycles (or on 32 cycles, off 16 cycles) #define VIKING_READ_TIME3_BASE (0x40) // on 32, off 32 cycles @@ -94,7 +94,7 @@ static void viking_free(viking_codec *d) { free(d); }; -static uint8_t *viking_get_data(viking_codec *d) { +static uint8_t *viking_get_data(viking_codec *d) { return d->data; }; @@ -111,7 +111,7 @@ static bool viking_decode_feed(viking_codec *d, bool bit) { if (bit) { d->raw |= 0x01; } - if (d->raw_length < (VIKING_RAW_SIZE-2)) { + if (d->raw_length < (VIKING_RAW_SIZE - 2)) { return false; } @@ -132,7 +132,7 @@ static bool viking_decode_feed(viking_codec *d, bool bit) { // Validate CRC uint8_t crc = 0x5A; for (int i = 0; i < VIKING_DATA_SIZE; i++) { - uint8_t data = (d->raw >> ((i+1)*8)) & 0xff; + uint8_t data = (d->raw >> ((i + 1) * 8)) & 0xff; crc ^= data; d->data[VIKING_DATA_SIZE - i - 1] |= data; } @@ -144,7 +144,7 @@ static bool viking_decoder_feed(viking_codec *d, uint16_t interval) { bool bits[2] = {0}; int8_t bitlen = 0; - // Hack: due to hardware sometimes not detecting a time2 pulse. Rather than + // Hack: due to hardware sometimes not detecting a time2 pulse. Rather than // reset when interval is really long, assume there was a time2 pulse. if (interval > VIKING_READ_TIME3_BASE + VIKING_READ_JITTER_TIME_BASE) { interval -= VIKING_READ_TIME2_BASE; @@ -203,10 +203,10 @@ const protocol viking = { .get_data = (codec_get_data)viking_get_data, .modulator = (modulator)viking_modulator, .decoder = - { - .start = (decoder_start)viking_decoder_start, - .feed = (decoder_feed)viking_decoder_feed, - }, + { + .start = (decoder_start)viking_decoder_start, + .feed = (decoder_feed)viking_decoder_feed, + }, }; // Encode viking card number to T55xx blocks. @@ -216,4 +216,4 @@ uint8_t viking_t55xx_writer(uint8_t *uid, uint32_t *blks) { blks[1] = raw >> 32; blks[2] = raw & 0xffffffff; return VIKING_T55XX_BLOCK_COUNT; -} \ No newline at end of file +} diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/viking.h b/firmware/application/src/rfid/nfctag/lf/protocols/viking.h index 7e27d1fa..e6db9f2a 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/viking.h +++ b/firmware/application/src/rfid/nfctag/lf/protocols/viking.h @@ -4,4 +4,4 @@ extern const protocol viking; -uint8_t viking_t55xx_writer(uint8_t* uid, uint32_t* blks); \ No newline at end of file +uint8_t viking_t55xx_writer(uint8_t* uid, uint32_t* blks); diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/wiegand.c b/firmware/application/src/rfid/nfctag/lf/protocols/wiegand.c index e33bad78..9c380e26 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/wiegand.c +++ b/firmware/application/src/rfid/nfctag/lf/protocols/wiegand.c @@ -100,7 +100,7 @@ static uint64_t pack_h10301(wiegand_card_t *card) { static wiegand_card_t *unpack_h10301(uint64_t hi, uint64_t lo) { if (!((IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xfff)) && - (IS_SET(lo, 25) == evenparity32((lo >> 13) & 0xfff)))) { + (IS_SET(lo, 25) == evenparity32((lo >> 13) & 0xfff)))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -192,8 +192,8 @@ static uint64_t pack_2804w(wiegand_card_t *card) { static wiegand_card_t *unpack_2804w(uint64_t hi, uint64_t lo) { if (!(((lo >> 27) & 0x1) == (evenparity32((lo >> 14) & 0x1fff)) && - (((lo >> 25) & 0x1) == (oddparity32(lo & 0xDB6DB6))) && - (((lo >> 0) & 0x1) == (oddparity32((lo >> 1) & 0x7ffffff))))) { + (((lo >> 25) & 0x1) == (oddparity32(lo & 0xDB6DB6))) && + (((lo >> 0) & 0x1) == (oddparity32((lo >> 1) & 0x7ffffff))))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -233,7 +233,7 @@ static uint64_t pack_atsw30(wiegand_card_t *card) { static wiegand_card_t *unpack_atsw30(uint64_t hi, uint64_t lo) { if (!(IS_SET(lo, 29) == evenparity32((lo >> 17) & 0xfff) && - IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff))) { + IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -308,7 +308,7 @@ static wiegand_card_t *unpack_kastle(uint64_t hi, uint64_t lo) { return NULL; } if (!(IS_SET(lo, 31) == evenparity32((lo >> 15) & 0xffff) && - IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x1ffff))) { + IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x1ffff))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -366,7 +366,7 @@ static uint64_t pack_d10202(wiegand_card_t *card) { static wiegand_card_t *unpack_d10202(uint64_t hi, uint64_t lo) { if (!((IS_SET(lo, 32) == evenparity32((lo >> 16) & 0xffff)) && - (IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff)))) { + (IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff)))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -392,7 +392,7 @@ static uint64_t pack_h10306(wiegand_card_t *card) { static wiegand_card_t *unpack_h10306(uint64_t hi, uint64_t lo) { if (!((IS_SET(lo, 33) == evenparity32((lo >> 17) & 0xffff)) && - (IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff)))) { + (IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff)))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -418,7 +418,7 @@ static uint64_t pack_n10002(wiegand_card_t *card) { static wiegand_card_t *unpack_n10002(uint64_t hi, uint64_t lo) { if (!((IS_SET(lo, 33) == evenparity32((lo >> 17) & 0xffff)) && - (IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff)))) { + (IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff)))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -479,7 +479,7 @@ static uint64_t pack_bqt34(wiegand_card_t *card) { static wiegand_card_t *unpack_bqt34(uint64_t hi, uint64_t lo) { if (!((IS_SET(lo, 33) == evenparity32((lo >> 17) & 0xffff)) && - (IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff)))) { + (IS_SET(lo, 0) == oddparity32((lo >> 1) & 0xffff)))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -508,8 +508,8 @@ static uint64_t pack_c1k35s(wiegand_card_t *card) { static wiegand_card_t *unpack_c1k35s(uint64_t hi, uint64_t lo) { if (!(IS_SET(lo, 33) == (evenparity32((lo >> 1) & 0xDB6DB6DB)) && - IS_SET(lo, 0) == (oddparity32((lo >> 2) & 0xDB6DB6DB)) && - IS_SET(lo, 34) == (oddparity32(((lo >> 32) & 0x3) ^ (lo & 0xFFFFFFFF))))) { + IS_SET(lo, 0) == (oddparity32((lo >> 2) & 0xDB6DB6DB)) && + IS_SET(lo, 34) == (oddparity32(((lo >> 32) & 0x3) ^ (lo & 0xFFFFFFFF))))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -539,7 +539,7 @@ static uint64_t pack_c15001(wiegand_card_t *card) { static wiegand_card_t *unpack_c15001(uint64_t hi, uint64_t lo) { if (!(IS_SET(lo, 35) == evenparity32((lo >> 18) & 0x1ffff) && - IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x1ffff))) { + IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x1ffff))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -570,7 +570,7 @@ static uint64_t pack_actprox(wiegand_card_t *card) { static wiegand_card_t *unpack_actprox(uint64_t hi, uint64_t lo) { if (!(IS_SET(lo, 35) == evenparity32((lo >> 18) & 0x1ffff) && - IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x1ffff))) { + IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x1ffff))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -598,7 +598,7 @@ static uint64_t pack_s12906(wiegand_card_t *card) { static wiegand_card_t *unpack_s12906(uint64_t hi, uint64_t lo) { if (!(IS_SET(lo, 35) == oddparity32((lo >> 18) & 0x1ffff) && - IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x3ffff))) { + IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x3ffff))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -625,7 +625,7 @@ static uint64_t pack_sie36(wiegand_card_t *card) { static wiegand_card_t *unpack_sie36(uint64_t hi, uint64_t lo) { if (!(IS_SET(lo, 35) == oddparity32((lo & 0xB6DB6DB6) ^ ((lo >> 32) & 0x05)) && - IS_SET(lo, 0) == evenparity32((lo & 0xDB6DB6DA) ^ ((lo >> 32) & 0x06)))) { + IS_SET(lo, 0) == evenparity32((lo & 0xDB6DB6DA) ^ ((lo >> 32) & 0x06)))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -664,9 +664,9 @@ static wiegand_card_t *unpack_h10320(uint64_t hi, uint64_t lo) { } if (!((IS_SET(lo, 3) == evenparity32((lo >> 4) & 0x88888888)) && - (IS_SET(lo, 2) == oddparity32((lo >> 4) & 0x44444444)) && - (IS_SET(lo, 1) == evenparity32((lo >> 4) & 0x22222222)) && - (IS_SET(lo, 0) == evenparity32((lo >> 4) & 0x11111111)))) { + (IS_SET(lo, 2) == oddparity32((lo >> 4) & 0x44444444)) && + (IS_SET(lo, 1) == evenparity32((lo >> 4) & 0x22222222)) && + (IS_SET(lo, 0) == evenparity32((lo >> 4) & 0x11111111)))) { return NULL; } @@ -703,7 +703,7 @@ static uint64_t pack_h10302(wiegand_card_t *card) { static wiegand_card_t *unpack_h10302(uint64_t hi, uint64_t lo) { if (!(IS_SET(lo, 36) == evenparity32((lo >> 18) & 0x3ffff) && - IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x3ffff))) { + IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x3ffff))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -728,7 +728,7 @@ static uint64_t pack_h10304(wiegand_card_t *card) { static wiegand_card_t *unpack_h10304(uint64_t hi, uint64_t lo) { if (!(IS_SET(lo, 36) == evenparity32((lo >> 18) & 0x3ffff) && - IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x3ffff))) { + IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x3ffff))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -780,8 +780,8 @@ static wiegand_card_t *unpack_hgeneric37(uint64_t hi, uint64_t lo) { return NULL; } if (!(IS_SET(lo, 36) == evenparity32((lo >> 4) & 0x11111111) && - IS_SET(lo, 34) == oddparity32(lo & 0x44444444) && - IS_SET(lo, 33) == evenparity32(lo & 0x22222222))) { + IS_SET(lo, 34) == oddparity32(lo & 0x44444444) && + IS_SET(lo, 33) == evenparity32(lo & 0x22222222))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); @@ -806,7 +806,7 @@ static uint64_t pack_mdi37(wiegand_card_t *card) { static wiegand_card_t *unpack_mdi37(uint64_t hi, uint64_t lo) { if (!(IS_SET(lo, 36) == evenparity32((lo >> 18) & 0x3ffff) && - IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x3ffff))) { + IS_SET(lo, 0) == oddparity32((lo >> 1) & 0x3ffff))) { return NULL; } wiegand_card_t *d = wiegand_card_alloc(); diff --git a/firmware/application/src/rfid/nfctag/lf/protocols/wiegand.h b/firmware/application/src/rfid/nfctag/lf/protocols/wiegand.h index 43f848e0..5262fea4 100644 --- a/firmware/application/src/rfid/nfctag/lf/protocols/wiegand.h +++ b/firmware/application/src/rfid/nfctag/lf/protocols/wiegand.h @@ -86,4 +86,4 @@ typedef struct { extern uint64_t pack(wiegand_card_t *card); extern wiegand_card_t *unpack(uint8_t format_hint, uint8_t length, uint64_t hi, uint64_t lo); -extern wiegand_card_t *wiegand_card_alloc(); \ No newline at end of file +extern wiegand_card_t *wiegand_card_alloc(); diff --git a/firmware/application/src/rfid/nfctag/lf/utils/circular_buffer.c b/firmware/application/src/rfid/nfctag/lf/utils/circular_buffer.c index 59b76ca7..817563b5 100644 --- a/firmware/application/src/rfid/nfctag/lf/utils/circular_buffer.c +++ b/firmware/application/src/rfid/nfctag/lf/utils/circular_buffer.c @@ -48,4 +48,4 @@ bool cb_pop_front(circular_buffer *cb, void *item) { } cb->count--; return true; -} \ No newline at end of file +} diff --git a/firmware/application/src/rfid/nfctag/lf/utils/circular_buffer.h b/firmware/application/src/rfid/nfctag/lf/utils/circular_buffer.h index 9a670cf6..257d3ffc 100644 --- a/firmware/application/src/rfid/nfctag/lf/utils/circular_buffer.h +++ b/firmware/application/src/rfid/nfctag/lf/utils/circular_buffer.h @@ -25,4 +25,4 @@ extern bool cb_pop_front(circular_buffer *cb, void *item); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/firmware/application/src/rfid/nfctag/lf/utils/fskdemod.c b/firmware/application/src/rfid/nfctag/lf/utils/fskdemod.c index 02a34e1e..a6ea7306 100644 --- a/firmware/application/src/rfid/nfctag/lf/utils/fskdemod.c +++ b/firmware/application/src/rfid/nfctag/lf/utils/fskdemod.c @@ -25,7 +25,7 @@ void fsk_free(fsk_t *m) { } /** - * Changed from fixed BITRATE constant to dynamic parameter to allow + * Changed from fixed BITRATE constant to dynamic parameter to allow * multiple protocols with different speeds. */ bool fsk_feed(fsk_t *m, uint16_t sample, bool *bit) { @@ -39,12 +39,12 @@ bool fsk_feed(fsk_t *m, uint16_t sample, bool *bit) { // Reset counter and clear sample buffer for the next bit m->c = 0; - memset(m->samples, 0, sizeof(uint16_t) * m->bitrate); + memset(m->samples, 0, sizeof(uint16_t) * m->bitrate); return true; } /** - * Changed from fixed BITRATE constant to dynamic parameter to allow + * Changed from fixed BITRATE constant to dynamic parameter to allow * multiple protocols with different speeds. */ fsk_t *fsk_alloc(uint8_t bitrate) { diff --git a/firmware/application/src/rfid/nfctag/lf/utils/manchester.h b/firmware/application/src/rfid/nfctag/lf/utils/manchester.h index 202d563f..c317d620 100644 --- a/firmware/application/src/rfid/nfctag/lf/utils/manchester.h +++ b/firmware/application/src/rfid/nfctag/lf/utils/manchester.h @@ -12,4 +12,4 @@ typedef struct { } manchester; extern void manchester_reset(manchester *m); -extern void manchester_feed(manchester *m, uint8_t interval, bool *bits, int8_t *bitlen); \ No newline at end of file +extern void manchester_feed(manchester *m, uint8_t interval, bool *bits, int8_t *bitlen); diff --git a/firmware/application/src/rfid/nfctag/tag_emulation.c b/firmware/application/src/rfid/nfctag/tag_emulation.c index 25e63537..dd54c6e6 100644 --- a/firmware/application/src/rfid/nfctag/tag_emulation.c +++ b/firmware/application/src/rfid/nfctag/tag_emulation.c @@ -353,11 +353,13 @@ void tag_emulation_delete_data(uint8_t slot, tag_sense_type_t sense_type) { case TAG_SENSE_HF: { slotConfig.slots[slot].tag_hf = TAG_TYPE_UNDEFINED; slotConfig.slots[slot].enabled_hf = false; - } break; + } + break; case TAG_SENSE_LF: { slotConfig.slots[slot].tag_lf = TAG_TYPE_UNDEFINED; slotConfig.slots[slot].enabled_lf = false; - } break; + } + break; default: break; } @@ -416,7 +418,7 @@ void tag_emulation_sense_switch(tag_sense_type_t type, bool enable) { break; case TAG_SENSE_HF: if (enable && (slotConfig.slots[slot].enabled_hf) && - (slotConfig.slots[slot].tag_hf != TAG_TYPE_UNDEFINED)) { + (slotConfig.slots[slot].tag_hf != TAG_TYPE_UNDEFINED)) { nfc_tag_14a_sense_switch(true); } else { nfc_tag_14a_sense_switch(false); @@ -424,7 +426,7 @@ void tag_emulation_sense_switch(tag_sense_type_t type, bool enable) { break; case TAG_SENSE_LF: if (enable && (slotConfig.slots[slot].enabled_lf) && - (slotConfig.slots[slot].tag_lf != TAG_TYPE_UNDEFINED)) { + (slotConfig.slots[slot].tag_lf != TAG_TYPE_UNDEFINED)) { lf_tag_125khz_sense_switch(true); } else { lf_tag_125khz_sense_switch(false); diff --git a/firmware/application/src/rfid/reader/hf/mf1_toolbox.c b/firmware/application/src/rfid/reader/hf/mf1_toolbox.c index 67e39278..9af40ab4 100644 --- a/firmware/application/src/rfid/reader/hf/mf1_toolbox.c +++ b/firmware/application/src/rfid/reader/hf/mf1_toolbox.c @@ -1114,8 +1114,8 @@ uint8_t mf1_hardnested_nonces_acquire(bool slow, uint8_t blkKnown, uint8_t typKn uint8_t targetBlk, uint8_t targetTyp, uint8_t *nonces, uint16_t noncesMax, uint8_t *num_nonces) { struct Crypto1State mpcs = { 0, 0 }; struct Crypto1State *pcs = &mpcs; - uint8_t answer[] = { 0x00, 0x00, 0x00, 0x00 }; - uint8_t parity[] = { 0x00, 0x00, 0x00, 0x00 }; + uint8_t answer[] = { 0x00, 0x00, 0x00, 0x00 }; + uint8_t parity[] = { 0x00, 0x00, 0x00, 0x00 }; uint8_t nt_par_enc = 0; uint8_t status = STATUS_HF_TAG_NO; uint32_t cuid = 0; // cuid can be fixed when selecting card diff --git a/firmware/application/src/rfid/reader/hf/mf1_toolbox.h b/firmware/application/src/rfid/reader/hf/mf1_toolbox.h index c107c4db..b74e70a4 100644 --- a/firmware/application/src/rfid/reader/hf/mf1_toolbox.h +++ b/firmware/application/src/rfid/reader/hf/mf1_toolbox.h @@ -105,20 +105,20 @@ extern "C" { uint8_t darkside_recover_key( - uint8_t targetBlk, - uint8_t targetTyp, - uint8_t firstRecover, - uint8_t ntSyncMax, - DarksideCore_t *dc, - mf1_darkside_status_t *darkside_status +uint8_t targetBlk, +uint8_t targetTyp, +uint8_t firstRecover, +uint8_t ntSyncMax, +DarksideCore_t *dc, +mf1_darkside_status_t *darkside_status ); uint8_t nested_distance_detect( - uint8_t block, - uint8_t type, - uint8_t *key, - uint8_t *uid, - uint32_t *distance +uint8_t block, +uint8_t type, +uint8_t *key, +uint8_t *uid, +uint32_t *distance ); #define NESTED_CORE_PARAM_DEF \ @@ -137,17 +137,17 @@ void antenna_switch_delay(uint32_t delay_ms); uint16_t auth_key_use_522_hw(uint8_t block, uint8_t type, uint8_t *key); uint16_t mf1_toolbox_check_keys_of_sectors( - mf1_toolbox_check_keys_of_sectors_in_t *in, - mf1_toolbox_check_keys_of_sectors_out_t *out +mf1_toolbox_check_keys_of_sectors_in_t *in, +mf1_toolbox_check_keys_of_sectors_out_t *out ); uint16_t mf1_toolbox_check_keys_on_block( - mf1_toolbox_check_keys_on_block_in_t *in, - mf1_toolbox_check_keys_on_block_out_t *out +mf1_toolbox_check_keys_on_block_in_t *in, +mf1_toolbox_check_keys_on_block_out_t *out ); uint8_t mf1_hardnested_nonces_acquire(bool slow, uint8_t blkKnown, uint8_t typKnown, uint64_t keyKnown, - uint8_t targetBlk, uint8_t targetTyp, uint8_t *nonces, uint16_t noncesMax, uint8_t *num_nonces); +uint8_t targetBlk, uint8_t targetTyp, uint8_t *nonces, uint16_t noncesMax, uint8_t *num_nonces); uint8_t mf1_static_encrypted_nonces_acquire(uint64_t keyKnown, uint8_t sector_count, uint8_t starting_sector, uint8_t sector_data[40][sizeof(mf1_static_nonce_sector_t)], uint8_t *sectors_acquired, uint32_t *cardUid); diff --git a/firmware/application/src/rfid/reader/hf/rc522.h b/firmware/application/src/rfid/reader/hf/rc522.h index 1efcd259..c07da004 100644 --- a/firmware/application/src/rfid/reader/hf/rc522.h +++ b/firmware/application/src/rfid/reader/hf/rc522.h @@ -201,25 +201,25 @@ void pcd_14a_reader_timeout_set(uint16_t timeout_ms); // Device communication interface uint8_t pcd_14a_reader_bytes_transfer(uint8_t Command, - uint8_t *pIn, - uint8_t InLenByte, - uint8_t *pOut, - uint16_t *pOutLenBit, - uint16_t maxOutLenBit); +uint8_t *pIn, +uint8_t InLenByte, +uint8_t *pOut, +uint16_t *pOutLenBit, +uint16_t maxOutLenBit); uint8_t pcd_14a_reader_bytes_transfer_flags(uint8_t Command, - uint8_t *pIn, - uint8_t InLenByte, - uint8_t *pOut, - uint16_t *pOutLenBit, - uint16_t maxOutLenBit, - uint32_t flags); +uint8_t *pIn, +uint8_t InLenByte, +uint8_t *pOut, +uint16_t *pOutLenBit, +uint16_t maxOutLenBit, +uint32_t flags); uint8_t pcd_14a_reader_bits_transfer(uint8_t *pTx, - uint16_t szTxBits, - uint8_t *pTxPar, - uint8_t *pRx, - uint8_t *pRxPar, - uint16_t *pRxLenBit, - uint16_t szRxLenBitMax); +uint16_t szTxBits, +uint8_t *pTxPar, +uint8_t *pRx, +uint8_t *pRxPar, +uint16_t *pRxLenBit, +uint16_t szRxLenBitMax); // Device auto append and check 14443-A parity enable or disable. void pcd_14a_reader_parity_on(void); @@ -248,7 +248,7 @@ uint8_t pcd_14a_reader_halt_tag(void); void pcd_14a_reader_fast_halt_tag(void); uint8_t pcd_14a_reader_raw_cmd(bool openRFField, bool waitResp, bool appendCrc, bool autoSelect, bool keepField, bool checkCrc, uint16_t waitRespTimeout, - uint16_t szDataSendBits, uint8_t *pDataSend, uint8_t *pDataRecv, uint16_t *pszDataRecv, uint16_t szDataRecvBitMax); +uint16_t szDataSendBits, uint8_t *pDataSend, uint8_t *pDataRecv, uint16_t *pszDataRecv, uint16_t szDataRecvBitMax); // UID & UFUID tag operation uint8_t pcd_14a_reader_gen1a_unlock(void); diff --git a/firmware/application/src/rfid/reader/lf/lf_125khz_radio.c b/firmware/application/src/rfid/reader/lf/lf_125khz_radio.c index 9f70f23f..ce8ff7ae 100644 --- a/firmware/application/src/rfid/reader/lf/lf_125khz_radio.c +++ b/firmware/application/src/rfid/reader/lf/lf_125khz_radio.c @@ -25,7 +25,8 @@ nrf_pwm_sequence_t const m_lf_125khz_pwm_seq_obj = { .values.p_individual = m_lf_125khz_pwm_seq_val, .length = NRF_PWM_VALUES_LENGTH(m_lf_125khz_pwm_seq_val), .repeats = 0, - .end_delay = 0}; + .end_delay = 0 +}; /** * LF reading card decrease along the trigger collection event @@ -96,9 +97,9 @@ static void pwm_timer_count_ppi_init(void) { APP_ERROR_CHECK(err_code); err_code = nrfx_ppi_channel_assign( - m_pwm_timer_count_ppi_channel, - nrfx_pwm_event_address_get(&m_pwm, NRF_PWM_EVENT_PWMPERIODEND), - nrfx_timer_task_address_get(&m_pwm_timer_counter, NRF_TIMER_TASK_COUNT)); + m_pwm_timer_count_ppi_channel, + nrfx_pwm_event_address_get(&m_pwm, NRF_PWM_EVENT_PWMPERIODEND), + nrfx_timer_task_address_get(&m_pwm_timer_counter, NRF_TIMER_TASK_COUNT)); APP_ERROR_CHECK(err_code); } @@ -110,9 +111,9 @@ static void pwm_saadc_sample_ppi_init(void) { APP_ERROR_CHECK(err_code); err_code = nrfx_ppi_channel_assign( - m_pwm_saadc_sample_ppi_channel, - nrfx_pwm_event_address_get(&m_pwm, NRF_PWM_EVENT_PWMPERIODEND), - nrf_saadc_task_address_get(NRF_SAADC_TASK_SAMPLE)); + m_pwm_saadc_sample_ppi_channel, + nrfx_pwm_event_address_get(&m_pwm, NRF_PWM_EVENT_PWMPERIODEND), + nrf_saadc_task_address_get(NRF_SAADC_TASK_SAMPLE)); APP_ERROR_CHECK(err_code); } @@ -172,4 +173,4 @@ void lf_125khz_radio_uninit(void) { nrfx_pwm_uninit(&m_pwm); m_reader_inited = false; } -} \ No newline at end of file +} diff --git a/firmware/application/src/rfid/reader/lf/lf_em4x05_data.c b/firmware/application/src/rfid/reader/lf/lf_em4x05_data.c index d948f381..4c2e1780 100644 --- a/firmware/application/src/rfid/reader/lf/lf_em4x05_data.c +++ b/firmware/application/src/rfid/reader/lf/lf_em4x05_data.c @@ -322,7 +322,7 @@ bool em4x05_read(em4x05_data_t *out, uint32_t timeout_ms) { uint32_t uid_lo = 0, uid_hi = 0; if (em4x05_read_block(EM4X69_BLOCK_UID_LO, &uid_lo, block_timeout) && - em4x05_read_block(EM4X69_BLOCK_UID_HI, &uid_hi, block_timeout)) { + em4x05_read_block(EM4X69_BLOCK_UID_HI, &uid_hi, block_timeout)) { out->uid_hi = uid_hi; out->uid = uid_lo; out->is_em4x69 = true; diff --git a/firmware/application/src/rfid_main.c b/firmware/application/src/rfid_main.c index deb72e73..afe2b3e1 100644 --- a/firmware/application/src/rfid_main.c +++ b/firmware/application/src/rfid_main.c @@ -47,7 +47,7 @@ void tag_mode_enter(void) { pcd_14a_reader_antenna_off(); m_is_field_on = false; } - + // uninit reader lf_125khz_radio_uninit(); pcd_14a_reader_uninit(); @@ -122,4 +122,4 @@ uint8_t get_color_by_slot(uint8_t slot) { } else { // Low -frequency emulation, return B return 2; } -} \ No newline at end of file +} diff --git a/firmware/application/src/rgb_marquee.c b/firmware/application/src/rgb_marquee.c index 1705de0c..06caa875 100644 --- a/firmware/application/src/rgb_marquee.c +++ b/firmware/application/src/rgb_marquee.c @@ -562,24 +562,24 @@ void rgb_marquee_symmetric_out(uint8_t color, uint8_t slot) { for (uint8_t offset = 0; offset < length; offset++) { if (step < offset || step >= (offset + half_leds)) continue; switch (offset) { - case 0: - case length - 1: - pwm_config.output_pins[0] = led_pins[3 - step + offset]; - pwm_config.output_pins[3] = led_pins[4 + step - offset]; - break; - case 1: - case length - 2: - pwm_config.output_pins[1] = led_pins[3 - step + offset]; - pwm_config.output_pins[2] = led_pins[4 + step - offset]; - break; - default: - nrf_gpio_pin_set(led_pins[3 - step + offset]); - nrf_gpio_pin_set(led_pins[4 + step - offset]); + case 0: + case length - 1: + pwm_config.output_pins[0] = led_pins[3 - step + offset]; + pwm_config.output_pins[3] = led_pins[4 + step - offset]; + break; + case 1: + case length - 2: + pwm_config.output_pins[1] = led_pins[3 - step + offset]; + pwm_config.output_pins[2] = led_pins[4 + step - offset]; + break; + default: + nrf_gpio_pin_set(led_pins[3 - step + offset]); + nrf_gpio_pin_set(led_pins[4 + step - offset]); } } if ((slot <= 3 && slot > (3 - step + slide_leds)) || - (slot >= 4 && slot < (4 + step - slide_leds))) { + (slot >= 4 && slot < (4 + step - slide_leds))) { nrf_gpio_pin_set(led_pins[slot]); for (uint8_t j = 0; j < 4; j++) { if (pwm_config.output_pins[j] == led_pins[slot]) { @@ -622,24 +622,24 @@ void rgb_marquee_symmetric_in(uint8_t color, uint8_t slot) { for (uint8_t offset = 0; offset < length; offset++) { if (step < offset || step >= (offset + half_leds)) continue; switch (offset) { - case 0: - case length - 1: - pwm_config.output_pins[0] = led_pins[0 + step - offset]; - pwm_config.output_pins[3] = led_pins[7 - step + offset]; - break; - case 1: - case length - 2: - pwm_config.output_pins[1] = led_pins[0 + step - offset]; - pwm_config.output_pins[2] = led_pins[7 - step + offset]; - break; - default: - nrf_gpio_pin_set(led_pins[0 + step - offset]); - nrf_gpio_pin_set(led_pins[7 - step + offset]); + case 0: + case length - 1: + pwm_config.output_pins[0] = led_pins[0 + step - offset]; + pwm_config.output_pins[3] = led_pins[7 - step + offset]; + break; + case 1: + case length - 2: + pwm_config.output_pins[1] = led_pins[0 + step - offset]; + pwm_config.output_pins[2] = led_pins[7 - step + offset]; + break; + default: + nrf_gpio_pin_set(led_pins[0 + step - offset]); + nrf_gpio_pin_set(led_pins[7 - step + offset]); } } if ((slot <= 3 && slot > (0 + step - slide_leds)) || - (slot >= 4 && slot < (7 - step + slide_leds))) { + (slot >= 4 && slot < (7 - step + slide_leds))) { nrf_gpio_pin_set(led_pins[slot]); for (uint8_t j = 0; j < 4; j++) { if (pwm_config.output_pins[j] == led_pins[slot]) { diff --git a/firmware/application/src/settings.h b/firmware/application/src/settings.h index 73f6a5d0..301da7a0 100644 --- a/firmware/application/src/settings.h +++ b/firmware/application/src/settings.h @@ -84,4 +84,4 @@ bool settings_get_ble_pairing_enable_first_load(void); uint32_t settings_get_sleep_timeout(void); void settings_set_sleep_timeout(uint8_t seconds); void settings_init_sleep_timeout_config(void); -#endif \ No newline at end of file +#endif diff --git a/firmware/application/src/utils/syssleep.c b/firmware/application/src/utils/syssleep.c index 69f8d2a0..07e0f07d 100644 --- a/firmware/application/src/utils/syssleep.c +++ b/firmware/application/src/utils/syssleep.c @@ -73,4 +73,4 @@ void sleep_system_run(void (*sysOffSleep)(), void (*sysOnSleep)()) { // If no task can to process, we can sleep cpu sometime. sysOnSleep(); } -} \ No newline at end of file +} diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index a34a8a41..f16c9b60 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -632,6 +632,7 @@ class LFHIDIdReadArgsUnit(DeviceRequiredUnit): def on_exec(self, args: argparse.Namespace): raise NotImplementedError() + class LFIOProxIdArgsUnit(DeviceRequiredUnit): """ IOProx identity arguments: @@ -643,9 +644,11 @@ class LFIOProxIdArgsUnit(DeviceRequiredUnit): @staticmethod def add_card_arg(parser: ArgumentParserNoExit, required=False): parser.add_argument("--ver", type=int, required=False, help="ioProx version", metavar="") - parser.add_argument("--fc", type=str, required=False, help="ioProx facility code, e.g., 83 or 0x53", metavar="") + parser.add_argument("--fc", type=str, required=False, + help="ioProx facility code, e.g., 83 or 0x53", metavar="") parser.add_argument("--cn", type=int, required=required, help="ioProx card number", metavar="") - parser.add_argument("--raw8", type=str, required=False, help="ioProx raw 8 bytes hex (e.g. 00AABBCCDDEEFF55)", metavar="") + parser.add_argument("--raw8", type=str, required=False, + help="ioProx raw 8 bytes hex (e.g. 00AABBCCDDEEFF55)", metavar="") return parser @staticmethod @@ -678,7 +681,7 @@ class LFIOProxIdArgsUnit(DeviceRequiredUnit): if args.ver is not None: self._check_u8("version", args.ver) if args.fc is not None: - val = int(args.fc, 0) + val = int(args.fc, 0) self._check_u8("facility", val) args.fc = val if args.cn is not None: @@ -697,6 +700,7 @@ class LFIOProxReadArgsUnit(DeviceRequiredUnit): parser.add_argument("-v", "--verbose", action="store_true", help="Verbose output") return parser + class LFVikingIdArgsUnit(DeviceRequiredUnit): @staticmethod def add_card_arg(parser: ArgumentParserNoExit, required=False): @@ -1909,7 +1913,7 @@ class HFMFHardNested(ReaderRequiredUnit): # Found the target line, now extract the key using regex # Regex now looks for 12 hex chars specifically after the prefix sea_obj = re.search( - r"([a-fA-F0-9]{12})", line_stripped[len(key_prefix) :] + r"([a-fA-F0-9]{12})", line_stripped[len(key_prefix):] ) if sea_obj: key_list.append(sea_obj.group(1)) @@ -2144,7 +2148,7 @@ class HFMFStaticEncryptedNested(ReaderRequiredUnit): ) for i in tqdm_if_exists(range(0, len(keys_bytes), 64)): data = self.cmd.mf1_check_keys_on_block( - sector * 4 + 3, 0x61, keys_bytes[i : i + 64] + sector * 4 + 3, 0x61, keys_bytes[i: i + 64] ) if data: key = data.hex().zfill(12) @@ -2195,7 +2199,7 @@ class HFMFStaticEncryptedNested(ReaderRequiredUnit): ) for i in tqdm_if_exists(range(0, len(keys_bytes), 64)): data = self.cmd.mf1_check_keys_on_block( - sector * 4 + 3, 0x60, keys_bytes[i : i + 64] + sector * 4 + 3, 0x60, keys_bytes[i: i + 64] ) if data: key = data.hex().zfill(12) @@ -2326,7 +2330,7 @@ class HFMFAutopwn(ReaderRequiredUnit): if 0 <= idx < total_bits: field[idx if msb_left else total_bits - 1 - idx] = "1" bstr = "".join(field) - return bstr, bytes(int(bstr[i : i + 8], 2) for i in range(0, total_bits, 8)) + return bstr, bytes(int(bstr[i: i + 8], 2) for i in range(0, total_bits, 8)) def run_senested(self, current_keys_found, max_sectors_num): print( @@ -2690,7 +2694,7 @@ class HFMFFCHK(ReaderRequiredUnit): for i in range(0, len(keys), chunkSize): # print("mask = {}".format(mask.hex(sep=' ', bytes_per_sep=1))) - chunkKeys = keys[i : i + chunkSize] + chunkKeys = keys[i: i + chunkSize] print( f' - progress of checking keys... {color_string((CY, i))} / {len(keys)} ({color_string((CY, f"{100 * i / len(keys):.1f}"))} %)' ) @@ -3113,7 +3117,7 @@ class HFMFClone(MF1AuthArgsUnit): raise Exception(f"No key found for sector {s}") # iterate over blocks for b in range(4): - block_data = buffer[(4 * s + b) * 16 : (4 * s + b + 1) * 16] + block_data = buffer[(4 * s + b) * 16: (4 * s + b + 1) * 16] # special case for last block of each sector if b == 3: # check ACL option @@ -3380,9 +3384,9 @@ _KEY = re.compile("[a-fA-F0-9]{12}", flags=re.MULTILINE) # Sentinel values returned by _run_mfkey64 / _run_mfkey32v2_sniff # to distinguish "tool unavailable" from "tool ran but found no key". -_TOOL_MISSING = "MISSING" # binary not found on disk -_TOOL_BLOCKED = "BLOCKED" # binary exists but OS/AV prevented execution -_TOOL_NO_KEY = "NO_KEY" # binary ran cleanly, no key found for these nonces +_TOOL_MISSING = "MISSING" # binary not found on disk +_TOOL_BLOCKED = "BLOCKED" # binary exists but OS/AV prevented execution +_TOOL_NO_KEY = "NO_KEY" # binary ran cleanly, no key found for these nonces def _sniff_tool_path(name): @@ -3692,7 +3696,7 @@ class HFMFELoad(SlotIndexArgsAndGoUnit, DeviceRequiredUnit): max_blocks = (self.device_com.data_max_length - 1) // 16 while index + 16 < len(buffer): # split a block from buffer - block_data = buffer[index : index + 16 * max_blocks] + block_data = buffer[index: index + 16 * max_blocks] n_blocks = len(block_data) // 16 index += 16 * n_blocks # load to device @@ -3762,7 +3766,7 @@ class HFMFESave(SlotIndexArgsAndGoUnit, DeviceRequiredUnit): with open(file, "wb") as fd: if content_type == "hex": for i in range(len(data) // 16): - fd.write(binascii.hexlify(data[i * 16 : (i + 1) * 16]) + b"\n") + fd.write(binascii.hexlify(data[i * 16: (i + 1) * 16]) + b"\n") else: fd.write(data) print("\n - Read success") @@ -4347,7 +4351,7 @@ class HFMFUELOAD(DeviceRequiredUnit): if offset >= len(data): page_data = bytes.fromhex("00000000") * cur_count else: - page_data = data[offset : offset + 4 * cur_count] + page_data = data[offset: offset + 4 * cur_count] self.cmd.mfu_write_emu_page_data(page, page_data) page += cur_count @@ -4427,7 +4431,7 @@ class HFMFUESAVE(DeviceRequiredUnit): data = self.cmd.mfu_read_emu_page_data(page, cur_count) if save_as_eml: for i in range(0, len(data), 4): - fd.write(data[i : i + 4].hex() + "\n") + fd.write(data[i: i + 4].hex() + "\n") else: fd.write(data) @@ -5268,7 +5272,7 @@ class HFMFUULCG(ReaderRequiredUnit): ][0] full_key = full_key_line.split("Full key (hex): ")[1].strip() key_segment_values[key_segment_idx] = full_key[ - (8 * key_segment_idx) : + (8 * key_segment_idx): ][:8] key_found = True crack_effect.add_cracked_block( @@ -5322,7 +5326,7 @@ class HFMFUULCG(ReaderRequiredUnit): # Write 4 blocks of 4 bytes each for i in range(4): block = 44 + i - data = bytes(key_swapped[i * 4 : (i + 1) * 4]) + data = bytes(key_swapped[i * 4: (i + 1) * 4]) self.write_block(block, data) print("[+] Key restored on the card") @@ -5698,6 +5702,7 @@ class LFHIDProxRead(LFHIDIdReadArgsUnit, ReaderRequiredUnit): print(f" OEM: {color_string((CG, oem))}") print(f" CN: {color_string((CG, cn))}") + @lf_hid_prox.command("write") class LFHIDProxWriteT55xx(LFHIDIdArgsUnit, ReaderRequiredUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -5783,6 +5788,7 @@ class LFHIDProxEconfig(SlotIndexArgsAndGoUnit, LFHIDIdArgsUnit): print(f" OEM: {color_string((CG, oem))}") print(f" CN: {color_string((CG, cn))}") + @lf_ioprox.command("read") class LFIOProxRead(LFIOProxReadArgsUnit, ReaderRequiredUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -5798,6 +5804,7 @@ class LFIOProxRead(LFIOProxReadArgsUnit, ReaderRequiredUnit): print(f" ID: {color_string((CY, cn))}") print(f" Raw: {color_string((CY, raw8.hex().upper()))}") + @lf_ioprox.command("write") class LFIOProxWriteT55xx(LFIOProxIdArgsUnit, ReaderRequiredUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -5808,8 +5815,8 @@ class LFIOProxWriteT55xx(LFIOProxIdArgsUnit, ReaderRequiredUnit): def on_exec(self, args: argparse.Namespace): # defaults ver = args.ver if args.ver is not None else 1 - fc = args.fc if args.fc is not None else 0 - cn = args.cn if args.cn is not None else 0 + fc = args.fc if args.fc is not None else 0 + cn = args.cn if args.cn is not None else 0 # raw8 priority if args.raw8 is not None: @@ -5835,6 +5842,7 @@ class LFIOProxWriteT55xx(LFIOProxIdArgsUnit, ReaderRequiredUnit): print(f" Raw: {color_string((CY, raw8.hex().upper()))}") print("Write done.") + @lf_ioprox.command("econfig") class LFIOProxEconfig(SlotIndexArgsAndGoUnit, LFIOProxIdArgsUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -5857,8 +5865,8 @@ class LFIOProxEconfig(SlotIndexArgsAndGoUnit, LFIOProxIdArgsUnit): # defaults ver = args.ver if args.ver is not None else 1 - fc = args.fc if args.fc is not None else 0 - cn = args.cn if args.cn is not None else 0 + fc = args.fc if args.fc is not None else 0 + cn = args.cn if args.cn is not None else 0 # raw8 priority if args.raw8 is not None: @@ -5893,6 +5901,7 @@ class LFIOProxEconfig(SlotIndexArgsAndGoUnit, LFIOProxIdArgsUnit): print(f" ID: {color_string((CY, cn))}") print(f" Raw: {color_string((CY, raw8.hex().upper()))}") + def pac_encode_raw(card_id: bytes) -> bytes: """Encode 8-byte card ID to 16-byte T55XX bitstream (128 bits). @@ -6033,6 +6042,7 @@ class LFPacIdArgsUnit(DeviceRequiredUnit): def on_exec(self, args: argparse.Namespace): raise NotImplementedError("Please implement this") + @lf_pac.command('write') class LFPacWriteT55xx(LFPacIdArgsUnit, ReaderRequiredUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -6047,6 +6057,7 @@ class LFPacWriteT55xx(LFPacIdArgsUnit, ReaderRequiredUnit): raw = pac_encode_raw(id_bytes) print(f" - PAC/Stanley write done - CN: {id_ascii} | Raw: {raw.hex().upper()}") + @lf_pac.command('econfig') class LFPacEconfig(SlotIndexArgsAndGoUnit, LFPacIdArgsUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -6072,6 +6083,7 @@ class LFPacEconfig(SlotIndexArgsAndGoUnit, LFPacIdArgsUnit): print(' - Get PAC/Stanley tag id success.') print(f'CN: {card_id_ascii} | Raw: {raw.hex().upper()}') + @lf_viking.command("read") class LFVikingRead(ReaderRequiredUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -6220,8 +6232,8 @@ class LFT55xxClone(ReaderRequiredUnit): if args.cn is None: raise ArgsParserError("--cn is required for hid") fmt = HIDFormat[args.format] - fc = args.fc if args.fc is not None else 0 - il = args.il if args.il is not None else 0 + fc = args.fc if args.fc is not None else 0 + il = args.il if args.il is not None else 0 oem = args.oem if args.oem is not None else 0 LFHIDIdArgsUnit.check_limits(fmt.value, fc, args.cn, il, oem) cn = args.cn @@ -6237,15 +6249,18 @@ class LFT55xxClone(ReaderRequiredUnit): self.cmd.hidprox_write_to_t55xx(id_bytes) print(f" - HID Prox cloned to T55xx") print(f" Format : {fmt.name}") - if fc: print(f" FC : {fc}") - if il: print(f" IL : {il}") - if oem: print(f" OEM : {oem}") + if fc: + print(f" FC : {fc}") + if il: + print(f" IL : {il}") + if oem: + print(f" OEM : {oem}") print(f" CN : {cn}") elif t == "ioprox": ver = args.ver if args.ver is not None else 1 - fc = int(args.fc) if args.fc is not None else 0 - cn = args.cn if args.cn is not None else 0 + fc = int(args.fc) if args.fc is not None else 0 + cn = args.cn if args.cn is not None else 0 if args.raw8 is not None: raw8 = LFIOProxIdArgsUnit.parse_raw8(args.raw8) ver, fc, cn, raw8, *_ = self.cmd.ioprox_decode_raw(raw8) @@ -6293,7 +6308,7 @@ class LFADCGenericRead(ReaderRequiredUnit): print(f"generic read data[{len(resp)}]:") width = 50 for i in range(0, len(resp), width): - chunk = resp[i : i + width] + chunk = resp[i: i + width] hexpart = " ".join(f"{b:02x}" for b in chunk) binpart = "".join("1" if b >= 0xBF else "0" for b in chunk) print(f"{i:04x} {hexpart:<{width * 3}} {binpart}") @@ -6509,11 +6524,11 @@ class HWSlotList(DeviceRequiredUnit): print(f" {'OEM:':40}{color_string((CG, oem))}") print(f" {'CN:':40}{color_string((CG, cn))}") if lf_tag_type == TagSpecificType.ioProx: - ver, fc, cn, raw8, *futureuse = self.cmd.ioprox_get_emu_id() + ver, fc, cn, raw8, *futureuse = self.cmd.ioprox_get_emu_id() print(f" {'Version:':40}{color_string((CG, ver))}") print(f" {'Facility:':40}{color_string((CG, f'{fc} [0x{fc:02X}]'))}") print(f" {'ID:':40}{color_string((CY, cn))}") - print(f" {'Raw:':40}{color_string((CY, raw8.hex().upper()))}") + print(f" {'Raw:':40}{color_string((CY, raw8.hex().upper()))}") if lf_tag_type == TagSpecificType.Viking: id = self.cmd.viking_get_emu_id() print(f" {'ID:':40}{color_string((CY, id.hex().upper()))}") @@ -7356,7 +7371,8 @@ class LFEm4x05Read(ReaderRequiredUnit): print(f" Config : {CG}{config:#010x}{C0}") print(f" UID block: {CG}{uid_block}{C0}") if rl: - print(f" Auth : {CG}LOGIN used (pwd={args.pwd.upper() if hasattr(args, 'pwd') and args.pwd else '00000000'}){C0}") + print( + f" Auth : {CG}LOGIN used (pwd={args.pwd.upper() if hasattr(args, 'pwd') and args.pwd else '00000000'}){C0}") if is_em4x69: uid64 = (uid_hi << 32) | uid print(f" UID (64) : {CG}{uid64:016x}{C0}") @@ -7506,9 +7522,9 @@ class HF14ASniff(BaseCLIUnit): frames = [] # (szBits, data, is_tx) i = 0 while i + 2 <= len(buf): - hdr = (buf[i] << 8) | buf[i+1] + hdr = (buf[i] << 8) | buf[i+1] i += 2 - is_tx = bool(hdr & 0x8000) + is_tx = bool(hdr & 0x8000) szBits = hdr & 0x7FFF if szBits == 0: break @@ -7607,8 +7623,6 @@ class HF14ASniff(BaseCLIUnit): _print_14a_sniff_summary(frames) # full frames needed for nonce extraction - - @hf_14a.command("auth-trace") class HF14AAuthTrace(ReaderRequiredUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -7833,9 +7847,6 @@ examples: print(f" {CY}Auth aborted before NR||AR — NT={nt_int:08X}, no further analysis{C0}") - - - def _decode_sw(sw1: int, sw2: int) -> str: """Decode an ISO 7816-4 status word pair.""" exact = { @@ -7873,20 +7884,27 @@ def _decode_sw(sw1: int, sw2: int) -> str: key = (sw1 << 8) | sw2 if key in exact: return exact[key] - if sw1 == 0x61: return f'Response bytes available: {sw2}' - if sw1 == 0x62: return f'Warning — no info change: {sw2:02X}' - if sw1 == 0x63: return f'Warning — state changed: {sw2:02X}' - if sw1 == 0x6C: return f'Wrong Le — use {sw2}' - if sw1 == 0x90: return 'OK' - if sw1 == 0x91: return 'Proprietary OK' + if sw1 == 0x61: + return f'Response bytes available: {sw2}' + if sw1 == 0x62: + return f'Warning — no info change: {sw2:02X}' + if sw1 == 0x63: + return f'Warning — state changed: {sw2:02X}' + if sw1 == 0x6C: + return f'Wrong Le — use {sw2}' + if sw1 == 0x90: + return 'OK' + if sw1 == 0x91: + return 'Proprietary OK' return '' + def _decode_14a_frame_col(data: bytes, szBits: int): """Return (description, colour) for a 14A frame.""" if not data: return '', C0 b0 = data[0] - + # --------------------------------------------------------------------- # ISO14443-A "reply" frames that often show as "unknown" in hf 14a sniff # because the sniffer doesn't know if a frame is reader->card or card->reader. @@ -7934,10 +7952,9 @@ def _decode_14a_frame_col(data: bytes, szBits: int): uid = bytes(data[:4]).hex() return f"ANTICOLL-like: UID={uid} BCC=0x{bcc:02X} (expected 0x{calc:02X})", CY - # Short frames (7-bit) if szBits == 7: - if b0 == 0x26: + if b0 == 0x26: return 'REQA', CG if b0 == 0x52: return 'WUPA', CG @@ -7978,25 +7995,25 @@ def _decode_14a_frame_col(data: bytes, szBits: int): # RATS if b0 == 0xe0: fsdi = (data[1] >> 4) if len(data) > 1 else 0 - cid = (data[1] & 0xf) if len(data) > 1 else 0 + cid = (data[1] & 0xf) if len(data) > 1 else 0 return f'RATS FSDI={fsdi} CID={cid}', CC # MIFARE Classic commands - if b0 == 0x60: + if b0 == 0x60: return f'AUTH KeyA block={data[1]}' if len(data) > 1 else 'AUTH KeyA', CR - if b0 == 0x61: + if b0 == 0x61: return f'AUTH KeyB block={data[1]}' if len(data) > 1 else 'AUTH KeyB', CR # Encrypted nonce / auth response (follows AUTH, first byte varies) - if szBits == 72: + if szBits == 72: return '(encrypted nonce — auth challenge/response)', CC - if b0 == 0x30: + if b0 == 0x30: return f'READ block={data[1]}' if len(data) > 1 else 'READ', CC - if b0 == 0xa0: + if b0 == 0xa0: return f'WRITE block={data[1]}' if len(data) > 1 else 'WRITE', CY - if b0 == 0x40: + if b0 == 0x40: return 'MAGIC WUPC1', CY - if b0 == 0x43: + if b0 == 0x43: return 'MAGIC WUPC2', CY if b0 == 0x41: return 'MAGIC WIPE', CR @@ -8014,13 +8031,13 @@ def _decode_14a_frame_col(data: bytes, szBits: int): aid_raw = bytes(data[5:5+data[4]]) name = _known_aid(aid_raw) label = f'SELECT AID {aid.upper()}' - if name: + if name: label += f' ({name})' return label, CY return 'SELECT', CY # READ BINARY if cla == 0x00 and ins == 0xb0: - return f'READ BINARY off={p1<<8|p2} len={data[4] if len(data)>4 else 0}', CC + return f'READ BINARY off={p1 << 8 | p2} len={data[4] if len(data) > 4 else 0}', CC # READ RECORD if cla == 0x00 and ins == 0xb2: sfi = p2 >> 3 @@ -8035,7 +8052,7 @@ def _decode_14a_frame_col(data: bytes, szBits: int): return 'GPO (Get Processing Options)', CY # GENERATE AC if cla == 0x80 and ins == 0xae: - actype = {0x00:'AAC', 0x40:'TC', 0x80:'ARQC'}.get(p1 & 0xc0, f'AC/{p1:02x}') + actype = {0x00: 'AAC', 0x40: 'TC', 0x80: 'ARQC'}.get(p1 & 0xc0, f'AC/{p1:02x}') return f'GENERATE AC requesting {actype}', CR # VERIFY if cla == 0x00 and ins == 0x20: @@ -8067,8 +8084,6 @@ def _decode_14a_frame_col(data: bytes, szBits: int): return f'unknown (0x{b0:02x})', CC - - def _known_aid(aid: bytes) -> str: table = { bytes.fromhex('a0000000031010'): 'Visa Credit/Debit', @@ -8086,8 +8101,6 @@ def _known_aid(aid: bytes) -> str: return table.get(aid, '') - - def _known_bertag(tag: int) -> str: table = { 0x9f36: 'ATC', @@ -8099,8 +8112,6 @@ def _known_bertag(tag: int) -> str: return table.get(tag, '') - - def _extract_sniff_nonces(frames): """ Extract MIFARE Classic auth nonces from a complete frame list (reader + card). @@ -8115,7 +8126,7 @@ def _extract_sniff_nonces(frames): Returns a list of dicts: { uid, block, key_type, nt, nr, ar } Paired nonces for the same (uid, block, key_type) appear consecutively. """ - nonces = [] + nonces = [] uid_hex = None for i, (szBits, data, is_tx) in enumerate(frames): @@ -8134,7 +8145,7 @@ def _extract_sniff_nonces(frames): # AUTH command: reader→card, 0x60 (KeyA) or 0x61 (KeyB) if not is_tx and data[0] in (0x60, 0x61) and len(data) >= 2: key_type = 'A' if data[0] == 0x60 else 'B' - block = data[1] + block = data[1] # frame i+1: card→reader, exactly 4 bytes = nt (tag nonce) if i + 1 >= len(frames): @@ -8167,18 +8178,18 @@ def _extract_sniff_nonces(frames): def _print_14a_sniff_summary(frames): """Print a decoded summary of the sniff session.""" - uid_cl1 = None - uid_cl2 = None - uid_cl3 = None - aids = [] + uid_cl1 = None + uid_cl2 = None + uid_cl3 = None + aids = [] auth_blocks = [] # (key_type, block) - auth_seen = False - arqc_seen = False - tc_seen = False - halted = False - rats_seen = False - atc_tag = None - amount = None + auth_seen = False + arqc_seen = False + tc_seen = False + halted = False + rats_seen = False + atc_tag = None + amount = None for szBits, data, is_tx in frames: if not data or is_tx: # protocol decode uses reader→card frames only @@ -8216,7 +8227,7 @@ def _print_14a_sniff_summary(frames): aid = bytes(data[5:5+data[4]]) name = _known_aid(aid) entry = aid.hex().upper() - if name: + if name: entry += f' ({name})' if entry not in aids: aids.append(entry) @@ -8233,7 +8244,7 @@ def _print_14a_sniff_summary(frames): if b0 == 0x80 and len(data) > 2 and data[1] == 0xae: if (data[2] & 0xc0) == 0x80: arqc_seen = True - if (data[2] & 0xc0) == 0x40: + if (data[2] & 0xc0) == 0x40: tc_seen = True # GET DATA — ATC @@ -8382,8 +8393,6 @@ def _get_capture(): return _m._last_capture - - @data.command('hexsamples') class DataHexsamples(BaseCLIUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -8408,24 +8417,23 @@ class DataHexsamples(BaseCLIUnit): for b in chunk: if b < 0x10: bar += '_' - elif b < 0x40: + elif b < 0x40: bar += '.' - elif b < 0x80: + elif b < 0x80: bar += '-' - elif b < 0xa0: + elif b < 0xa0: bar += '+' - elif b < 0xc0: + elif b < 0xc0: bar += 'o' - elif b < 0xe0: + elif b < 0xe0: bar += 'O' else: bar += '#' - print(f" {row // 16 :02d} | {hex_part:<47s} | {bar}") + print(f" {row // 16:02d} | {hex_part:<47s} | {bar}") print() print(" _ gap . ringing - low + mid o carrier O high # clipped") - @data.command('plot') class DataPlot(BaseCLIUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -8446,9 +8454,9 @@ class DataPlot(BaseCLIUnit): return start = max(0, args.start) - end = min(len(buf), start + args.len) - view = list(buf[start:end]) - n = len(view) + end = min(len(buf), start + args.len) + view = list(buf[start:end]) + n = len(view) # X axis: time in µs (1 sample = 8µs) xs = [((start + i) * 8) for i in range(n)] @@ -8494,15 +8502,13 @@ class DataPlot(BaseCLIUnit): print(f" Samples {start}–{end} range 0x{mn:02x}–0x{mx:02x} mean 0x{mean:02x}") print() levels = [0xe0, 0xc0, 0xa0, 0x80, 0x60, 0x40, 0x20, 0x00] - labels = ['0xff','0xc0','0xa0','0x80','0x60','0x40','0x20','0x00'] + labels = ['0xff', '0xc0', '0xa0', '0x80', '0x60', '0x40', '0x20', '0x00'] for thresh, lbl in zip(levels, labels): row = ''.join('#' if v >= thresh else ' ' for v in buckets) print(f" {lbl} |{row}|") print(f" +{'-'*len(buckets)}+") - - def _plot_matplotlib(xs, ys, mean, threshold, start, end): import matplotlib.pyplot as plt import matplotlib.patches as mpatches @@ -8554,8 +8560,6 @@ def _plot_matplotlib(xs, ys, mean, threshold, start, end): plt.show() - - def _plot_pyqtgraph(xs, ys, mean, threshold, start, end): import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QLabel @@ -8590,8 +8594,8 @@ def _plot_pyqtgraph(xs, ys, mean, threshold, start, end): for i in range(len(ys)-1): if ys[i] < threshold: r = pg.LinearRegionItem([xs[i], xs[i+1]], - brush=pg.mkBrush(255, 61, 87, 40), - pen=pg.mkPen(None), movable=False) + brush=pg.mkBrush(255, 61, 87, 40), + pen=pg.mkPen(None), movable=False) plot.addItem(r) # Legend / info panel @@ -8612,8 +8616,6 @@ def _plot_pyqtgraph(xs, ys, mean, threshold, start, end): app.exec_() - - @data.command('manrawdecode') class DataManrawdecode(BaseCLIUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -8689,7 +8691,7 @@ class DataManrawdecode(BaseCLIUnit): return bits_str = ''.join(str(b) for b in decoded_bits) - hex_str = hex(int(bits_str, 2))[2:] if decoded_bits else '' + hex_str = hex(int(bits_str, 2))[2:] if decoded_bits else '' print(f" Clock : RF/{args.clock} ({args.clock} Tc = {args.clock*8}µs/bit)") print(f" Threshold: 0x{threshold:02x} Inverted: {args.invert}") @@ -8703,8 +8705,6 @@ class DataManrawdecode(BaseCLIUnit): print(f" Hex: {CG}{hex_str[:64]}{C0}{'...' if len(hex_str) > 64 else ''}") - - @data.command('modulation') class DataModulation(BaseCLIUnit): def args_parser(self) -> ArgumentParserNoExit: @@ -8720,8 +8720,8 @@ class DataModulation(BaseCLIUnit): n = len(buf) mean = sum(buf) // n - mn = min(buf) - mx = max(buf) + mn = min(buf) + mx = max(buf) threshold = mean // 2 print(f" Samples : {CG}{n}{C0} ({n*8}µs)") @@ -8811,7 +8811,6 @@ class DataModulation(BaseCLIUnit): gap_threshold = mean // 2 gaps = [i for i, b in enumerate(buf[200:]) if b < gap_threshold] - if gaps: print(f" RTF gaps : {CG}{len(gaps)}{C0} samples below 0x{gap_threshold:02x}" f" ^`^t gap commands present") @@ -8865,13 +8864,14 @@ class EMVScan(DeviceRequiredUnit): parser = ArgumentParserNoExit() parser.description = 'EMV contactless card scan (reader mode) — like PM3 emv scan -at' parser.add_argument('-f', '--file', default='', metavar='', - help='Save results to JSON file (PM3-compatible format)') + help='Save results to JSON file (PM3-compatible format)') parser.add_argument('-s', '--slot', type=int, default=None, - metavar='<1-8>', help='Also load scanned card into this slot for emulation') + metavar='<1-8>', help='Also load scanned card into this slot for emulation') return parser def on_exec(self, args: argparse.Namespace): - import time, json as jsonlib + import time + import json as jsonlib cmd = self.cmd # Ensure reader mode @@ -8894,27 +8894,38 @@ class EMVScan(DeviceRequiredUnit): d = bytes(resp.data) off = 0 - uid_len = d[off]; off += 1 - uid = d[off:off+uid_len]; off += uid_len - atqa = d[off:off+2]; off += 2 - sak = d[off]; off += 1 - ats_len = d[off]; off += 1 - ats = d[off:off+ats_len]; off += ats_len + uid_len = d[off] + off += 1 + uid = d[off:off+uid_len] + off += uid_len + atqa = d[off:off+2] + off += 2 + sak = d[off] + off += 1 + ats_len = d[off] + off += 1 + ats = d[off:off+ats_len] + off += ats_len - uid_str = ' '.join(f'{b:02X}' for b in uid) + uid_str = ' '.join(f'{b:02X}' for b in uid) atqa_str = ' '.join(f'{b:02X}' for b in atqa) - ats_str = ' '.join(f'{b:02X}' for b in ats) + ats_str = ' '.join(f'{b:02X}' for b in ats) print(f' {CG}UID : {uid_str}{C0}') print(f' {CG}ATQA: {atqa_str} SAK: {sak:02X}{C0}') print(f' {CG}ATS : {ats_str}{C0}') - num_apdus = d[off]; off += 1 + num_apdus = d[off] + off += 1 pairs = [] for _ in range(num_apdus): - cl = d[off]; off += 1 - c = d[off:off+cl]; off += cl - rl = d[off] | (d[off+1] << 8); off += 2 - r = d[off:off+rl]; off += rl + cl = d[off] + off += 1 + c = d[off:off+cl] + off += cl + rl = d[off] | (d[off+1] << 8) + off += 2 + r = d[off:off+rl] + off += rl pairs.append((c, r)) if not pairs: @@ -8929,35 +8940,51 @@ class EMVScan(DeviceRequiredUnit): }} def tlv_to_dict(data): - if not data: return {} + if not data: + return {} i = 0 tl = 2 if (data[i] & 0x1F) == 0x1F else 1 - tag_hex = data[:tl].hex().upper(); i += tl - if i >= len(data): return {} + tag_hex = data[:tl].hex().upper() + i += tl + if i >= len(data): + return {} if data[i] & 0x80: - nb = data[i] & 0x7F; i += 1 - vlen = int.from_bytes(data[i:i+nb], 'big'); i += nb + nb = data[i] & 0x7F + i += 1 + vlen = int.from_bytes(data[i:i+nb], 'big') + i += nb else: - vlen = data[i]; i += 1 + vlen = data[i] + i += 1 val = data[i:i+vlen] return {'tag': tag_hex, 'length': f'{vlen:02X}', 'value': ' '.join(f'{b:02X}' for b in val)} def find_tag(data, tag): - results = []; i = 0 + results = [] + i = 0 while i < len(data) - 1: tl = 2 if (data[i] & 0x1F) == 0x1F else 1 - if i + tl > len(data): break - cur = data[i:i+tl]; i += tl - if i >= len(data): break + if i + tl > len(data): + break + cur = data[i:i+tl] + i += tl + if i >= len(data): + break if data[i] & 0x80: - nb = data[i] & 0x7F; i += 1 - vlen = int.from_bytes(data[i:i+nb], 'big'); i += nb + nb = data[i] & 0x7F + i += 1 + vlen = int.from_bytes(data[i:i+nb], 'big') + i += nb else: - vlen = data[i]; i += 1 - val = data[i:i+vlen]; i += vlen - if int.from_bytes(cur, 'big') == tag: results.append(val) - elif cur[0] & 0x20: results.extend(find_tag(val, tag)) + vlen = data[i] + i += 1 + val = data[i:i+vlen] + i += vlen + if int.from_bytes(cur, 'big') == tag: + results.append(val) + elif cur[0] & 0x20: + results.extend(find_tag(val, tag)) return results # PPSE @@ -8977,7 +9004,7 @@ class EMVScan(DeviceRequiredUnit): aid_str = ' '.join(f'{b:02X}' for b in aid_bytes) print(f' {CG}SELECT AID OK ({len(sel_resp)}b){C0}') result['Application'] = {'AID': aid_str, - 'FCITemplate': tlv_to_dict(sel_body)} + 'FCITemplate': tlv_to_dict(sel_body)} if len(pairs) >= 3: gpo_cmd, gpo_resp = pairs[2] @@ -8991,7 +9018,7 @@ class EMVScan(DeviceRequiredUnit): r_body = rb[:-2] if len(rb) >= 2 else rb print(f' {CG}READ RECORD SFI={sfi_n} rec={rec_n} OK ({len(rb)}b){C0}') records.append({'SFI': f'{sfi_n:02X}', 'RecordNum': f'{rec_n:02X}', - 'Offline': '01', 'Data': tlv_to_dict(r_body)}) + 'Offline': '01', 'Data': tlv_to_dict(r_body)}) result['Application']['Records'] = records # ---- Decode and display key card fields from EMV records -------- @@ -9017,15 +9044,19 @@ class EMVScan(DeviceRequiredUnit): if i >= len(data): break if data[i] & 0x80: - nb = data[i] & 0x7F; i += 1 - vlen = int.from_bytes(data[i:i+nb], 'big'); i += nb + nb = data[i] & 0x7F + i += 1 + vlen = int.from_bytes(data[i:i+nb], 'big') + i += nb else: - vlen = data[i]; i += 1 - val = data[i:i+vlen]; i += vlen + vlen = data[i] + i += 1 + val = data[i:i+vlen] + i += vlen if cur_tag in results: results[cur_tag].append(val) # recurse into constructed TLV - if data[i - vlen - (1 if vlen < 128 else 2)] & 0x20 if False else (data[i - vlen - 1] & 0x20 if vlen < 128 else False): + if data[i - vlen - (1 if vlen < 128 else 2)] & 0x20 if False else (data[i - vlen - 1] & 0x20 if vlen < 128 else False): sub = _find_tag_all(val, *tags) for t in tags: results[t].extend(sub[t]) @@ -9048,12 +9079,15 @@ class EMVScan(DeviceRequiredUnit): break constructed = bool(b0 & 0x20) if data[i] & 0x80: - nb = data[i] & 0x7F; i += 1 + nb = data[i] & 0x7F + i += 1 if i + nb > len(data): break - vlen = int.from_bytes(data[i:i+nb], 'big'); i += nb + vlen = int.from_bytes(data[i:i+nb], 'big') + i += nb else: - vlen = data[i]; i += 1 + vlen = data[i] + i += 1 # For truncated TLV: read whatever bytes are available and # continue parsing — don't break, so we can find tags inside # truncated constructed TLV (e.g. 6F/A5 larger than received data) @@ -9100,7 +9134,7 @@ class EMVScan(DeviceRequiredUnit): tags = tlv_find(all_record_data, 0x5A, 0x57, 0x5F24, 0x5F20, 0x5F28) app_tags = tlv_find(all_search_data, 0x9F12, 0x50) tags[0x9F12] = app_tags[0x9F12] - tags[0x50] = app_tags[0x50] + tags[0x50] = app_tags[0x50] print(f'') print(f' {CG}── Card Details ──────────────────────{C0}') @@ -9194,7 +9228,8 @@ class EMVScan(DeviceRequiredUnit): json_str = jsonlib.dumps(result, indent=2) if args.file: try: - with open(args.file, 'w') as fp: fp.write(json_str) + with open(args.file, 'w') as fp: + fp.write(json_str) print(f'\n {CG}Saved to {args.file}{C0}') except Exception as e: print(f' {CR}Save failed: {e}{C0}') @@ -9236,7 +9271,8 @@ class EMVDebug(DeviceRequiredUnit): print(f' {CY}T=CL debug counters:{C0}') print(f' I-blocks received : {d[0]}') print(f' I-blocks sent : {d[1]}') - print(f' Last rx PCB : {d[2]:02x} (blk_num={(d[2] & 0x01)}, chain={(d[2]>>5)&1}, cid={(d[2]>>4)&1})') + print( + f' Last rx PCB : {d[2]:02x} (blk_num={(d[2] & 0x01)}, chain={(d[2] >> 5) & 1}, cid={(d[2] >> 4) & 1})') print(f' Last static match : {"yes" if d[3] else "no"}') @@ -9260,17 +9296,17 @@ class EMVLoad(DeviceRequiredUnit): parser = ArgumentParserNoExit() parser.description = 'Load EMV APDU responses into HF14A_4 slot for autonomous emulation' parser.add_argument('-f', '--file', default='', metavar='', - help='Load from PM3 emv scan JSON file') + help='Load from PM3 emv scan JSON file') parser.add_argument('-s', '--slot', type=int, default=None, - metavar='<1-8>', help='Target slot when using --file (default: active)') + metavar='<1-8>', help='Target slot when using --file (default: active)') parser.add_argument('--clear', action='store_true', - help='Clear all static responses from active slot') + help='Clear all static responses from active slot') parser.add_argument('--cmd', default='', metavar='', - help='Command APDU prefix to match (hex)') + help='Command APDU prefix to match (hex)') parser.add_argument('--resp', default='', metavar='', - help='Response APDU to return (hex)') + help='Response APDU to return (hex)') parser.add_argument('--defaults', action='store_true', - help='Load built-in Mastercard test responses') + help='Load built-in Mastercard test responses') return parser def on_exec(self, args: argparse.Namespace): @@ -9343,7 +9379,8 @@ class EMVLoad(DeviceRequiredUnit): def _load_from_json(self, filepath, target_slot, cmd): """Load card data from a PM3 emv scan JSON file.""" - import json as jsonlib, os + import json as jsonlib + import os if not os.path.exists(filepath): print(f' {CR}File not found: {filepath}{C0}') return @@ -9356,12 +9393,12 @@ class EMVLoad(DeviceRequiredUnit): # Parse card info try: - card = data['Card']['Contactless'] - uid = bytes.fromhex(card['UID'].replace(' ', '')) - atqa = bytes.fromhex(card['ATQA'].replace(' ', '')) - sak = int(card['SAK'], 16) + card = data['Card']['Contactless'] + uid = bytes.fromhex(card['UID'].replace(' ', '')) + atqa = bytes.fromhex(card['ATQA'].replace(' ', '')) + sak = int(card['SAK'], 16) ats_raw = bytes.fromhex(card['ATS'].replace(' ', '')) - ats = ats_raw[:ats_raw[0]] if ats_raw else b'' + ats = ats_raw[:ats_raw[0]] if ats_raw else b'' except Exception as e: print(f' {CR}Card info parse error: {e}{C0}') return @@ -9416,12 +9453,12 @@ class EMVLoad(DeviceRequiredUnit): try: for rec in data['Application'].get('Records', []): - sfi_n = int(rec['SFI'], 16) - rec_n = int(rec['RecordNum'], 16) - v = rec['Data']['value'].replace(' ', '') - l = rec['Data']['length'] - tag = rec['Data'].get('tag', '70') - p2 = (sfi_n << 3) | 4 + sfi_n = int(rec['SFI'], 16) + rec_n = int(rec['RecordNum'], 16) + v = rec['Data']['value'].replace(' ', '') + l = rec['Data']['length'] + tag = rec['Data'].get('tag', '70') + p2 = (sfi_n << 3) | 4 static_pairs.append(( bytes([0x00, 0xB2, rec_n, p2, 0x00]), tlv_resp(tag, l, v), @@ -9471,7 +9508,7 @@ class EMVApdu(DeviceRequiredUnit): parser = ArgumentParserNoExit() parser.description = 'ISO14443-4 T=CL interactive APDU relay (manual response mode)' parser.add_argument('--timeout', type=int, default=15000, metavar='', - help='Total relay timeout in ms (default: 15000)') + help='Total relay timeout in ms (default: 15000)') return parser def on_exec(self, args: argparse.Namespace): diff --git a/software/script/chameleon_cmd.py b/software/script/chameleon_cmd.py index 7a3dd2d6..faf9d18a 100644 --- a/software/script/chameleon_cmd.py +++ b/software/script/chameleon_cmd.py @@ -13,6 +13,7 @@ CURRENT_VERSION_SETTINGS = 6 new_key = b'\x20\x20\x66\x66' old_keys = [b'\x51\x24\x36\x48', b'\x19\x92\x04\x27'] + class ChameleonCMD: """ Chameleon cmd function @@ -248,7 +249,8 @@ class ChameleonCMD: offset = 0 data = [] while offset < len(resp.data): - uidlen, = struct.unpack_from('!B', resp.data, offset); offset += 1 + uidlen, = struct.unpack_from('!B', resp.data, offset) + offset += 1 uid, atqa, sak, atslen = struct.unpack_from( f'!{uidlen}s2s1sB', resp.data, offset) offset += struct.calcsize(f'!{uidlen}s2s1sB') @@ -295,7 +297,8 @@ class ChameleonCMD: an APDU whose first len(cmd) bytes match cmd, without USB involvement. Must be called before hw mode -e. """ - rlen = len(resp); payload = bytes([len(cmd)]) + bytes(cmd) + bytes([(rlen >> 8) & 0xFF, rlen & 0xFF]) + bytes(resp) + rlen = len(resp) + payload = bytes([len(cmd)]) + bytes(cmd) + bytes([(rlen >> 8) & 0xFF, rlen & 0xFF]) + bytes(resp) return self.device.send_cmd_sync(Command.HF14A_4_STATIC_RESP, payload) def hf14a_4_reader_apdu(self, apdu: bytes): @@ -608,7 +611,7 @@ class ChameleonCMD: fmt = '!H13s' else: fmt = '!H5s' - resp.parsed = struct.unpack(fmt, resp.data[:struct.calcsize(fmt)]) # tag type + uid + resp.parsed = struct.unpack(fmt, resp.data[:struct.calcsize(fmt)]) # tag type + uid return resp @expect_response(Status.LF_TAG_OK) @@ -659,9 +662,9 @@ class ChameleonCMD: """ resp = self.device.send_cmd_sync(Command.IOPROX_SCAN) if resp.status == Status.LF_TAG_OK: - resp.parsed = struct.unpack(">BBH8sBBBB", resp.data[:16]) + resp.parsed = struct.unpack(">BBH8sBBBB", resp.data[:16]) return resp - + @expect_response(Status.LF_TAG_OK) def ioprox_write_to_t55xx(self, id_bytes: bytes): """ @@ -674,7 +677,7 @@ class ChameleonCMD: fmt = f'!16s4s{4 * len(old_keys)}s' data = struct.pack(fmt, id_bytes, new_key, b''.join(old_keys)) return self.device.send_cmd_sync(Command.IOPROX_WRITE_TO_T55XX, data) - + @expect_response(Status.SUCCESS) def ioprox_decode_raw(self, raw8_bytes): """ @@ -698,9 +701,6 @@ class ChameleonCMD: resp.parsed = struct.unpack(">BBH8sBBBB", resp.data[:16]) return resp - - - def lf_sniff(self, timeout_ms: int = 2000): """ Capture raw LF field ADC samples. @@ -716,8 +716,6 @@ class ChameleonCMD: timeout_s = (timeout_ms // 1000) + 2 return self.device.send_cmd_sync(Command.LF_SNIFF, payload, timeout=timeout_s) - - @expect_response(Status.LF_TAG_OK) def em4x05_scan(self, pwd: int = 0): """ @@ -739,8 +737,6 @@ class ChameleonCMD: resp.parsed = struct.unpack('!IIIBB', resp.data[:14]) return resp - - @expect_response(Status.LF_TAG_OK) def viking_scan(self): """ @@ -750,7 +746,7 @@ class ChameleonCMD: """ resp = self.device.send_cmd_sync(Command.VIKING_SCAN) if resp.status == Status.LF_TAG_OK: - resp.parsed = resp.data # uid + resp.parsed = resp.data # uid return resp @expect_response(Status.LF_TAG_OK) @@ -979,7 +975,7 @@ class ChameleonCMD: if resp.status == Status.SUCCESS: resp.parsed = struct.unpack('>BIBIBH', resp.data[:13]) return resp - + @expect_response(Status.SUCCESS) def ioprox_set_emu_id(self, id: bytes): """ @@ -997,9 +993,9 @@ class ChameleonCMD: """ Get the emulated ioProx card id """ - resp = self.device.send_cmd_sync(Command.IOPROX_GET_EMU_ID) + resp = self.device.send_cmd_sync(Command.IOPROX_GET_EMU_ID) if resp.status == Status.SUCCESS: - resp.parsed = struct.unpack(">BBH8sBBBB", resp.data[:16]) + resp.parsed = struct.unpack(">BBH8sBBBB", resp.data[:16]) return resp @expect_response(Status.SUCCESS) @@ -1733,7 +1729,7 @@ class ChameleonCMD: def set_ble_pairing_enable(self, enabled: bool): data = struct.pack('!B', enabled) return self.device.send_cmd_sync(Command.SET_BLE_PAIRING_ENABLE, data) - + @expect_response(Status.SUCCESS) def mf1_get_field_off_do_reset(self): resp = self.device.send_cmd_sync(Command.MF1_GET_FIELD_OFF_DO_RESET) diff --git a/software/script/chameleon_com.py b/software/script/chameleon_com.py index 6940f552..09a2cb17 100644 --- a/software/script/chameleon_com.py +++ b/software/script/chameleon_com.py @@ -20,11 +20,13 @@ THREAD_BLOCKING_TIMEOUT = 0.1 # TODO: client settings DEBUG = False + class TransportType(Enum): NONE = auto() SERIAL = auto() SOCKET = auto() + class NotOpenException(Exception): """ Chameleon err status @@ -104,7 +106,8 @@ class ChameleonCom: self.transport_type = TransportType.SOCKET else: if ANDROID: - sys.exit(color_string(CR, 'COM port is not supported on Android, make a USB-serial to TCP communication bridge')) + sys.exit(color_string( + CR, 'COM port is not supported on Android, make a USB-serial to TCP communication bridge')) self.transport = serial.Serial(port=port, baudrate=115200) self.transport_type = TransportType.SERIAL except Exception as e: @@ -262,7 +265,8 @@ class ChameleonCom: except ValueError: status_string = f"{data_status:30x}" response = data_response.hex() if data_response is not None else "" - print(f"<={color_string((CC, command_string.ljust(40)), (CR, status_string), (CY, response))}") + print( + f"<={color_string((CC, command_string.ljust(40)), (CR, status_string), (CY, response))}") if data_cmd in self.wait_response_map: # call processor if 'callback' in self.wait_response_map[data_cmd]: diff --git a/software/script/chameleon_enum.py b/software/script/chameleon_enum.py index 7c4e7bc0..115c79ce 100644 --- a/software/script/chameleon_enum.py +++ b/software/script/chameleon_enum.py @@ -600,12 +600,14 @@ class ButtonPressFunction(enum.IntEnum): return "Toggle NFC Field Generator" return "None" + @enum.unique class MfcValueBlockOperator(enum.IntEnum): DECREMENT = 0xC0 INCREMENT = 0xC1 RESTORE = 0xC2 + @enum.unique class HIDFormat(enum.IntEnum): H10301 = 1 diff --git a/software/script/chameleon_utils.py b/software/script/chameleon_utils.py index 0577c1a2..ef338de9 100644 --- a/software/script/chameleon_utils.py +++ b/software/script/chameleon_utils.py @@ -64,67 +64,69 @@ class ArgumentParserNoExit(argparse.ArgumentParser): args = {'prog': self.prog, 'message': message} raise ArgsParserError('%(prog)s: error: %(message)s\n' % args) + def print_help(self): - """ - Colorize argparse help - """ - print("-" * 80) - print(color_string((CR, self.prog))) - - # Get the help text and split it, filtering out leading empty lines - raw_lines = self.format_help().splitlines() - lines = [line for line in raw_lines if line.strip() or line == ''] - - # Find the usage block safely - usage_start = -1 - for i, line in enumerate(lines): - if line.strip().startswith('usage:'): - usage_start = i - break - - if usage_start != -1: - # We found a usage line, extract the block until the first empty line - try: - empty_after_usage = lines.index('', usage_start) - usage = lines[usage_start:empty_after_usage] - - # Apply coloring to the usage string - usage[0] = usage[0].replace('usage:', f'{color_string((CG, "usage:"))}\n ') - usage[0] = usage[0].replace(self.prog, color_string((CR, self.prog))) - - # Reformat indentation and print - usage_to_print = [usage[0]] + [x[4:] for x in usage[1:]] + [''] - print('\n'.join(usage_to_print)) - - # Advance lines pointer to after the usage block - lines = lines[empty_after_usage + 1:] - except ValueError: - # If no empty line found, just print what we have - print('\n'.join(lines[usage_start:])) - lines = [] - - # Print description if available - if lines and lines[0].strip() != '': - try: - desc_end = lines.index('') - desc = lines[:desc_end] - print(color_string((CC, "\n".join(desc)))) - lines = lines[desc_end + 1:] - except ValueError: - pass + """ + Colorize argparse help + """ + print("-" * 80) + print(color_string((CR, self.prog))) - # Handle options and positional arguments without crashing on strict matches - for line in lines: - clean_line = line.strip().lower() - if clean_line == 'positional arguments:': - print(color_string((CG, line))) - elif clean_line in ['options:', 'optional arguments:']: - print(color_string((CG, line))) - else: - print(line) + # Get the help text and split it, filtering out leading empty lines + raw_lines = self.format_help().splitlines() + lines = [line for line in raw_lines if line.strip() or line == ''] + + # Find the usage block safely + usage_start = -1 + for i, line in enumerate(lines): + if line.strip().startswith('usage:'): + usage_start = i + break + + if usage_start != -1: + # We found a usage line, extract the block until the first empty line + try: + empty_after_usage = lines.index('', usage_start) + usage = lines[usage_start:empty_after_usage] + + # Apply coloring to the usage string + usage[0] = usage[0].replace('usage:', f'{color_string((CG, "usage:"))}\n ') + usage[0] = usage[0].replace(self.prog, color_string((CR, self.prog))) + + # Reformat indentation and print + usage_to_print = [usage[0]] + [x[4:] for x in usage[1:]] + [''] + print('\n'.join(usage_to_print)) + + # Advance lines pointer to after the usage block + lines = lines[empty_after_usage + 1:] + except ValueError: + # If no empty line found, just print what we have + print('\n'.join(lines[usage_start:])) + lines = [] + + # Print description if available + if lines and lines[0].strip() != '': + try: + desc_end = lines.index('') + desc = lines[:desc_end] + print(color_string((CC, "\n".join(desc)))) + lines = lines[desc_end + 1:] + except ValueError: + pass + + # Handle options and positional arguments without crashing on strict matches + for line in lines: + clean_line = line.strip().lower() + if clean_line == 'positional arguments:': + print(color_string((CG, line))) + elif clean_line in ['options:', 'optional arguments:']: + print(color_string((CG, line))) + else: + print(line) + + print('') + self.help_requested = True - print('') - self.help_requested = True def print_mem_dump(bindata, blocksize): diff --git a/software/script/crypto1.py b/software/script/crypto1.py index a0005a06..ea675930 100644 --- a/software/script/crypto1.py +++ b/software/script/crypto1.py @@ -7,43 +7,55 @@ LFSR48_POLY = 0xE882B0AD621 U8_TO_ODD4 = [((i & 0x80) >> 4) + ((i & 0x20) >> 3) + ((i & 0x08) >> 2) + ((i & 0x02) >> 1) for i in range(256)] EVEN_PARITY_U8 = [0 for i in range(256)] + def u8_to_odd4(u8): return U8_TO_ODD4[u8 & 0xFF] -def get_bit(num, x = 0): + +def get_bit(num, x=0): return (num >> x) & 1 + for i in range(256): tmp = i tmp ^= tmp >> 4 tmp ^= tmp >> 2 EVEN_PARITY_U8[i] = (tmp ^ (tmp >> 1)) & 1 + def even_parity_u8(u8): return EVEN_PARITY_U8[u8 & 0xFF] + def odd_parity_u8(u8): return even_parity_u8(u8) ^ 1 + def even_parity_u16(u16): return even_parity_u8((u16 >> 8) ^ u16) + def even_parity_u48(u48): return even_parity_u16((u48 >> 32) ^ (u48 >> 16) ^ u48) + def swap_endian_u16(u16): return ((u16 & 0xFF) << 8) | ((u16 >> 8) & 0xFF) + def swap_endian_u32(u32): return swap_endian_u16(u32 & 0xFFFF) << 16 | swap_endian_u16((u32 >> 16) & 0xFFFF) + """ ref: https://web.archive.org/web/20081010065744/http://sar.informatik.hu-berlin.de/research/publications/SAR-PR-2008-21/SAR-PR-2008-21_.pdf """ + + class Crypto1: def __init__(self, new_lfsr48: int = 0): self.lfsr48 = new_lfsr48 - + @property def key(self) -> bytearray: tmp, key = self.lfsr48, bytearray(6) @@ -51,7 +63,7 @@ class Crypto1: key[i] = tmp & 0xFF tmp >>= 8 return key.hex() - + @key.setter def key(self, key: str): if not re.match(r"^[a-fA-F0-9]{12}$", key): @@ -63,11 +75,11 @@ class Crypto1: def lfsr48_filter(self): f = 0 - f |= get_bit(LFSR48_FILTER_B, u8_to_odd4(self.lfsr48 >> 8)) # fb4 - f |= get_bit(LFSR48_FILTER_A, u8_to_odd4(self.lfsr48 >> 16)) << 1 # fa4 - f |= get_bit(LFSR48_FILTER_A, u8_to_odd4(self.lfsr48 >> 24)) << 2 # fa4 - f |= get_bit(LFSR48_FILTER_B, u8_to_odd4(self.lfsr48 >> 32)) << 3 # fb4 - f |= get_bit(LFSR48_FILTER_A, u8_to_odd4(self.lfsr48 >> 40)) << 4 # fa4 + f |= get_bit(LFSR48_FILTER_B, u8_to_odd4(self.lfsr48 >> 8)) # fb4 + f |= get_bit(LFSR48_FILTER_A, u8_to_odd4(self.lfsr48 >> 16)) << 1 # fa4 + f |= get_bit(LFSR48_FILTER_A, u8_to_odd4(self.lfsr48 >> 24)) << 2 # fa4 + f |= get_bit(LFSR48_FILTER_B, u8_to_odd4(self.lfsr48 >> 32)) << 3 # fb4 + f |= get_bit(LFSR48_FILTER_A, u8_to_odd4(self.lfsr48 >> 40)) << 4 # fa4 return get_bit(LFSR48_FILTER_C, f) def lfsr48_bit(self, bit_in: int = 0, is_encrypted: bool = False) -> int: @@ -75,36 +87,36 @@ class Crypto1: bit_feedback = even_parity_u48(LFSR48_POLY & self.lfsr48) ^ (bit_in & 1) ^ (is_encrypted & out_bit) self.lfsr48 = (bit_feedback << 47) | (self.lfsr48 >> 1) return out_bit - + def lfsr48_u8(self, u8_in: int = 0, is_encrypted: bool = False) -> int: out_u8 = 0 for i in range(8): tmp = self.lfsr48_bit(u8_in >> i, is_encrypted) << i out_u8 |= tmp return out_u8 - + def lfsr48_u32(self, u32_in: int = 0, is_encrypted: bool = False) -> int: out_u32 = 0 for i in range(3, -1, -1): bit_offset = i << 3 out_u32 |= self.lfsr48_u8(u32_in >> bit_offset, is_encrypted) << bit_offset return out_u32 - + @staticmethod def prng_next(lfsr32: int, n: int = 1) -> int: lfsr32 = swap_endian_u32(lfsr32) for i in range(n): lfsr32 = even_parity_u8(0x2D & (lfsr32 >> 16)) << 31 | (lfsr32 >> 1) return swap_endian_u32(lfsr32) - + @staticmethod def mfkey32_is_reader_has_key(uid: int, nt: int, nrEnc: int, arEnc: int, key: str) -> bool: state = Crypto1() state.key = key - state.lfsr48_u32(uid ^ nt, False) # ks0 - state.lfsr48_u32(nrEnc, True) # ks1 - ks2 = state.lfsr48_u32(0, False) # ks2 + state.lfsr48_u32(uid ^ nt, False) # ks0 + state.lfsr48_u32(nrEnc, True) # ks1 + ks2 = state.lfsr48_u32(0, False) # ks2 ar = arEnc ^ ks2 result = ar == Crypto1.prng_next(nt, 64) # print(f'uid: {hex(uid)}, nt: {hex(nt)}, nrEnc: {hex(nrEnc)}, arEnc: {hex(arEnc)}, key: {key}, result = {result}') - return result \ No newline at end of file + return result diff --git a/software/script/tests/test_crypto1.py b/software/script/tests/test_crypto1.py index bae62aca..4611f690 100644 --- a/software/script/tests/test_crypto1.py +++ b/software/script/tests/test_crypto1.py @@ -9,6 +9,7 @@ config_path = CURRENT_DIR.rsplit(os.sep, 1)[0] sys.path.append(config_path) print(config_path) + class TestCrypto1(unittest.TestCase): def test_key_getter_setter(self): @@ -64,21 +65,22 @@ class TestCrypto1(unittest.TestCase): def test_mfkey32_is_reader_has_key_true(self): self.assertTrue(Crypto1.mfkey32_is_reader_has_key( - uid = 0x65535D33, - nt = 0x2C198BE4, - nrEnc = 0xFEDAC6D2, - arEnc = 0xCF0A3C7E, - key = 'A9AC67832330' - )) - - def test_mfkey32_is_reader_has_key_false(self): - self.assertFalse(Crypto1.mfkey32_is_reader_has_key( - uid = 0x65535D33, - nt = 0x2C198BE4, - nrEnc = 0xFEDAC6D2, - arEnc = 0xCF0A3C7E, - key = 'FFFFFFFFFFFF' + uid=0x65535D33, + nt=0x2C198BE4, + nrEnc=0xFEDAC6D2, + arEnc=0xCF0A3C7E, + key='A9AC67832330' )) + def test_mfkey32_is_reader_has_key_false(self): + self.assertFalse(Crypto1.mfkey32_is_reader_has_key( + uid=0x65535D33, + nt=0x2C198BE4, + nrEnc=0xFEDAC6D2, + arEnc=0xCF0A3C7E, + key='FFFFFFFFFFFF' + )) + + if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/software/src/HardnestedRecovery/cmdhfmfhard.c b/software/src/HardnestedRecovery/cmdhfmfhard.c index 0350e9cf..484de9cf 100755 --- a/software/src/HardnestedRecovery/cmdhfmfhard.c +++ b/software/src/HardnestedRecovery/cmdhfmfhard.c @@ -249,7 +249,7 @@ static int compare_count_bitflip_bitarrays(const void *b1, const void *b2) { static void init_bitflip_bitarrays(void) { - // z_stream compressed_stream; + // z_stream compressed_stream; lzma_stream strm = LZMA_STREAM_INIT; for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { diff --git a/software/src/mfulc_des_brute.c b/software/src/mfulc_des_brute.c index 1357c106..23aaf19b 100644 --- a/software/src/mfulc_des_brute.c +++ b/software/src/mfulc_des_brute.c @@ -231,13 +231,13 @@ static void *worker(void *arg) { static void print_help_and_exit(const char *cmd_name) { fprintf(stderr, - "Usage:\n" - " * Counterfeit key recovery:\n" - " %s -c <3DES base key hex (32 hex digits)> \n" - " * Reader nonce key recovery:\n" - " %s -r <3DES base key hex (32 hex digits)> \n", - cmd_name, - cmd_name); + "Usage:\n" + " * Counterfeit key recovery:\n" + " %s -c <3DES base key hex (32 hex digits)> \n" + " * Reader nonce key recovery:\n" + " %s -r <3DES base key hex (32 hex digits)> \n", + cmd_name, + cmd_name); exit(1); }