some code clean up: find . -name '*.[ch]' | xargs perl -pi -e 's/\t+$//; s/ +$//'

This commit is contained in:
Romuald Conty 2012-06-03 21:07:51 +00:00
parent 435de61cc5
commit bc109b9252
7 changed files with 163 additions and 160 deletions

View file

@ -48,7 +48,7 @@ int nonce_distance(uint32_t from, uint32_t to);
break;\ break;\
else if(__i)\ else if(__i)\
__M = prng_successor(__M, (__i == 7) ? 48 : 8);\ __M = prng_successor(__M, (__i == 7) ? 48 : 8);\
else else
#define LF_POLY_ODD (0x29CE5C) #define LF_POLY_ODD (0x29CE5C)
#define LF_POLY_EVEN (0x870804) #define LF_POLY_EVEN (0x870804)

View file

@ -1,29 +1,29 @@
/* /*
Mifare Classic Offline Cracker Mifare Classic Offline Cracker
Requirements: crapto1 library http://code.google.com/p/crapto1 Requirements: crapto1 library http://code.google.com/p/crapto1
libnfc http://www.libnfc.org libnfc http://www.libnfc.org
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or the Free Software Foundation, either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
Contact: <mifare@nethemba.com> Contact: <mifare@nethemba.com>
Porting to libnfc 1.3.3: Michal Boska <boska.michal@gmail.com> Porting to libnfc 1.3.3: Michal Boska <boska.michal@gmail.com>
Porting to libnfc 1.3.9: Romuald Conty <romuald@libnfc.org> Porting to libnfc 1.3.9: Romuald Conty <romuald@libnfc.org>
Porting to libnfc 1.4.x: Romuald Conty <romuald@libnfc.org> Porting to libnfc 1.4.x: Romuald Conty <romuald@libnfc.org>
URL http://eprint.iacr.org/2009/137.pdf URL http://eprint.iacr.org/2009/137.pdf
URL http://www.sos.cs.ru.nl/applications/rfid/2008-esorics.pdf URL http://www.sos.cs.ru.nl/applications/rfid/2008-esorics.pdf
URL http://www.cosic.esat.kuleuven.be/rfidsec09/Papers/mifare_courtois_rfidsec09.pdf URL http://www.cosic.esat.kuleuven.be/rfidsec09/Papers/mifare_courtois_rfidsec09.pdf
@ -61,21 +61,21 @@ int main(int argc, char * const argv[]) {
int ch, i, k, n, j, m; int ch, i, k, n, j, m;
int key, block; int key, block;
int succeed = 1; int succeed = 1;
// Exploit sector // Exploit sector
int e_sector; int e_sector;
int probes = DEFAULT_PROBES_NR; int probes = DEFAULT_PROBES_NR;
int sets = DEFAULT_SETS_NR; int sets = DEFAULT_SETS_NR;
// By default, dump 'A' keys // By default, dump 'A' keys
int dumpKeysA = true; int dumpKeysA = true;
bool failure = false; bool failure = false;
bool skip = false; bool skip = false;
// Next default key specified as option (-k) // Next default key specified as option (-k)
uint8_t * defKeys = NULL, *p; uint8_t * defKeys = NULL, *p;
size_t defKeys_len = 0; size_t defKeys_len = 0;
// Array with default Mifare Classic keys // Array with default Mifare Classic keys
uint8_t defaultKeys[][6] = { uint8_t defaultKeys[][6] = {
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // Default key (first key used by program if no user defined key) {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // Default key (first key used by program if no user defined key)
@ -93,7 +93,7 @@ int main(int argc, char * const argv[]) {
{0x8f, 0xd0, 0xa4, 0xf2, 0x56, 0xe9} {0x8f, 0xd0, 0xa4, 0xf2, 0x56, 0xe9}
}; };
mftag t; mftag t;
mfreader r; mfreader r;
denonce d = {NULL, 0, DEFAULT_DIST_NR, DEFAULT_TOLERANCE, {0x00, 0x00, 0x00}}; denonce d = {NULL, 0, DEFAULT_DIST_NR, DEFAULT_TOLERANCE, {0x00, 0x00, 0x00}};
@ -101,23 +101,23 @@ int main(int argc, char * const argv[]) {
// Pointers to possible keys // Pointers to possible keys
pKeys *pk; pKeys *pk;
countKeys *ck; countKeys *ck;
// Pointer to already broken keys, except defaults // Pointer to already broken keys, except defaults
bKeys *bk; bKeys *bk;
static mifare_param mp; static mifare_param mp;
static mifare_classic_tag mtDump; static mifare_classic_tag mtDump;
mifare_cmd mc; mifare_cmd mc;
FILE *pfDump = NULL; FILE *pfDump = NULL;
// Parse command line arguments // Parse command line arguments
while ((ch = getopt(argc, argv, "hD:s:BP:T:S:O:k:t:")) != -1) { while ((ch = getopt(argc, argv, "hD:s:BP:T:S:O:k:t:")) != -1) {
switch (ch) { switch (ch) {
case 'P': case 'P':
// Number of probes // Number of probes
if (!(probes = atoi(optarg)) || probes < 1) { if (!(probes = atoi(optarg)) || probes < 1) {
ERR ("The number of probes must be a positive number"); ERR ("The number of probes must be a positive number");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
// fprintf(stdout, "Number of probes: %d\n", probes); // fprintf(stdout, "Number of probes: %d\n", probes);
@ -127,7 +127,7 @@ int main(int argc, char * const argv[]) {
int res; int res;
// Nonce tolerance range // Nonce tolerance range
if (((res = atoi(optarg)) != 0) || (res < 0)) { if (((res = atoi(optarg)) != 0) || (res < 0)) {
ERR ("The nonce distances range must be a zero or a positive number"); ERR ("The nonce distances range must be a zero or a positive number");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
d.tolerance = (uint32_t)res; d.tolerance = (uint32_t)res;
@ -146,12 +146,12 @@ int main(int argc, char * const argv[]) {
num_to_bytes(strtoll(optarg, NULL, 16), 6, defKeys+defKeys_len); 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)); 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; defKeys_len = defKeys_len + 6;
break; break;
case 'O': case 'O':
// File output // File output
if (!(pfDump = fopen(optarg, "wb"))) { if (!(pfDump = fopen(optarg, "wb"))) {
fprintf(stderr, "Cannot open: %s, exiting\n", optarg); fprintf(stderr, "Cannot open: %s, exiting\n", optarg);
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
// fprintf(stdout, "Output file: %s\n", optarg); // fprintf(stdout, "Output file: %s\n", optarg);
@ -164,12 +164,12 @@ int main(int argc, char * const argv[]) {
break; break;
} }
} }
if (!pfDump) { if (!pfDump) {
ERR ("parameter -O is mandatory"); ERR ("parameter -O is mandatory");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
// Initialize reader/tag structures // Initialize reader/tag structures
mf_init(&r); mf_init(&r);
@ -207,7 +207,7 @@ int main(int argc, char * const argv[]) {
nfc_perror (r.pdi, "nfc_initiator_select_passive_target"); nfc_perror (r.pdi, "nfc_initiator_select_passive_target");
goto error; goto error;
} }
// Test if a compatible MIFARE tag is used // Test if a compatible MIFARE tag is used
if ((t.nt.nti.nai.btSak & 0x08) == 0) { if ((t.nt.nti.nai.btSak & 0x08) == 0) {
ERR ("only Mifare Classic is supported"); ERR ("only Mifare Classic is supported");
@ -224,37 +224,37 @@ int main(int argc, char * const argv[]) {
t.num_blocks = (t.b4K) ? 0xff : 0x3f; t.num_blocks = (t.b4K) ? 0xff : 0x3f;
t.num_sectors = t.b4K ? NR_TRAILERS_4k : NR_TRAILERS_1k; t.num_sectors = t.b4K ? NR_TRAILERS_4k : NR_TRAILERS_1k;
t.sectors = (void *) calloc(t.num_sectors, sizeof(sector)); t.sectors = (void *) calloc(t.num_sectors, sizeof(sector));
if (t.sectors == NULL) { if (t.sectors == NULL) {
ERR ("Cannot allocate memory for t.sectors"); ERR ("Cannot allocate memory for t.sectors");
goto error; goto error;
} }
if ((pk = (void *) malloc(sizeof(pKeys))) == NULL) { if ((pk = (void *) malloc(sizeof(pKeys))) == NULL) {
ERR ("Cannot allocate memory for pk"); ERR ("Cannot allocate memory for pk");
goto error; goto error;
} }
if ((bk = (void *) malloc(sizeof(bKeys))) == NULL) { if ((bk = (void *) malloc(sizeof(bKeys))) == NULL) {
ERR ("Cannot allocate memory for bk"); ERR ("Cannot allocate memory for bk");
goto error; goto error;
} else { } else {
bk->brokenKeys = NULL; bk->brokenKeys = NULL;
bk->size = 0; bk->size = 0;
} }
d.distances = (void *) calloc(d.num_distances, sizeof(uint32_t)); d.distances = (void *) calloc(d.num_distances, sizeof(uint32_t));
if (d.distances == NULL) { if (d.distances == NULL) {
ERR ("Cannot allocate memory for t.distances"); ERR ("Cannot allocate memory for t.distances");
goto error; goto error;
} }
// Initialize t.sectors, keys are not known yet // Initialize t.sectors, keys are not known yet
for (uint8_t s = 0; s < (t.num_sectors); ++s) { for (uint8_t s = 0; s < (t.num_sectors); ++s) {
t.sectors[s].foundKeyA = t.sectors[s].foundKeyB = false; t.sectors[s].foundKeyA = t.sectors[s].foundKeyB = false;
} }
print_nfc_iso14443a_info (t.nt.nti.nai, true); print_nfc_iso14443a_info (t.nt.nti.nai, true);
// Try to authenticate to all sectors with default keys // Try to authenticate to all sectors with default keys
// Set the authentication information (uid) // Set the authentication information (uid)
memcpy(mp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mp.mpa.abtAuthUid)); memcpy(mp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mp.mpa.abtAuthUid));
@ -279,7 +279,7 @@ int main(int argc, char * const argv[]) {
if (!t.sectors[i].foundKeyA) { if (!t.sectors[i].foundKeyA) {
mc = MC_AUTH_A; mc = MC_AUTH_A;
if (!nfc_initiator_mifare_cmd(r.pdi,mc,block,&mp)) { if (!nfc_initiator_mifare_cmd(r.pdi,mc,block,&mp)) {
// fprintf(stdout, "!!Error: AUTH [Key A:%012llx] sector %02x t_block %02x\n", // fprintf(stdout, "!!Error: AUTH [Key A:%012llx] sector %02x t_block %02x\n",
// bytes_to_num(mp.mpa.abtKey, 6), i, block); // bytes_to_num(mp.mpa.abtKey, 6), i, block);
mf_anticollision(t, r); mf_anticollision(t, r);
} else { } else {
@ -291,7 +291,7 @@ int main(int argc, char * const argv[]) {
if (!t.sectors[i].foundKeyB) { if (!t.sectors[i].foundKeyB) {
mc = MC_AUTH_B; mc = MC_AUTH_B;
if (!nfc_initiator_mifare_cmd(r.pdi,mc,block,&mp)) { if (!nfc_initiator_mifare_cmd(r.pdi,mc,block,&mp)) {
// fprintf(stdout, "!!Error: AUTH [Key B:%012llx] sector %02x t_block %02x\n", // fprintf(stdout, "!!Error: AUTH [Key B:%012llx] sector %02x t_block %02x\n",
// bytes_to_num(mp.mpa.abtKey, 6), i, block); // bytes_to_num(mp.mpa.abtKey, 6), i, block);
mf_anticollision(t, r); mf_anticollision(t, r);
// No success, try next block // No success, try next block
@ -311,7 +311,7 @@ int main(int argc, char * const argv[]) {
fprintf(stdout, "."); fprintf(stdout, ".");
} }
fflush(stdout); fflush(stdout);
// fprintf(stdout, "\nSuccess: AUTH [Key %c:%012llx] sector %02x t_block %02x\n", // fprintf(stdout, "\nSuccess: AUTH [Key %c:%012llx] sector %02x t_block %02x\n",
// (mc == MC_AUTH_A ? 'A' :'B'), bytes_to_num(mp.mpa.abtKey, 6), i, block); // (mc == MC_AUTH_A ? 'A' :'B'), bytes_to_num(mp.mpa.abtKey, 6), i, block);
// Save position of a trailer block to sector struct // Save position of a trailer block to sector struct
t.sectors[i++].trailer = block; t.sectors[i++].trailer = block;
@ -327,25 +327,25 @@ int main(int argc, char * const argv[]) {
fprintf(stdout, "\n"); fprintf(stdout, "\n");
} }
fflush(stdout); fflush(stdout);
// Return the first (exploit) sector encrypted with the default key or -1 (we have all keys) // Return the first (exploit) sector encrypted with the default key or -1 (we have all keys)
e_sector = find_exploit_sector(t); e_sector = find_exploit_sector(t);
//mf_enhanced_auth(e_sector, 0, t, r, &d, pk, 'd'); // AUTH + Get Distances mode //mf_enhanced_auth(e_sector, 0, t, r, &d, pk, 'd'); // AUTH + Get Distances mode
// Recover key from encrypted sectors, j is a sector counter // Recover key from encrypted sectors, j is a sector counter
for (m = 0; m < 2; ++m) { for (m = 0; m < 2; ++m) {
if (e_sector == -1) break; // All keys are default, I am skipping recovery mode if (e_sector == -1) break; // All keys are default, I am skipping recovery mode
for (j = 0; j < (t.num_sectors); ++j) { for (j = 0; j < (t.num_sectors); ++j) {
memcpy(mp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mp.mpa.abtAuthUid)); memcpy(mp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mp.mpa.abtAuthUid));
if ((dumpKeysA && !t.sectors[j].foundKeyA) || (!dumpKeysA && !t.sectors[j].foundKeyB)) { if ((dumpKeysA && !t.sectors[j].foundKeyA) || (!dumpKeysA && !t.sectors[j].foundKeyB)) {
// First, try already broken keys // First, try already broken keys
skip = false; skip = false;
for (uint32_t o = 0; o < bk->size; o++) { for (uint32_t o = 0; o < bk->size; o++) {
num_to_bytes(bk->brokenKeys[o], 6, mp.mpa.abtKey); num_to_bytes(bk->brokenKeys[o], 6, mp.mpa.abtKey);
mc = dumpKeysA ? 0x60 : 0x61; mc = dumpKeysA ? 0x60 : 0x61;
if (!nfc_initiator_mifare_cmd(r.pdi,mc,t.sectors[j].trailer,&mp)) { if (!nfc_initiator_mifare_cmd(r.pdi,mc,t.sectors[j].trailer,&mp)) {
// fprintf(stdout, "!!Error: AUTH [Key A:%012llx] sector %02x t_block %02x, key %d\n", // fprintf(stdout, "!!Error: AUTH [Key A:%012llx] sector %02x t_block %02x, key %d\n",
// bytes_to_num(mp.mpa.abtKey, 6), j, t.sectors[j].trailer, o); // bytes_to_num(mp.mpa.abtKey, 6), j, t.sectors[j].trailer, o);
mf_anticollision(t, r); mf_anticollision(t, r);
} else { } else {
@ -358,7 +358,7 @@ int main(int argc, char * const argv[]) {
t.sectors[j].foundKeyB = true; t.sectors[j].foundKeyB = true;
} }
printf("Sector: %d, type %c\n", j, (dumpKeysA ? 'A' : 'B')); printf("Sector: %d, type %c\n", j, (dumpKeysA ? 'A' : 'B'));
fprintf(stdout, "Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'), fprintf(stdout, "Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'),
bytes_to_num(mp.mpa.abtKey, 6)); bytes_to_num(mp.mpa.abtKey, 6));
mf_configure(r.pdi); mf_configure(r.pdi);
mf_anticollision(t, r); mf_anticollision(t, r);
@ -367,16 +367,16 @@ int main(int argc, char * const argv[]) {
} }
} }
if (skip) continue; // We have already revealed key, go to the next iteration if (skip) continue; // We have already revealed key, go to the next iteration
// Max probes for auth for each sector // Max probes for auth for each sector
for (k = 0; k < probes; ++k) { for (k = 0; k < probes; ++k) {
// Try to authenticate to exploit sector and determine distances (filling denonce.distances) // Try to authenticate to exploit sector and determine distances (filling denonce.distances)
mf_enhanced_auth(e_sector, 0, t, r, &d, pk, 'd', dumpKeysA); // AUTH + Get Distances mode mf_enhanced_auth(e_sector, 0, t, r, &d, pk, 'd', dumpKeysA); // AUTH + Get Distances mode
printf("Sector: %d, type %c, probe %d, distance %d ", j, (dumpKeysA ? 'A' : 'B'), k, d.median); printf("Sector: %d, type %c, probe %d, distance %d ", j, (dumpKeysA ? 'A' : 'B'), k, d.median);
// Configure device to the previous state // Configure device to the previous state
mf_configure(r.pdi); mf_configure(r.pdi);
mf_anticollision(t, r); mf_anticollision(t, r);
pk->possibleKeys = NULL; pk->possibleKeys = NULL;
pk->size = 0; pk->size = 0;
// We have 'sets' * 32b keystream of potential keys // We have 'sets' * 32b keystream of potential keys
@ -397,10 +397,10 @@ int main(int argc, char * const argv[]) {
if (ck[i].count > 0) { if (ck[i].count > 0) {
// fprintf(stdout,"%d %llx\n",ck[i].count, ck[i].key); // fprintf(stdout,"%d %llx\n",ck[i].count, ck[i].key);
// Set required authetication method // Set required authetication method
num_to_bytes(ck[i].key, 6, mp.mpa.abtKey); num_to_bytes(ck[i].key, 6, mp.mpa.abtKey);
mc = dumpKeysA ? 0x60 : 0x61; mc = dumpKeysA ? 0x60 : 0x61;
if (!nfc_initiator_mifare_cmd(r.pdi,mc,t.sectors[j].trailer,&mp)) { if (!nfc_initiator_mifare_cmd(r.pdi,mc,t.sectors[j].trailer,&mp)) {
// fprintf(stdout, "!!Error: AUTH [Key A:%llx] sector %02x t_block %02x\n", // fprintf(stdout, "!!Error: AUTH [Key A:%llx] sector %02x t_block %02x\n",
// bytes_to_num(mp.mpa.abtKey, 6), j, t.sectors[j].trailer); // bytes_to_num(mp.mpa.abtKey, 6), j, t.sectors[j].trailer);
mf_anticollision(t, r); mf_anticollision(t, r);
} else { } else {
@ -411,12 +411,12 @@ int main(int argc, char * const argv[]) {
if (dumpKeysA) { if (dumpKeysA) {
memcpy(t.sectors[j].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey)); memcpy(t.sectors[j].KeyA, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
t.sectors[j].foundKeyA = true; t.sectors[j].foundKeyA = true;
} else { } else {
memcpy(t.sectors[j].KeyB, mp.mpa.abtKey, sizeof(mp.mpa.abtKey)); memcpy(t.sectors[j].KeyB, mp.mpa.abtKey, sizeof(mp.mpa.abtKey));
t.sectors[j].foundKeyB = true; t.sectors[j].foundKeyB = true;
} }
fprintf(stdout, "Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'), fprintf(stdout, "Found Key: %c [%012llx]\n", (dumpKeysA ? 'A' : 'B'),
bytes_to_num(mp.mpa.abtKey, 6)); bytes_to_num(mp.mpa.abtKey, 6));
mf_configure(r.pdi); mf_configure(r.pdi);
mf_anticollision(t, r); mf_anticollision(t, r);
@ -427,10 +427,10 @@ int main(int argc, char * const argv[]) {
free(pk->possibleKeys); free(pk->possibleKeys);
free(ck); free(ck);
// Success, try the next sector // Success, try the next sector
if ((dumpKeysA && t.sectors[j].foundKeyA) || (!dumpKeysA && t.sectors[j].foundKeyB)) break; if ((dumpKeysA && t.sectors[j].foundKeyA) || (!dumpKeysA && t.sectors[j].foundKeyB)) break;
} }
// We haven't found any key, exiting // We haven't found any key, exiting
if ((dumpKeysA && !t.sectors[j].foundKeyA) || (!dumpKeysA && !t.sectors[j].foundKeyB)) { if ((dumpKeysA && !t.sectors[j].foundKeyA) || (!dumpKeysA && !t.sectors[j].foundKeyB)) {
ERR ("No success, maybe you should increase the probes"); ERR ("No success, maybe you should increase the probes");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
@ -438,8 +438,8 @@ int main(int argc, char * const argv[]) {
} }
dumpKeysA = false; dumpKeysA = false;
} }
for (i = 0; i < (t.num_sectors); ++i) { for (i = 0; i < (t.num_sectors); ++i) {
if ((dumpKeysA && !t.sectors[i].foundKeyA) || (!dumpKeysA && !t.sectors[i].foundKeyB)) { if ((dumpKeysA && !t.sectors[i].foundKeyA) || (!dumpKeysA && !t.sectors[i].foundKeyB)) {
fprintf(stdout, "\nTry again, there are still some encrypted blocks\n"); fprintf(stdout, "\nTry again, there are still some encrypted blocks\n");
@ -455,7 +455,7 @@ int main(int argc, char * const argv[]) {
for (block = t.num_blocks; block >= 0; block--) { for (block = t.num_blocks; block >= 0; block--) {
trailer_block(block) ? i-- : i; trailer_block(block) ? i-- : i;
failure = true; failure = true;
// Try A key, auth() + read() // Try A key, auth() + read()
memcpy(mp.mpa.abtKey, t.sectors[i].KeyA, sizeof(t.sectors[i].KeyA)); memcpy(mp.mpa.abtKey, t.sectors[i].KeyA, sizeof(t.sectors[i].KeyA));
if (!nfc_initiator_mifare_cmd(r.pdi, MC_AUTH_A, block, &mp)) { if (!nfc_initiator_mifare_cmd(r.pdi, MC_AUTH_A, block, &mp)) {
@ -479,7 +479,7 @@ int main(int argc, char * const argv[]) {
// ERR ("Error: Auth B"); // ERR ("Error: Auth B");
mf_configure(r.pdi); mf_configure(r.pdi);
mf_anticollision(t, r); mf_anticollision(t, r);
} else { // and Read } else { // and Read
if (nfc_initiator_mifare_cmd(r.pdi, MC_READ, block, &mp)) { if (nfc_initiator_mifare_cmd(r.pdi, MC_READ, block, &mp)) {
fprintf(stdout, "Block %02d, type %c, key %012llx :", block, 'B', bytes_to_num(t.sectors[i].KeyB, 6)); fprintf(stdout, "Block %02d, type %c, key %012llx :", block, 'B', bytes_to_num(t.sectors[i].KeyB, 6));
print_hex(mp.mpd.abtData, 16); print_hex(mp.mpd.abtData, 16);
@ -502,7 +502,7 @@ int main(int argc, char * const argv[]) {
} else if (!failure) memcpy(mtDump.amb[block].mbd.abtData, mp.mpd.abtData,16); } else if (!failure) memcpy(mtDump.amb[block].mbd.abtData, mp.mpd.abtData,16);
memcpy(mp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mp.mpa.abtAuthUid)); memcpy(mp.mpa.abtAuthUid, t.nt.nti.nai.abtUid + t.nt.nti.nai.szUidLen - 4, sizeof(mp.mpa.abtAuthUid));
} }
// Finally save all keys + data to file // Finally save all keys + data to file
if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) { if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
fprintf(stdout, "Error, cannot write dump\n"); fprintf(stdout, "Error, cannot write dump\n");
@ -511,10 +511,10 @@ int main(int argc, char * const argv[]) {
} }
fclose(pfDump); fclose(pfDump);
} }
free(t.sectors); free(t.sectors);
free(d.distances); free(d.distances);
// Reset the "advanced" configuration to normal // Reset the "advanced" configuration to normal
nfc_device_set_property_bool(r.pdi, NP_HANDLE_CRC, true); nfc_device_set_property_bool(r.pdi, NP_HANDLE_CRC, true);
nfc_device_set_property_bool(r.pdi, NP_HANDLE_PARITY, true); nfc_device_set_property_bool(r.pdi, NP_HANDLE_PARITY, true);
@ -609,14 +609,14 @@ void mf_select_tag(nfc_device* pdi, nfc_target* pnt) {
int trailer_block(uint32_t block) int trailer_block(uint32_t block)
{ {
// Test if we are in the small or big sectors // Test if we are in the small or big sectors
return (block < 128) ? ((block + 1) % 4 == 0) : ((block + 1) % 16 == 0); return (block < 128) ? ((block + 1) % 4 == 0) : ((block + 1) % 16 == 0);
} }
// Return position of sector if it is encrypted with the default key otherwise exit.. // Return position of sector if it is encrypted with the default key otherwise exit..
int find_exploit_sector(mftag t) { int find_exploit_sector(mftag t) {
int i; int i;
bool interesting = false; bool interesting = false;
for (i = 0; i < t.num_sectors; i++) { for (i = 0; i < t.num_sectors; i++) {
if (!t.sectors[i].foundKeyA || !t.sectors[i].foundKeyB) { if (!t.sectors[i].foundKeyA || !t.sectors[i].foundKeyB) {
interesting = true; interesting = true;
@ -655,32 +655,32 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
struct Crypto1State* revstate_start; struct Crypto1State* revstate_start;
uint64_t lfsr; uint64_t lfsr;
// Possible key counter, just continue with a previous "session" // Possible key counter, just continue with a previous "session"
uint32_t kcount = pk->size; uint32_t kcount = pk->size;
uint8_t Nr[4] = { 0x00,0x00,0x00,0x00 }; // Reader nonce uint8_t Nr[4] = { 0x00,0x00,0x00,0x00 }; // Reader nonce
uint8_t Auth[4] = { 0x00, t.sectors[e_sector].trailer, 0x00, 0x00 }; uint8_t Auth[4] = { 0x00, t.sectors[e_sector].trailer, 0x00, 0x00 };
uint8_t AuthEnc[4] = { 0x00, t.sectors[e_sector].trailer, 0x00, 0x00 }; uint8_t AuthEnc[4] = { 0x00, t.sectors[e_sector].trailer, 0x00, 0x00 };
uint8_t AuthEncPar[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8_t AuthEncPar[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t ArEnc[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8_t ArEnc[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t ArEncPar[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8_t ArEncPar[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t Rx[MAX_FRAME_LEN]; // Tag response uint8_t Rx[MAX_FRAME_LEN]; // Tag response
uint8_t RxPar[MAX_FRAME_LEN]; // Tag response uint8_t RxPar[MAX_FRAME_LEN]; // Tag response
size_t RxLen; size_t RxLen;
uint32_t Nt, NtLast, NtProbe, NtEnc, Ks1; uint32_t Nt, NtLast, NtProbe, NtEnc, Ks1;
int i, m; int i, m;
// Prepare AUTH command // Prepare AUTH command
Auth[0] = (t.sectors[e_sector].foundKeyA) ? 0x60 : 0x61; Auth[0] = (t.sectors[e_sector].foundKeyA) ? 0x60 : 0x61;
iso14443a_crc_append (Auth,2); iso14443a_crc_append (Auth,2);
// fprintf(stdout, "\nAuth command:\t"); // fprintf(stdout, "\nAuth command:\t");
// print_hex(Auth, 4); // print_hex(Auth, 4);
// We need full control over the CRC // We need full control over the CRC
if (nfc_device_set_property_bool(r.pdi, NP_HANDLE_CRC, false) < 0) { if (nfc_device_set_property_bool(r.pdi, NP_HANDLE_CRC, false) < 0) {
nfc_perror (r.pdi, "nfc_device_set_property_bool crc"); nfc_perror (r.pdi, "nfc_device_set_property_bool crc");
@ -704,10 +704,10 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
// print_hex(Rx, 4); // print_hex(Rx, 4);
// Save the tag nonce (Nt) // Save the tag nonce (Nt)
Nt = bytes_to_num(Rx, 4); Nt = bytes_to_num(Rx, 4);
// Init the cipher with key {0..47} bits // Init the cipher with key {0..47} bits
if (t.sectors[e_sector].foundKeyA) { if (t.sectors[e_sector].foundKeyA) {
pcs = crypto1_create(bytes_to_num(t.sectors[e_sector].KeyA, 6)); pcs = crypto1_create(bytes_to_num(t.sectors[e_sector].KeyA, 6));
@ -717,7 +717,7 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
// Load (plain) uid^nt into the cipher {48..79} bits // Load (plain) uid^nt into the cipher {48..79} bits
crypto1_word(pcs, bytes_to_num(Rx, 4) ^ t.uid, 0); crypto1_word(pcs, bytes_to_num(Rx, 4) ^ t.uid, 0);
// Generate (encrypted) nr+parity by loading it into the cipher // Generate (encrypted) nr+parity by loading it into the cipher
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
// Load in, and encrypt the reader nonce (Nr) // Load in, and encrypt the reader nonce (Nr)
@ -734,7 +734,7 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
ArEnc[i] = crypto1_byte(pcs, 0x00, 0) ^ (Nt&0xff); ArEnc[i] = crypto1_byte(pcs, 0x00, 0) ^ (Nt&0xff);
ArEncPar[i] = filter(pcs->odd) ^ oddparity(Nt); ArEncPar[i] = filter(pcs->odd) ^ oddparity(Nt);
} }
// Finally we want to send arbitrary parity bits // Finally we want to send arbitrary parity bits
if (nfc_device_set_property_bool(r.pdi, NP_HANDLE_PARITY, false) < 0) { if (nfc_device_set_property_bool(r.pdi, NP_HANDLE_PARITY, false) < 0) {
nfc_perror (r.pdi, "nfc_device_set_property_bool parity"); nfc_perror (r.pdi, "nfc_device_set_property_bool parity");
@ -749,11 +749,11 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
ERR ("Reader-answer transfer error, exiting.."); ERR ("Reader-answer transfer error, exiting..");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
// Now print the answer from the tag // Now print the answer from the tag
// fprintf(stdout, "\t{At}:\t"); // fprintf(stdout, "\t{At}:\t");
// print_hex_par(Rx,RxLen,RxPar); // print_hex_par(Rx,RxLen,RxPar);
// Decrypt the tag answer and verify that suc3(Nt) is At // Decrypt the tag answer and verify that suc3(Nt) is At
Nt = prng_successor(Nt, 32); Nt = prng_successor(Nt, 32);
if (!((crypto1_word(pcs, 0x00, 0) ^ bytes_to_num(Rx, 4)) == (Nt&0xFFFFFFFF))) { if (!((crypto1_word(pcs, 0x00, 0) ^ bytes_to_num(Rx, 4)) == (Nt&0xFFFFFFFF))) {
@ -761,7 +761,7 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
// fprintf(stdout, "Authentication completed.\n\n"); // fprintf(stdout, "Authentication completed.\n\n");
// If we are in "Get Distances" mode // If we are in "Get Distances" mode
if (mode == 'd') { if (mode == 'd') {
for (m = 0; m < d->num_distances; m++) { for (m = 0; m < d->num_distances; m++) {
@ -779,18 +779,18 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
// Decrypt the encrypted auth // Decrypt the encrypted auth
if (t.sectors[e_sector].foundKeyA) { if (t.sectors[e_sector].foundKeyA) {
pcs = crypto1_create(bytes_to_num(t.sectors[e_sector].KeyA, 6)); pcs = crypto1_create(bytes_to_num(t.sectors[e_sector].KeyA, 6));
} else { } else {
pcs = crypto1_create(bytes_to_num(t.sectors[e_sector].KeyB, 6)); pcs = crypto1_create(bytes_to_num(t.sectors[e_sector].KeyB, 6));
} }
NtLast = bytes_to_num(Rx, 4) ^ crypto1_word(pcs, bytes_to_num(Rx, 4) ^ t.uid, 1); NtLast = bytes_to_num(Rx, 4) ^ crypto1_word(pcs, bytes_to_num(Rx, 4) ^ t.uid, 1);
// Save the determined nonces distance // Save the determined nonces distance
d->distances[m] = nonce_distance(Nt, NtLast); d->distances[m] = nonce_distance(Nt, NtLast);
// fprintf(stdout, "distance: %05d\n", d->distances[m]); // fprintf(stdout, "distance: %05d\n", d->distances[m]);
// Again, prepare and send {At} // Again, prepare and send {At}
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
ArEnc[i] = crypto1_byte(pcs, Nr[i], 0) ^ Nr[i]; ArEnc[i] = crypto1_byte(pcs, Nr[i], 0) ^ Nr[i];
@ -813,19 +813,19 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} // Next auth probe } // Next auth probe
// Find median from all distances // Find median from all distances
d->median = median(*d); d->median = median(*d);
//fprintf(stdout, "Median: %05d\n", d->median); //fprintf(stdout, "Median: %05d\n", d->median);
} // The end of Get Distances mode } // The end of Get Distances mode
// If we are in "Get Recovery" mode // If we are in "Get Recovery" mode
if (mode == 'r') { if (mode == 'r') {
// Again, prepare the Auth command with MC_AUTH_A, recover the block and CRC // Again, prepare the Auth command with MC_AUTH_A, recover the block and CRC
Auth[0] = dumpKeysA ? 0x60 : 0x61; Auth[0] = dumpKeysA ? 0x60 : 0x61;
Auth[1] = a_sector; Auth[1] = a_sector;
iso14443a_crc_append (Auth,2); iso14443a_crc_append (Auth,2);
// Encryption of the Auth command, sending the Auth command // Encryption of the Auth command, sending the Auth command
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
AuthEnc[i] = crypto1_byte(pcs,0x00,0) ^ Auth[i]; AuthEnc[i] = crypto1_byte(pcs,0x00,0) ^ Auth[i];
@ -847,23 +847,23 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
nfc_perror (r.pdi, "nfc_device_set_property_bool crc restore M"); nfc_perror (r.pdi, "nfc_device_set_property_bool crc restore M");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
// Save the encrypted nonce // Save the encrypted nonce
NtEnc = bytes_to_num(Rx, 4); NtEnc = bytes_to_num(Rx, 4);
// Parity validity check // Parity validity check
for (i = 0; i < 3; ++i) { for (i = 0; i < 3; ++i) {
d->parity[i] = (oddparity(Rx[i]) != RxPar[i]); d->parity[i] = (oddparity(Rx[i]) != RxPar[i]);
} }
// Iterate over Nt-x, Nt+x // Iterate over Nt-x, Nt+x
// fprintf(stdout, "Iterate from %d to %d\n", d->median-TOLERANCE, d->median+TOLERANCE); // fprintf(stdout, "Iterate from %d to %d\n", d->median-TOLERANCE, d->median+TOLERANCE);
NtProbe = prng_successor(Nt, d->median-d->tolerance); NtProbe = prng_successor(Nt, d->median-d->tolerance);
for (m = d->median-d->tolerance; m <= d->median+d->tolerance; m +=2) { for (m = d->median-d->tolerance; m <= d->median+d->tolerance; m +=2) {
// Try to recover the keystream1 // Try to recover the keystream1
Ks1 = NtEnc ^ NtProbe; Ks1 = NtEnc ^ NtProbe;
// Skip this nonce after invalid 3b parity check // Skip this nonce after invalid 3b parity check
revstate_start = NULL; revstate_start = NULL;
if (valid_nonce(NtProbe, NtEnc, Ks1, d->parity)) { if (valid_nonce(NtProbe, NtEnc, Ks1, d->parity)) {
@ -881,7 +881,7 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
// fprintf(stdout, "New chunk by %d, sizeof %lu\n", kcount, pk->size * sizeof(uint64_t)); // fprintf(stdout, "New chunk by %d, sizeof %lu\n", kcount, pk->size * sizeof(uint64_t));
pk->possibleKeys = (uint64_t *) realloc((void *)pk->possibleKeys, pk->size * sizeof(uint64_t)); pk->possibleKeys = (uint64_t *) realloc((void *)pk->possibleKeys, pk->size * sizeof(uint64_t));
if (pk->possibleKeys == NULL) { if (pk->possibleKeys == NULL) {
ERR ("Memory allocation error for pk->possibleKeys"); ERR ("Memory allocation error for pk->possibleKeys");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} }
@ -897,9 +897,9 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
if (kcount != 0) { if (kcount != 0) {
pk->size = --kcount; pk->size = --kcount;
if ((pk->possibleKeys = (uint64_t *) realloc((void *)pk->possibleKeys, pk->size * sizeof(uint64_t))) == NULL) { if ((pk->possibleKeys = (uint64_t *) realloc((void *)pk->possibleKeys, pk->size * sizeof(uint64_t))) == NULL) {
ERR ("Memory allocation error for pk->possibleKeys"); ERR ("Memory allocation error for pk->possibleKeys");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
} }
} }
crypto1_destroy(pcs); crypto1_destroy(pcs);
@ -910,7 +910,7 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
uint32_t median(denonce d) { uint32_t median(denonce d) {
int middle = (int) d.num_distances / 2; int middle = (int) d.num_distances / 2;
qsort(d.distances, d.num_distances, sizeof(uint32_t), compar_int); qsort(d.distances, d.num_distances, sizeof(uint32_t), compar_int);
if (d.num_distances % 2 == 1) { if (d.num_distances % 2 == 1) {
// Odd number of elements // Odd number of elements
return d.distances[middle]; return d.distances[middle];
@ -933,17 +933,17 @@ countKeys * uniqsort(uint64_t * possibleKeys, uint32_t size) {
unsigned int i, j = 0; unsigned int i, j = 0;
int count = 0; int count = 0;
countKeys *our_counts; countKeys *our_counts;
qsort(possibleKeys, size, sizeof (uint64_t), compar_int); qsort(possibleKeys, size, sizeof (uint64_t), compar_int);
our_counts = calloc(size, sizeof(countKeys)); our_counts = calloc(size, sizeof(countKeys));
if (our_counts == NULL) { if (our_counts == NULL) {
ERR ("Memory allocation error for our_counts"); ERR ("Memory allocation error for our_counts");
exit (EXIT_FAILURE); exit (EXIT_FAILURE);
} }
for (i = 0; i < size; i++) { for (i = 0; i < size; i++) {
if (possibleKeys[i+1] == possibleKeys[i]) { if (possibleKeys[i+1] == possibleKeys[i]) {
count++; count++;
} else { } else {
our_counts[j].key = possibleKeys[i]; our_counts[j].key = possibleKeys[i];

View file

@ -30,15 +30,15 @@ typedef struct {
bool foundKeyB; bool foundKeyB;
uint8_t trailer; // Value of a trailer block uint8_t trailer; // Value of a trailer block
} sector; } sector;
typedef struct { typedef struct {
uint32_t *distances; uint32_t *distances;
uint32_t median; uint32_t median;
uint32_t num_distances; uint32_t num_distances;
uint32_t tolerance; uint32_t tolerance;
uint8_t parity[3]; // used for 3 bits of parity information uint8_t parity[3]; // used for 3 bits of parity information
} denonce; // Revealed information about nonce } denonce; // Revealed information about nonce
typedef struct { typedef struct {
nfc_target nt; nfc_target nt;
sector * sectors; // Allocate later, we do not know the number of sectors yet sector * sectors; // Allocate later, we do not know the number of sectors yet
@ -46,9 +46,9 @@ typedef struct {
uint8_t num_sectors; uint8_t num_sectors;
uint8_t num_blocks; uint8_t num_blocks;
uint32_t uid; uint32_t uid;
bool b4K; bool b4K;
} mftag; } mftag;
typedef struct { typedef struct {
uint64_t *possibleKeys; uint64_t *possibleKeys;
uint32_t size; uint32_t size;

View file

@ -1,13 +1,13 @@
/*- /*-
* Public platform independent Near Field Communication (NFC) library examples * Public platform independent Near Field Communication (NFC) library examples
* *
* Copyright (C) 2009, Roel Verdult * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière * Copyright (C) 2010, Romuald Conty, Romain Tartière
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -23,11 +23,14 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */
/**
* @file mifare.c
* @brief provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
*/
#include "mifare.h" #include "mifare.h"
#include <string.h> #include <string.h>
@ -42,13 +45,13 @@
* The specified MIFARE command will be executed on the tag. There are different commands possible, they all require the destination block number. * The specified MIFARE command will be executed on the tag. There are different commands possible, they all require the destination block number.
* @note There are three different types of information (Authenticate, Data and Value). * @note There are three different types of information (Authenticate, Data and Value).
* *
* First an authentication must take place using Key A or B. It requires a 48 bit Key (6 bytes) and the UID. * First an authentication must take place using Key A or B. It requires a 48 bit Key (6 bytes) and the UID.
* They are both used to initialize the internal cipher-state of the PN53X chip (http://libnfc.org/hardware/pn53x-chip). * They are both used to initialize the internal cipher-state of the PN53X chip (http://libnfc.org/hardware/pn53x-chip).
* After a successful authentication it will be possible to execute other commands (e.g. Read/Write). * After a successful authentication it will be possible to execute other commands (e.g. Read/Write).
* The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process. * The MIFARE Classic Specification (http://www.nxp.com/acrobat/other/identification/M001053_MF1ICS50_rev5_3.pdf) explains more about this process.
*/ */
bool bool
nfc_initiator_mifare_cmd (nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp) nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp)
{ {
uint8_t abtRx[265]; uint8_t abtRx[265];
size_t szParamLen; size_t szParamLen;
@ -59,56 +62,56 @@ nfc_initiator_mifare_cmd (nfc_device *pnd, const mifare_cmd mc, const uint8_t ui
abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff) abtCmd[1] = ui8Block; // The block address (1K=0x00..0x39, 4K=0x00..0xff)
switch (mc) { switch (mc) {
// Read and store command have no parameter // Read and store command have no parameter
case MC_READ: case MC_READ:
case MC_STORE: case MC_STORE:
szParamLen = 0; szParamLen = 0;
break; break;
// Authenticate command // Authenticate command
case MC_AUTH_A: case MC_AUTH_A:
case MC_AUTH_B: case MC_AUTH_B:
szParamLen = sizeof (struct mifare_param_auth); szParamLen = sizeof(struct mifare_param_auth);
break; break;
// Data command // Data command
case MC_WRITE: case MC_WRITE:
szParamLen = sizeof (struct mifare_param_data); szParamLen = sizeof(struct mifare_param_data);
break; break;
// Value command // Value command
case MC_DECREMENT: case MC_DECREMENT:
case MC_INCREMENT: case MC_INCREMENT:
case MC_TRANSFER: case MC_TRANSFER:
szParamLen = sizeof (struct mifare_param_value); szParamLen = sizeof(struct mifare_param_value);
break; break;
// Please fix your code, you never should reach this statement // Please fix your code, you never should reach this statement
default: default:
return false; return false;
break; break;
} }
// When available, copy the parameter bytes // When available, copy the parameter bytes
if (szParamLen) if (szParamLen)
memcpy (abtCmd + 2, (uint8_t *) pmp, szParamLen); memcpy(abtCmd + 2, (uint8_t *) pmp, szParamLen);
// FIXME: Save and restore bEasyFraming // FIXME: Save and restore bEasyFraming
// bEasyFraming = nfc_device_get_property_bool (pnd, NP_EASY_FRAMING, &bEasyFraming); // bEasyFraming = nfc_device_get_property_bool (pnd, NP_EASY_FRAMING, &bEasyFraming);
if (nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, true) < 0) { if (nfc_device_set_property_bool(pnd, NP_EASY_FRAMING, true) < 0) {
nfc_perror (pnd, "nfc_device_set_property_bool"); nfc_perror(pnd, "nfc_device_set_property_bool");
return false; return false;
} }
// Fire the mifare command // Fire the mifare command
int res; int res;
if ((res = nfc_initiator_transceive_bytes (pnd, abtCmd, 2 + szParamLen, abtRx, sizeof(abtRx), -1)) < 0) { if ((res = nfc_initiator_transceive_bytes(pnd, abtCmd, 2 + szParamLen, abtRx, sizeof(abtRx), -1)) < 0) {
if (res == NFC_ERFTRANS) { if (res == NFC_ERFTRANS) {
// "Invalid received frame", usual means we are // "Invalid received frame", usual means we are
// authenticated on a sector but the requested MIFARE cmd (read, write) // authenticated on a sector but the requested MIFARE cmd (read, write)
// is not permitted by current acces bytes; // is not permitted by current acces bytes;
// So there is nothing to do here. // So there is nothing to do here.
} else { } else {
nfc_perror (pnd, "nfc_initiator_transceive_bytes"); nfc_perror(pnd, "nfc_initiator_transceive_bytes");
} }
// XXX nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming); // XXX nfc_device_set_property_bool (pnd, NP_EASY_FRAMING, bEasyFraming);
return false; return false;
@ -123,7 +126,7 @@ nfc_initiator_mifare_cmd (nfc_device *pnd, const mifare_cmd mc, const uint8_t ui
// When we have executed a read command, copy the received bytes into the param // When we have executed a read command, copy the received bytes into the param
if (mc == MC_READ) { if (mc == MC_READ) {
if (res == 16) { if (res == 16) {
memcpy (pmp->mpd.abtData, abtRx, 16); memcpy(pmp->mpd.abtData, abtRx, 16);
} else { } else {
return false; return false;
} }

View file

@ -1,13 +1,13 @@
/*- /*-
* Public platform independent Near Field Communication (NFC) library examples * Public platform independent Near Field Communication (NFC) library examples
* *
* Copyright (C) 2009, Roel Verdult * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière * Copyright (C) 2010, Romuald Conty, Romain Tartière
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -23,13 +23,13 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */
/** /**
* @file mifaretag.h * @file mifare.h
* @brief provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc * @brief provide samples structs and functions to manipulate MIFARE Classic and Ultralight tags using libnfc
*/ */
@ -75,7 +75,7 @@ typedef union {
// Reset struct alignment to default // Reset struct alignment to default
# pragma pack() # pragma pack()
bool nfc_initiator_mifare_cmd (nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp); bool nfc_initiator_mifare_cmd(nfc_device *pnd, const mifare_cmd mc, const uint8_t ui8Block, mifare_param *pmp);
// Compiler directive, set struct alignment to 1 uint8_t for compatibility // Compiler directive, set struct alignment to 1 uint8_t for compatibility
# pragma pack(1) # pragma pack(1)

View file

@ -1,13 +1,13 @@
/*- /*-
* Public platform independent Near Field Communication (NFC) library examples * Public platform independent Near Field Communication (NFC) library examples
* *
* Copyright (C) 2009, Roel Verdult * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière * Copyright (C) 2010, Romuald Conty, Romain Tartière
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -23,7 +23,7 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */

View file

@ -1,13 +1,13 @@
/*- /*-
* Public platform independent Near Field Communication (NFC) library examples * Public platform independent Near Field Communication (NFC) library examples
* *
* Copyright (C) 2009, Roel Verdult * Copyright (C) 2009, Roel Verdult
* Copyright (C) 2010, Romuald Conty, Romain Tartière * Copyright (C) 2010, Romuald Conty, Romain Tartière
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* 1) Redistributions of source code must retain the above copyright notice, * 1) Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* 2 )Redistributions in binary form must reproduce the above copyright * 2 )Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
@ -23,7 +23,7 @@
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
* *
* Note that this license only applies on the examples, NFC library itself is under LGPL * Note that this license only applies on the examples, NFC library itself is under LGPL
* *
*/ */