static bool parse_card() { e.logcount = 0; e.current_tran = 0; int32_t iBlock; bool bFailure = false; //printf("Reading out %d blocks\n", uiBlocks + 1); // Read the card from end to begin for (iBlock = uiBlocks; iBlock >= 0; iBlock--) { // Authenticate everytime we reach a trailer block if(is_debug) printf(" 0x%02x : ", iBlock); if (iBlock / 4 == DO_NOT_ACCESS) { if(is_debug) printf("!\n"); continue; } if (is_trailer_block(iBlock)) { if (bFailure) { // When a failure occured we need to redo the anti-collision if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) { printf("!\nError: tag was removed\n"); return false; } bFailure = false; } fflush(stdout); // Try to authenticate for the current sector if (!authenticate(iBlock, false)) { printf("!\nError: authentication failed for block 0x%02x\n", iBlock); return false; } // Try to read out the trailer if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) { if(is_debug) print_hex(mp.mpd.abtData, 16); parserights(&e, uiBlocks / 4, mp.mpd.abtData); } else { printf("!\nfailed to read trailer block 0x%02x\n", iBlock); bFailure = true; } } else { // Make sure a earlier readout did not fail if (!bFailure) { // Try to read out the data block if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) { if(is_debug) print_hex(mp.mpd.abtData, 16); parseTag(&e, iBlock, mp.mpd.abtData); } else { printf("!\nError: unable to read block 0x%02x\n", iBlock); bFailure = true; } } } if ( bFailure ) return false; } fflush(stdout); return true; }
static bool write_block(uint32_t uiBlock, uint8_t* data, bool isTypeA) { if(is_trailer_block(uiBlock)) return false; mifare_param mpw; mifare_cmd mc = MC_WRITE; memcpy(mpw.mpd.abtData, data, 16); if(!authenticate(uiBlock, isTypeA)) return false; if(!nfc_initiator_mifare_cmd(pnd, mc, uiBlock, &mpw)) return false; return true; }
int com_mac_validate(char* arg) { char* a = strtok(arg, " "); if (a && strtok(NULL, " ") != (char*)NULL) { printf("Too many arguments\n"); return -1; } mf_size_t size = parse_size_default(a, MF_1K); if (size == MF_INVALID_SIZE) { printf("Unknown argument: %s\n", a); return -1; } for(size_t i = 1; i < block_count(size); i++) { if(is_trailer_block(i)) { continue; } unsigned char* mac = compute_block_mac(i, current_mac_key, 0); printf("Block: %2x ", i); printf("Tag: "); print_hex_array_sep(¤t_tag.amb[i].mbd.abtData[14], 2, " "); printf(" Computed: "); print_hex_array_sep(mac, 2, " "); printf(" Result: "); if(memcmp(mac, ¤t_tag.amb[i].mbd.abtData[14], 2) == 0) { printf("VALID"); } else { printf("IN-VALID"); } printf("\n"); } return 0; }
bool write_card(int write_block_zero) { uint32_t uiBlock; bool bFailure = false; uint32_t uiWriteBlocks = 0; if (write_block_zero) { if (!unlock_card()) { return false; } } #ifdef DEBUG_PRINTF fprintf(stderr,"Writing %d blocks |", uiBlocks + 1); #endif //! Write the card from begin to end; for (uiBlock = 0; uiBlock <= uiBlocks; uiBlock++) { //! Authenticate everytime we reach the first sector of a new block if (is_first_block(uiBlock)) { if (bFailure) { //! When a failure occured we need to redo the anti-collision if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) { #ifdef DEBUG_PRINTF fprintf(stderr,"!\nError: tag was removed\n"); #endif sprintf(message_erreur,"Error: tag was removed !"); return false; } bFailure = false; } fflush(stdout); //! Try to authenticate for the current sector if (!write_block_zero && !authenticate(uiBlock)) { #ifdef DEBUG_PRINTF fprintf(stderr,"!\nError: authentication failed for block %02x\n", uiBlock); #endif sprintf(message_erreur,"Error: authentication failed for block %02x !", uiBlock); return false; } } if (is_trailer_block(uiBlock)) { //! Copy the keys over from our key dump and store the retrieved access bits memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbt.abtKeyA, 6); memcpy(mp.mpd.abtData + 6, mtDump.amb[uiBlock].mbt.abtAccessBits, 4); memcpy(mp.mpd.abtData + 10, mtDump.amb[uiBlock].mbt.abtKeyB, 6); //! Try to write the trailer if (nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp) == false) { #ifdef DEBUG_PRINTF fprintf(stderr,"failed to write trailer block %d \n", uiBlock); #endif bFailure = true; } } else { //! The first block 0x00 is read only, skip this if (uiBlock == 0 && ! write_block_zero && ! magic2) continue; //! Make sure a earlier write did not fail if (!bFailure) { //! Try to write the data block memcpy(mp.mpd.abtData, mtDump.amb[uiBlock].mbd.abtData, 16); //! do not write a block 0 with incorrect BCC - card will be made invalid! if (uiBlock == 0) { if ((mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3] ^ mp.mpd.abtData[4]) != 0x00 && !magic2) { #ifdef DEBUG_PRINTF fprintf(stderr,"!\nError: incorrect BCC in MFD file!\n"); fprintf(stderr,"Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]); #endif sprintf(message_erreur,"Error: incorrect BCC in MFD file! "); return false; } } if (!nfc_initiator_mifare_cmd(pnd, MC_WRITE, uiBlock, &mp)) { bFailure = true; } } } //! Show if the write went well for each block print_success_or_failure(bFailure, &uiWriteBlocks); if ((! bTolerateFailures) && bFailure) { return false; } } #ifdef DEBUG_PRINTF fprintf(stderr,"|\n"); fprintf(stderr,"Done, %d of %d blocks written.\n", uiWriteBlocks, uiBlocks + 1); #endif fflush(stdout); return true; }
bool read_card(int read_unlocked) { int32_t iBlock; bool bFailure = false; uint32_t uiReadBlocks = 0; if (read_unlocked) { if (!unlock_card()) { return false; } } #ifdef DEBUG_PRINTF fprintf(stderr,"Reading out %d blocks |\n", uiBlocks + 1); #endif //! Read the card from end to begin for (iBlock = uiBlocks; iBlock >= 0; iBlock--) { //! Authenticate everytime we reach a trailer block if (is_trailer_block(iBlock)) { if (bFailure) { //! When a failure occured we need to redo the anti-collision if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) { #ifdef DEBUG_PRINTF fprintf(stderr,"!\nError: tag was removed\n"); #endif sprintf(message_erreur,"Error: tag was removed !"); return false; } bFailure = false; } fflush(stdout); //! Try to authenticate for the current sector if (!read_unlocked && !authenticate(iBlock)) { #ifdef DEBUG_PRINTF fprintf(stderr,"!\nError: authentication failed for block 0x%02x\n", iBlock); #endif sprintf(message_erreur,"Error: authentication failed for block 0x%02x !", iBlock); return false; } //! Try to read out the trailer if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) { if (read_unlocked) { memcpy(mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, 16); } else { //! Copy the keys over from our key dump and store the retrieved access bits memcpy(mtDump.amb[iBlock].mbt.abtKeyA, mtKeys.amb[iBlock].mbt.abtKeyA, 6); memcpy(mtDump.amb[iBlock].mbt.abtAccessBits, mp.mpd.abtData + 6, 4); memcpy(mtDump.amb[iBlock].mbt.abtKeyB, mtKeys.amb[iBlock].mbt.abtKeyB, 6); } } else { #ifdef DEBUG_PRINTF fprintf(stderr,"!\nfailed to read trailer block 0x%02x\n", iBlock); #endif bFailure = true; } } else { //! Make sure a earlier readout did not fail if (!bFailure) { //! Try to read out the data block if (nfc_initiator_mifare_cmd(pnd, MC_READ, iBlock, &mp)) { memcpy(mtDump.amb[iBlock].mbd.abtData, mp.mpd.abtData, 16); } else { #ifdef DEBUG_PRINTF fprintf(stderr,"!\nError: unable to read block 0x%02x\n", iBlock); #endif bFailure = true; } } } //! Show if the readout went well for each block print_success_or_failure(bFailure, &uiReadBlocks); if ((! bTolerateFailures) && bFailure) { return false; } } #ifdef DEBUG_PRINTF fprintf(stderr,"|\n"); fprintf(stderr,"Done : %d of %d blocks read.\n", uiReadBlocks, uiBlocks + 1); #endif fflush(stdout); return true; }
bool mf_read_tag_internal(mf_tag_t* tag, const mf_tag_t* keys, mf_key_type_t key_type) { mifare_param mp; static mf_tag_t buffer_tag; clear_tag(&buffer_tag); int error = 0; printf("Reading: ["); fflush(stdout); // Read the card from end to begin for (int block_it = (int)block_count(size) - 1; block_it >= 0; --block_it) { size_t block = (size_t)block_it; // Authenticate everytime we reach a trailer block if (is_trailer_block(block)) { // Try to authenticate for the current sector uint8_t* key = key_from_tag(keys, key_type, block); if (!mf_authenticate(block, key, key_type)) { // Progress indication and error report printf("0x%02zx", block_to_sector(block)); if (block != 3) printf("."); fflush(stdout); block_it -= (int)sector_size(block) - 1; // Skip the rest of the sector blocks error = 1; } else { // Try to read the trailer (only to *read* the access bits) if (nfc_initiator_mifare_cmd(device, MC_READ, (uint8_t)block, &mp)) { // Copy the keys over to our tag buffer key_to_tag(&buffer_tag, keys->amb[block].mbt.abtKeyA, MF_KEY_A, block); key_to_tag(&buffer_tag, keys->amb[block].mbt.abtKeyB, MF_KEY_B, block); // Store the retrieved access bits in the tag buffer memcpy(buffer_tag.amb[block].mbt.abtAccessBits, mp.mpd.abtData + 6, 4); } else { printf ("\nUnable to read trailer block: 0x%02zx.\n", block); return false; } printf("."); fflush(stdout); // Progress indicator } } else { // I.e. not a sector trailer // Try to read out the block if (!nfc_initiator_mifare_cmd(device, MC_READ, (uint8_t)block, &mp)) { printf("\nUnable to read block: 0x%02zx.\n", block); return false; } memcpy(buffer_tag.amb[block].mbd.abtData, mp.mpd.abtData, 0x10); } } // Terminate progress indicator if (error) printf("] Auth errors in indicated sectors.\n"); else printf("] Success!\n"); // Success! Copy the data // todo: Or return static ptr? memcpy(tag, &buffer_tag, MF_4K); return true; }