public static bool authenticate(NFC.nfc_device pnd, NFC.nfc_target pnt, uint uiBlock, byte[] key, mifare_cmd mc) { mifare_param mp = new mifare_param(); // Set the authentication information (uid) MiscTool.memcpy(mp.mpa.abtAuthUid, 0, pnt.nti.nai.abtUid, pnt.nti.nai.szUidLen - 4, 4); MiscTool.memcpy(mp.mpa.abtKey, 0, key, 0, 6); if (nfc_initiator_mifare_cmd(pnd, mc, (byte)uiBlock, mp)) { return(true); } if (NFC.nfc_initiator_select_passive_target(pnd, nmMfClassic, pnt.nti.nai.abtUid, pnt.nti.nai.szUidLen, null) <= 0) { //ERR("tag was removed"); return(false); } return(true); }
public void FillRawData(byte[] dst, int offset) { MiscTool.memcpy(dst, offset, abtValue, 0, abtValue.Length); }
public void FillRawData(byte[] dst, int offset) { MiscTool.memcpy(dst, offset, abtKey, 0, abtKey.Length); offset += abtKey.Length; MiscTool.memcpy(dst, offset, abtAuthUid, 0, abtAuthUid.Length); }
nfc_initiator_mifare_cmd(NFCInternal.nfc_device pnd, mifare_cmd mc, byte ui8Block, mifare_param pmp) { byte[] abtRx = new byte[265]; byte szParamLen; byte[] abtCmd = new byte[265]; //bool bEasyFraming; abtCmd[0] = (byte)mc; // The MIFARE Classic command abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff) switch (mc) { // Read and store command have no parameter case mifare_cmd.MC_READ: case mifare_cmd.MC_STORE: szParamLen = 0; break; // Authenticate command case mifare_cmd.MC_AUTH_A: case mifare_cmd.MC_AUTH_B: szParamLen = (byte)pmp.mpa.Length(); //sizeof( mifare_param_auth); if (szParamLen > 0) { pmp.mpa.FillRawData(abtCmd, 2); } break; // Data command case mifare_cmd.MC_WRITE: szParamLen = (byte)pmp.mpd.Length(); //sizeof( mifare_param_data); if (szParamLen > 0) { pmp.mpd.FillRawData(abtCmd, 2); } break; // Value command case mifare_cmd.MC_DECREMENT: case mifare_cmd.MC_INCREMENT: case mifare_cmd.MC_TRANSFER: szParamLen = (byte)pmp.mpv.Length(); //sizeof( mifare_param_value); if (szParamLen > 0) { pmp.mpv.FillRawData(abtCmd, 2); } break; // Please fix your code, you never should reach this statement default: return(false); break; } // FIXME: Save and restore bEasyFraming // bEasyFraming = nfc_device_get_property_bool (pnd, NP_EASY_FRAMING, &bEasyFraming); if (NFC.nfc_device_set_property_bool(pnd, NFC.nfc_property.NP_EASY_FRAMING, true) < 0) { //nfc_perror(pnd, "nfc_device_set_property_bool"); return(false); } // Fire the mifare command int res; if ((res = NFC.nfc_initiator_transceive_bytes(pnd, abtCmd, 2 + szParamLen, abtRx, abtRx.Length, -1)) < 0) { if (res == NFC.NFC_ERFTRANS) { // "Invalid received frame", usual means we are // authenticated on a sector but the requested MIFARE cmd (read, write) // is not permitted by current acces bytes; // So there is nothing to do here. } else { //nfc_perror(pnd, "nfc_initiator_transceive_bytes"); } // XXX nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming); return(false); } /* XXX * if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming) < 0) { * nfc_perror (pnd, "nfc_device_set_property_bool"); * return false; * } */ // When we have executed a read command, copy the received bytes into the param if (mc == mifare_cmd.MC_READ) { if (res == 16) { MiscTool.memcpy(pmp.mpd.abtData, 0, abtRx, 0, 16); } else { return(false); } } // Command succesfully executed return(true); }
write_card(int write_block_zero) { uint uiBlock; bool bFailure = false; uint uiWriteBlocks = 0; if (write_block_zero != 0) { if (!unlock_card()) { return(false); } } //printf("Writing %d blocks |", uiBlocks + 1); // 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.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 (0 == write_block_zero && !authenticate(uiBlock)) { //printf("!\nError: authentication failed for block %02x\n", uiBlock); return(false); } } if (is_trailer_block(uiBlock)) { if (bFormatCard) { // Copy the default key and reset the access bits MiscTool.memcpy(mp.mpd.abtData, 0, default_key, 0, 6); MiscTool.memcpy(mp.mpd.abtData, 6, default_acl, 0, 4); MiscTool.memcpy(mp.mpd.abtData, 10, default_key, 0, 6); } else { // Copy the keys over from our key dump and store the retrieved access bits MiscTool.memcpy(mp.mpd.abtData, 0, mtDump.amb[uiBlock].mbt.abtKeyA, 0, 6); MiscTool.memcpy(mp.mpd.abtData, 6, mtDump.amb[uiBlock].mbt.abtAccessBits, 0, 4); MiscTool.memcpy(mp.mpd.abtData, 10, mtDump.amb[uiBlock].mbt.abtKeyB, 0, 6); } // Try to write the trailer if (Mifare.nfc_initiator_mifare_cmd(pnd, Mifare.mifare_cmd.MC_WRITE, (byte)uiBlock, mp) == false) { //printf("failed to write trailer block %d \n", uiBlock); bFailure = true; } } else { // The first block 0x00 is read only, skip this if (uiBlock == 0 && 0 == write_block_zero && !magic2) { continue; } // Make sure a earlier write did not fail if (!bFailure) { // Try to write the data block if (bFormatCard && uiBlock != 0) { MiscTool.memset(mp.mpd.abtData, 0x00, 16); } else { MiscTool.memcpy(mp.mpd.abtData, 0, mtDump.amb[uiBlock].mbd.abtData, 0, 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) { //printf("!\nError: incorrect BCC in MFD file!\n"); //printf("Expecting BCC=%02X\n", mp.mpd.abtData[0] ^ mp.mpd.abtData[1] ^ mp.mpd.abtData[2] ^ mp.mpd.abtData[3]); return(false); } } if (!Mifare.nfc_initiator_mifare_cmd(pnd, Mifare.mifare_cmd.MC_WRITE, (byte)uiBlock, mp)) { bFailure = true; } } } // Show if the write went well for each block print_success_or_failure(bFailure, ref uiWriteBlocks); if ((!bTolerateFailures) && bFailure) { return(false); } } //printf("|\n"); //printf("Done, %d of %d blocks written.\n", uiWriteBlocks, uiBlocks + 1); //fflush(stdout); return(true); }
read_card(int read_unlocked) { uint iBlock; bool bFailure = false; uint uiReadBlocks = 0; if (read_unlocked != 0) { if (!unlock_card()) { return(false); } } //printf("Reading out %d blocks |", uiBlocks + 1); // 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.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 (0 == read_unlocked && !authenticate(iBlock)) { //printf("!\nError: authentication failed for block 0x%02x\n", iBlock); return(false); } // Try to read out the trailer if (Mifare.nfc_initiator_mifare_cmd(pnd, Mifare.mifare_cmd.MC_READ, (byte)iBlock, mp)) { if (0 != read_unlocked) { MiscTool.memcpy(mtDump.amb[iBlock].mbd.abtData, 0, mp.mpd.abtData, 0, 16); } else { // Copy the keys over from our key dump and store the retrieved access bits MiscTool.memcpy(mtDump.amb[iBlock].mbt.abtKeyA, 0, mtKeys.amb[iBlock].mbt.abtKeyA, 0, 6); MiscTool.memcpy(mtDump.amb[iBlock].mbt.abtAccessBits, 0, mp.mpd.abtData, 6, 4); MiscTool.memcpy(mtDump.amb[iBlock].mbt.abtKeyB, 0, mtKeys.amb[iBlock].mbt.abtKeyB, 0, 6); } } 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 (Mifare.nfc_initiator_mifare_cmd(pnd, Mifare.mifare_cmd.MC_READ, (byte)iBlock, mp)) { MiscTool.memcpy(mtDump.amb[iBlock].mbd.abtData, 0, mp.mpd.abtData, 0, 16); } else { //printf("!\nError: unable to read block 0x%02x\n", iBlock); bFailure = true; } } } // Show if the readout went well for each block print_success_or_failure(bFailure, ref uiReadBlocks); if ((!bTolerateFailures) && bFailure) { return(false); } } //printf("|\n"); //printf("Done, %d of %d blocks read.\n", uiReadBlocks, uiBlocks + 1); //fflush(stdout); return(true); }
authenticate(uint uiBlock) { Mifare.mifare_cmd mc; uint uiTrailerBlock; // Set the authentication information (uid) MiscTool.memcpy(mp.mpa.abtAuthUid, 0, nt.nti.nai.abtUid, nt.nti.nai.szUidLen - 4, 4); // Should we use key A or B? mc = (bUseKeyA) ? Mifare.mifare_cmd.MC_AUTH_A : Mifare.mifare_cmd.MC_AUTH_B; // Key file authentication. if (bUseKeyFile) { // Locate the trailer (with the keys) used for this sector uiTrailerBlock = get_trailer_block(uiBlock); // Extract the right key from dump file if (bUseKeyA) { MiscTool.memcpy(mp.mpa.abtKey, 0, mtKeys.amb[uiTrailerBlock].mbt.abtKeyA, 0, 6); } else { MiscTool.memcpy(mp.mpa.abtKey, 0, mtKeys.amb[uiTrailerBlock].mbt.abtKeyB, 0, 6); } // Try to authenticate for the current sector if (Mifare.nfc_initiator_mifare_cmd(pnd, mc, (byte)uiBlock, mp)) { return(true); } } // If formatting or not using key file, try to guess the right key if (bFormatCard || !bUseKeyFile) { for (int key_index = 0; key_index < num_keys; key_index++) { MiscTool.memcpy(mp.mpa.abtKey, 0, keys, (key_index * 6), 6); if (Mifare.nfc_initiator_mifare_cmd(pnd, mc, (byte)uiBlock, mp)) { if (bUseKeyA) { MiscTool.memcpy(mtKeys.amb[uiBlock].mbt.abtKeyA, 0, mp.mpa.abtKey, 0, 6); } else { MiscTool.memcpy(mtKeys.amb[uiBlock].mbt.abtKeyB, 0, mp.mpa.abtKey, 0, 6); } return(true); } if (NFC.nfc_initiator_select_passive_target(pnd, nmMifare, nt.nti.nai.abtUid, nt.nti.nai.szUidLen, null) <= 0) { //ERR("tag was removed"); return(false); } } } return(false); }