Merge 1e9d1783097b3d71333c031558cbeed159296919 into ba072f16f6b2a655d51da2171ecfb83e26c0ef58

This commit is contained in:
puppywang 2020-11-17 15:59:05 +08:00 committed by GitHub
commit 412f9f9c6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -147,7 +147,7 @@ int main(int argc, char *const argv[])
ERR("The number of probes must be a positive number");
exit(EXIT_FAILURE);
}
// fprintf(stdout, "Number of probes: %d\n", probes);
fprintf(stdout, "Number of probes: %d\n", probes);
break;
case 'T': {
int res;
@ -157,7 +157,7 @@ int main(int argc, char *const argv[])
exit(EXIT_FAILURE);
}
d.tolerance = (uint32_t)res;
// fprintf(stdout, "Tolerance number: %d\n", probes);
fprintf(stdout, "Tolerance number: %d\n", probes);
}
break;
case 'f':
@ -213,7 +213,7 @@ int main(int argc, char *const argv[])
fprintf(stderr, "Cannot open: %s, exiting\n", optarg);
exit(EXIT_FAILURE);
}
// fprintf(stdout, "Output file: %s\n", optarg);
fprintf(stdout, "Output file: %s\n", optarg);
break;
case 'h':
usage(stdout, 0);
@ -232,29 +232,7 @@ int main(int argc, char *const argv[])
// Initialize reader/tag structures
mf_init(&r);
if (nfc_initiator_init(r.pdi) < 0) {
nfc_perror(r.pdi, "nfc_initiator_init");
goto error;
}
// Drop the field for a while, so can be reset
if (nfc_device_set_property_bool(r.pdi, NP_ACTIVATE_FIELD, true) < 0) {
nfc_perror(r.pdi, "nfc_device_set_property_bool activate field");
goto error;
}
// Let the reader only try once to find a tag
if (nfc_device_set_property_bool(r.pdi, NP_INFINITE_SELECT, false) < 0) {
nfc_perror(r.pdi, "nfc_device_set_property_bool infinite select");
goto error;
}
// Configure the CRC and Parity settings
if (nfc_device_set_property_bool(r.pdi, NP_HANDLE_CRC, true) < 0) {
nfc_perror(r.pdi, "nfc_device_set_property_bool crc");
goto error;
}
if (nfc_device_set_property_bool(r.pdi, NP_HANDLE_PARITY, true) < 0) {
nfc_perror(r.pdi, "nfc_device_set_property_bool parity");
goto error;
}
mf_configure(r.pdi);
/*
// wait for tag to appear
@ -285,6 +263,7 @@ int main(int argc, char *const argv[])
case 0x01:
case 0x08:
case 0x88:
case 0x28:
if (get_rats_is_2k(t, r)) {
printf("Found Mifare Plus 2k tag\n");
t.num_sectors = NR_TRAILERS_2k;
@ -575,7 +554,7 @@ int main(int argc, char *const argv[])
// We don't known this key, try to break it
// This key can be found here two or more times
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
num_to_bytes(ck[i].key, 6, mp.mpa.abtKey);
mc = dumpKeysA ? MC_AUTH_A : MC_AUTH_B;
@ -819,6 +798,11 @@ void mf_configure(nfc_device *pdi)
nfc_perror(pdi, "nfc_device_set_property_bool parity");
exit(EXIT_FAILURE);
}
// Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
if (nfc_device_set_property_bool(pdi, NP_AUTO_ISO14443_4, false) < 0) {
nfc_perror(pdi, "nfc_device_set_property_bool");
exit(EXIT_FAILURE);
}
// Enable the field so more power consuming cards can power themselves up
if (nfc_device_set_property_bool(pdi, NP_ACTIVATE_FIELD, true) < 0) {
nfc_perror(pdi, "nfc_device_set_property_bool activate field");
@ -915,6 +899,7 @@ get_rats_is_2k(mftag t, mfreader r)
&& (abtRx[7] == 0x2f) && (abtRx[8] == 0x2f)
&& ((t.nt.nti.nai.abtAtqa[1] & 0x02) == 0x00));
} else {
printf("ATS len = %d\n", res);
return false;
}
}
@ -944,13 +929,14 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
uint32_t Nt, NtLast, NtProbe, NtEnc, Ks1;
int i;
int res;
uint32_t m;
// Prepare AUTH command
Auth[0] = (t.sectors[e_sector].foundKeyA) ? MC_AUTH_A : MC_AUTH_B;
iso14443a_crc_append(Auth, 2);
// fprintf(stdout, "\nAuth command:\t");
// print_hex(Auth, 4);
fprintf(stdout, "\nMode: %c, Auth command:\t", mode);
print_hex(Auth, 4);
// We need full control over the CRC
if (nfc_device_set_property_bool(r.pdi, NP_HANDLE_CRC, false) < 0) {
@ -965,8 +951,8 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
exit(EXIT_FAILURE);
}
if (nfc_initiator_transceive_bytes(r.pdi, Auth, 4, Rx, sizeof(Rx), 0) < 0) {
fprintf(stdout, "Error while requesting plain tag-nonce\n");
if ((res = nfc_initiator_transceive_bytes(r.pdi, Auth, 4, Rx, sizeof(Rx), 0)) < 0) {
fprintf(stdout, "Error while requesting plain tag-nonce, %d\n", res);
exit(EXIT_FAILURE);
}
@ -974,10 +960,10 @@ 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");
exit(EXIT_FAILURE);
}
// print_hex(Rx, 4);
print_hex(Rx, res);
// Save the tag nonce (Nt)
Nt = bytes_to_num(Rx, 4);
Nt = bytes_to_num(Rx, res);
// Init the cipher with key {0..47} bits
if (t.sectors[e_sector].foundKeyA) {
@ -987,7 +973,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
crypto1_word(pcs, bytes_to_num(Rx, 4) ^ t.authuid, 0);
crypto1_word(pcs, bytes_to_num(Rx, res) ^ t.authuid, 0);
// Generate (encrypted) nr+parity by loading it into the cipher
for (i = 0; i < 4; i++) {
@ -1013,17 +999,16 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
}
// Transmit reader-answer
// fprintf(stdout, "\t{Ar}:\t");
// print_hex_par(ArEnc, 64, ArEncPar);
int res;
fprintf(stdout, "\t{Ar}:\t");
print_hex_par(ArEnc, 64, ArEncPar);
if (((res = nfc_initiator_transceive_bits(r.pdi, ArEnc, 64, ArEncPar, Rx, sizeof(Rx), RxPar)) < 0) || (res != 32)) {
ERR("Reader-answer transfer error, exiting..");
exit(EXIT_FAILURE);
}
// Now print the answer from the tag
// fprintf(stdout, "\t{At}:\t");
// print_hex_par(Rx,RxLen,RxPar);
fprintf(stdout, "\t{At}:\t");
print_hex_par(Rx,res,RxPar);
// Decrypt the tag answer and verify that suc3(Nt) is At
Nt = prng_successor(Nt, 32);
@ -1031,12 +1016,12 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
ERR("[At] is not Suc3(Nt), something is wrong, exiting..");
exit(EXIT_FAILURE);
}
// fprintf(stdout, "Authentication completed.\n\n");
fprintf(stdout, "Authentication completed.\n\n");
// If we are in "Get Distances" mode
if (mode == 'd') {
for (m = 0; m < d->num_distances; m++) {
// fprintf(stdout, "Nested Auth number: %x: ,", m);
fprintf(stdout, "Nested Auth number: %x\n", m);
// Encrypt Auth command with the current keystream
for (i = 0; i < 4; i++) {
AuthEnc[i] = crypto1_byte(pcs, 0x00, 0) ^ Auth[i];
@ -1044,12 +1029,18 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
AuthEncPar[i] = filter(pcs->odd) ^ oddparity(Auth[i]);
}
fprintf(stdout, "\t{AuthEnc}:\t");
print_hex_par(AuthEnc, 64, AuthEncPar);
// Sending the encrypted Auth command
if (nfc_initiator_transceive_bits(r.pdi, AuthEnc, 32, AuthEncPar, Rx, sizeof(Rx), RxPar) < 0) {
if ((res = nfc_initiator_transceive_bits(r.pdi, AuthEnc, 32, AuthEncPar, Rx, sizeof(Rx), RxPar)) < 0) {
fprintf(stdout, "Error requesting encrypted tag-nonce\n");
exit(EXIT_FAILURE);
}
fprintf(stdout, "\t{AuthEnResp}:\t");
print_hex_par(Rx,res,RxPar);
// Decrypt the encrypted auth
if (t.sectors[e_sector].foundKeyA) {
pcs = crypto1_create(bytes_to_num(t.sectors[e_sector].KeyA, 6));
@ -1078,6 +1069,11 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
ArEncPar[i] = filter(pcs->odd) ^ oddparity(Nt);
}
nfc_device_set_property_bool(r.pdi, NP_HANDLE_PARITY, false);
// Transmit reader-answer
fprintf(stdout, "\t{Ar}:\t");
print_hex_par(ArEnc, 64, ArEncPar);
if (((res = nfc_initiator_transceive_bits(r.pdi, ArEnc, 64, ArEncPar, Rx, sizeof(Rx), RxPar)) < 0) || (res != 32)) {
ERR("Reader-answer transfer error, exiting..");
exit(EXIT_FAILURE);
@ -1087,11 +1083,15 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
ERR("[At] is not Suc3(Nt), something is wrong, exiting..");
exit(EXIT_FAILURE);
}
// Now print the answer from the tag
fprintf(stdout, "\t{At}:\t");
print_hex_par(Rx,res,RxPar);
} // Next auth probe
// Find median from all distances
d->median = median(*d);
//fprintf(stdout, "Median: %05d\n", d->median);
fprintf(stdout, "Median: %05d\n", d->median);
} // The end of Get Distances mode
// If we are in "Get Recovery" mode
@ -1132,7 +1132,7 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
}
// 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-d->tolerance, 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) {
@ -1153,7 +1153,7 @@ int mf_enhanced_auth(int e_sector, int a_sector, mftag t, mfreader r, denonce *d
// Allocate a new space for keys
if (((kcount % MEM_CHUNK) == 0) || (kcount >= pk->size)) {
pk->size += MEM_CHUNK;
// 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));
if (pk->possibleKeys == NULL) {
ERR("Memory allocation error for pk->possibleKeys");