diff -Nru mfoc-0.10.2/src//mfoc.c mfoc/src//mfoc.c --- mfoc-0.10.2/src//mfoc.c 2011-05-18 11:18:29.000000000 +0200 +++ mfoc/src//mfoc.c 2012-02-11 02:02:27.028185737 +0100 @@ -70,11 +70,11 @@ bool skip = false; // Next default key specified as option (-k) - byte_t * defKey = NULL; + byte_t * defKeys = NULL, *p; + size_t defKeys_len = 0; // Array with default Mifare Classic keys byte_t defaultKeys[][6] = { - {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // User defined key slot {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // Default key (first key used by program if no user defined key) {0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}, // NFCForum MAD key {0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}, // NFCForum content key @@ -128,16 +128,17 @@ // fprintf(stdout, "Tolerance number: %d\n", probes); break; case 'k': - // Add this key to the default keys list - if ((defKey = calloc(6, sizeof(byte_t))) == NULL) { - ERR ("Cannot allocate memory for defKey"); + // Add this key to the default keys + p = realloc(defKeys, defKeys_len + 6); + if (!p) { + ERR ("Cannot allocate memory for defKeys"); exit (EXIT_FAILURE); - } else { - bzero(defKey, 6); - num_to_bytes(strtoll(optarg, NULL, 16), 6, defKey); - memcpy(defaultKeys[0], defKey, 6); } - fprintf(stdout, "The custom key 0x%012llx has been added to the default keys\n", bytes_to_num(defKey, 6)); + defKeys = p; + memset(defKeys+defKeys_len, 0, 6); + num_to_bytes(strtoll(optarg, NULL, 16), 6, defKeys+defKeys_len); + fprintf(stdout, "The custom key 0x%012llx has been added to the default keys\n", bytes_to_num(defKeys+defKeys_len, 6)); + defKeys_len = defKeys_len + 6; break; case 'O': @@ -252,9 +253,16 @@ memcpy(mp.mpa.abtUid, t.nt.nti.nai.abtUid, sizeof(mp.mpa.abtUid)); // Iterate over all keys (n = number of keys) n = sizeof(defaultKeys)/sizeof(defaultKeys[0]); - for (key = 0; key < n; key++) { - if (key == 0 && defKey == NULL) ++key; // Custom key not provided, try another key - memcpy(mp.mpa.abtKey, defaultKeys[key], sizeof(mp.mpa.abtKey)); + size_t defKey_bytes_todo = defKeys_len; + key = 0; + while (key < n) { + if (defKey_bytes_todo > 0) { + memcpy(mp.mpa.abtKey, defKeys + defKeys_len - defKey_bytes_todo, sizeof(mp.mpa.abtKey)); + defKey_bytes_todo -= sizeof(mp.mpa.abtKey); + } else { + memcpy(mp.mpa.abtKey, defaultKeys[key], sizeof(mp.mpa.abtKey)); + key++; + } fprintf(stdout, "[Key: %012llx] -> ", bytes_to_num(mp.mpa.abtKey, 6)); fprintf(stdout, "["); i = 0; // Sector counter @@ -511,22 +519,24 @@ } void usage(FILE * stream, int errno) { - fprintf(stream, "mfoc %s\n\n", PACKAGE_VERSION); - fprintf(stream, "usage: mfoc [-h] [-P probnum] [-T tolerance] [-k custom_key] [-O output]\n\n"); - fprintf(stream, "example: mfoc -O card_dump\n"); - fprintf(stream, "example: mfoc -k ffffeeeedddd -O card_dump\n"); - fprintf(stream, "example: mfoc -P 50 -O card_dump\n"); - fprintf(stream, "\n"); - fprintf(stream, " h : print this help\n"); -// fprintf(stream, " B : instead of 'A' dump 'B' keys\n"); - fprintf(stream, " k : use a specified key instead of looking for defaults ones\n"); -// fprintf(stream, " D : number of distance probes, default is 20\n"); -// fprintf(stream, " S : number of sets with keystreams, default is 5\n"); - fprintf(stream, " P : number of probes for a key recovery for one sector, default is 20\n"); - fprintf(stream, " T : range for a possible distance tolerance, default is 20 (40 in both direction)\n"); -// fprintf(stream, " s : specify the list of sectors to crack, for example -s 0,1,3,5\n"); - fprintf(stream, " O : dump file where the revealed keys should be stored\n"); + fprintf(stream, "Usage: mfoc [-h] [-k key]... [-P probnum] [-T tolerance] [-O output]\n"); + fprintf(stream, "\n"); + fprintf(stream, " h print this help and exit\n"); +// fprintf(stream, " B instead of 'A' dump 'B' keys\n"); + fprintf(stream, " k try the specified key in addition to the default keys\n"); +// fprintf(stream, " D number of distance probes, default is 20\n"); +// fprintf(stream, " S number of sets with keystreams, default is 5\n"); + fprintf(stream, " P number of probes per sector, instead of default of 20\n"); + fprintf(stream, " T nonce tolerance half-range, instead of default of 20\n (i.e., 40 for the total range, in both directions)\n"); +// fprintf(stream, " s specify the list of sectors to crack, for example -s 0,1,3,5\n"); + fprintf(stream, " O file in which the card contents will be written (REQUIRED)\n"); + fprintf(stream, "\n"); + fprintf(stream, "Example: mfoc -O mycard.mfd\n"); + fprintf(stream, "Example: mfoc -k ffffeeeedddd -O mycard.mfd\n"); + fprintf(stream, "Example: mfoc -P 50 -T 30 -O mycard.mfd\n"); fprintf(stream, "\n"); + fprintf(stream, "This is mfoc version %s.\n", PACKAGE_VERSION); + fprintf(stream, "For more information, run: 'man mfoc'.\n"); exit(errno); } @@ -534,7 +544,7 @@ // Connect to the first NFC device r->pdi = nfc_connect(NULL); if (!r->pdi) { - ERR ("Unable to connect to NFC device\n"); + printf ("No NFC device found.\n"); exit (EXIT_FAILURE); } } @@ -671,7 +681,7 @@ exit (EXIT_FAILURE); } - if (!nfc_initiator_transceive_bytes(r.pdi, Auth, 4, Rx, &RxLen)) { + if (!nfc_initiator_transceive_bytes(r.pdi, Auth, 4, Rx, &RxLen, NULL)) { fprintf(stdout, "Error while requesting plain tag-nonce\n"); exit(EXIT_FAILURE); } diff -Nru mfoc-0.10.2/src//mifare.c mfoc/src//mifare.c --- mfoc-0.10.2/src//mifare.c 2011-04-04 12:38:30.000000000 +0200 +++ mfoc/src//mifare.c 2012-02-11 02:02:27.028185737 +0100 @@ -100,7 +100,7 @@ return false; } // Fire the mifare command - if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx)) { + if (!nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, &szRx, NULL)) { if (pnd->iLastError == EINVRXFRAM) { // "Invalid received frame" AKA EINVRXFRAM, usual means we are // authenticated on a sector but the requested MIFARE cmd (read, write) diff -Nru mfoc-0.10.2/src//nfc-utils.c mfoc/src//nfc-utils.c --- mfoc-0.10.2/src//nfc-utils.c 2011-04-04 12:01:33.000000000 +0200 +++ mfoc/src//nfc-utils.c 2012-02-11 02:02:27.028185737 +0100 @@ -608,6 +608,51 @@ } void +print_nfc_iso14443bi_info (const nfc_iso14443bi_info_t nii, bool verbose) +{ + printf (" DIV: "); + print_hex (nii.abtDIV, 4); + if (verbose) { + int version = (nii.btVerLog & 0x1e)>>1; + printf (" Software Version: "); + if (version == 15) { + printf ("Undefined\n"); + } else { + printf ("%i\n", version); + } + + if ((nii.btVerLog & 0x80) && (nii.btConfig & 0x80)){ + printf (" Wait Enable: yes"); + } + } + if ((nii.btVerLog & 0x80) && (nii.btConfig & 0x40)) { + printf (" ATS: "); + print_hex (nii.abtAtr, nii.szAtrLen); + } +} + +void +print_nfc_iso14443b2sr_info (const nfc_iso14443b2sr_info_t nsi, bool verbose) +{ + (void) verbose; + printf (" UID: "); + print_hex (nsi.abtUID, 8); +} + +void +print_nfc_iso14443b2ct_info (const nfc_iso14443b2ct_info_t nci, bool verbose) +{ + (void) verbose; + uint32_t uid; + uid = (nci.abtUID[3] << 24) + (nci.abtUID[2] << 16) + (nci.abtUID[1] << 8) + nci.abtUID[0]; + printf (" UID: "); + print_hex (nci.abtUID, sizeof(nci.abtUID)); + printf (" UID (decimal): %010u\n", uid); + printf (" Product Code: %02X\n", nci.btProdCode); + printf (" Fab Code: %02X\n", nci.btFabCode); +} + +void print_nfc_dep_info (const nfc_dep_info_t ndi, bool verbose) { (void) verbose; @@ -651,8 +696,7 @@ strcpy (pndd->pcDriver, strtok (buffer, ":")); // Port. - pndd->pcPort = (char *) malloc (256); - strcpy (pndd->pcPort, strtok (NULL, ":")); + strcpy (pndd->acPort, strtok (NULL, ":")); // Speed. sscanf (strtok (NULL, ":"), "%u", &pndd->uiSpeed); @@ -712,6 +756,18 @@ printf ("ISO/IEC 14443-4B (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); print_nfc_iso14443b_info (nt.nti.nbi, verbose); break; + case NMT_ISO14443BI: + printf ("ISO/IEC 14443-4B' (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); + print_nfc_iso14443bi_info (nt.nti.nii, verbose); + break; + case NMT_ISO14443B2SR: + printf ("ISO/IEC 14443-2B ST SRx (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); + print_nfc_iso14443b2sr_info (nt.nti.nsi, verbose); + break; + case NMT_ISO14443B2CT: + printf ("ISO/IEC 14443-2B ASK CTx (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); + print_nfc_iso14443b2ct_info (nt.nti.nci, verbose); + break; case NMT_DEP: printf ("D.E.P. (%s) target:\n", str_nfc_baud_rate(nt.nm.nbr)); print_nfc_dep_info (nt.nti.ndi, verbose);