43 Commits

Author SHA1 Message Date
iceman1001
d46f80e7ea new desfire ats, based on #PR138 in nfc-tools/libfreefare repository 2021-05-20 06:44:48 +02:00
iceman1001
a0efc7aa02 Merge branch 'master' of github.com:RfidResearchGroup/proxmark3 2021-05-19 18:07:29 +02:00
iceman1001
8bf5a99bca codestyle prefer calloc 2021-05-19 18:07:19 +02:00
Iceman
a469fdd24b Merge pull request #1279 from mwalker33/desfire
Update cmdhfmfdes.c
2021-05-19 12:58:07 +02:00
mwalker33
0c71b6cc32 Update cmdhfmfdes.c
use defines for command 0xc4
2021-05-19 20:57:06 +10:00
mwalker33
c731c945d6 Update cmdhfmfdes.c
Desfire
- Change Key where key to change = key used to authenticate
- Patch to stop an AES key change incorrectly reporting an issue
2021-05-19 20:47:11 +10:00
iceman1001
27dcbb49ec hf 14a raw - now has a verbose parameter and less output normally 2021-05-19 12:18:04 +02:00
iceman1001
03a7109efd fix coverity CID 321717 2021-05-19 10:20:30 +02:00
iceman1001
b822e0e046 fix coverity CID 322764 2021-05-19 10:15:45 +02:00
iceman1001
dfd07ccd69 fix coverity CID 322762 2021-05-19 10:15:10 +02:00
iceman1001
16c43bea2d fix coverity CID 322671, 322668, and time now is zero padded 2021-05-19 10:13:37 +02:00
iceman1001
3d8b165033 fix coverity CID 344398 2021-05-19 09:06:35 +02:00
Philippe Teuwen
2b4d110836 accept multiple commands on prompt 2021-05-19 01:48:43 +02:00
Philippe Teuwen
836e0fa206 accept multiple commands on stdin 2021-05-19 01:19:26 +02:00
Philippe Teuwen
a592b349cb make style 2021-05-18 23:56:11 +02:00
Philippe Teuwen
76adb58feb Merge branch 'mbedtls_2.26.0'
* mbedtls_2.26.0:
  mbedtls: disable timing, unused and needs tuning on ProxSpace
  mbedtls: remove inline on mpi fcts to avoid warning:
  mbedtls: stack warning fix, cf 17bce5fb5a
  mbedtls: memset, cf 996ed197fb
  mbedtls: add secp128r1, cf 996ed197fb
  mbedtls: port previous config
  mbedtls: make style
  mbedtls 2.26.0
2021-05-18 23:52:55 +02:00
Iceman
592b7af837 Merge pull request #1277 from mwalker33/desfire
Update cmdhfmfdes.c
2021-05-18 12:19:45 +02:00
mwalker33
e0269bde74 Update cmdhfmfdes.c
Desfire readdata patch
2021-05-18 19:49:03 +10:00
iceman1001
03a8704e17 text 2021-05-18 09:13:00 +02:00
iceman1001
01154712a9 hf mfu info - search for NeXT implant known pwd 2021-05-17 20:36:03 +02:00
iceman1001
70694ff281 style 2021-05-17 20:35:11 +02:00
Iceman
269983db27 Merge pull request #1276 from mwalker33/desfire
Desfire
2021-05-17 12:10:51 +02:00
mwalker33
cfdef9e92e Update cmdhfmfdes.c
Desfire write MAC'ed and Encrypted update
2021-05-17 19:16:27 +10:00
iceman1001
c56d3dd42e remove unused var 2021-05-16 23:04:48 +02:00
iceman1001
09dc29dd9d fix cppchecker, lesser scope 2021-05-16 23:03:40 +02:00
iceman1001
16783000f0 rework some defines 2021-05-16 23:03:13 +02:00
iceman1001
451de246b7 if client wants to know how much SPIFFS 2021-05-16 23:01:37 +02:00
mwalker33
af59e27643 Update cmdhfmfdes.c
WriteData - Fixed MACed calculation.
- Tested on Plain (free and Authenticated access)
- Authenticated Plain+MAC

Bugfix for write loop for correct data offset etc.
2021-05-16 16:52:53 +10:00
Iceman
30fc94da4c Merge pull request #1275 from tharexde/fix_4x50_standalone
fixed upload of eml files in 4x50 standalone mode
2021-05-15 16:18:52 +02:00
tharexde
2f17034254 fixed evaluation of eml file size 2021-05-15 16:00:33 +02:00
iceman1001
8fa51075fb fix cppchecker unsigned warning 2021-05-15 15:33:11 +02:00
iceman1001
5fdd9ac392 fix cppchecker warnings 2021-05-15 15:23:32 +02:00
iceman1001
228668e7a3 mark as unsigned 2021-05-15 15:20:10 +02:00
iceman1001
7d151057c2 update test for mf_nonce_brute 2021-05-15 10:49:15 +02:00
Iceman
6e28a431cb Merge pull request #1273 from mwalker33/Desfire-List
Update cmdhflist.c
2021-05-15 10:48:48 +02:00
iceman1001
65e4d8e1fa fix thread and clock issues 2021-05-15 10:43:51 +02:00
mwalker33
929ddf0830 Update cmdhflist.c
Display the correct Key No in Annotation
2021-05-15 18:34:30 +10:00
iceman1001
925e672e54 Merge branch 'master' of github.com:RfidResearchGroup/proxmark3 2021-05-15 09:24:48 +02:00
Iceman
71504daea2 Merge pull request #1272 from mwalker33/EM410x-Sim
Update cmdlfem410x.c
2021-05-15 09:24:34 +02:00
mwalker33
2e347393e1 option rename
renamed option to --gap
extended option to em410x reader brute
updated change log
2021-05-15 15:59:43 +10:00
mwalker33
a99eb7bf5b Update cmdlfem410x.c
Draft EM4100 sim fix
2021-05-15 15:31:36 +10:00
iceman1001
e45924b450 moar format, WIP, need more samples 2021-05-14 22:45:57 +02:00
iceman1001
3a920f4e0c unsigned shift 2021-05-14 22:43:08 +02:00
34 changed files with 568 additions and 253 deletions

View File

@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Added '--gap' option to lf em 410x sim for more control over sim data (@mwalker)
- Changed `hf fido` - refactored load/save json objects (@iceman1001)
- Moved / renamed `fido2.json` -> `client/resource/fido2_defparams.json` (@iceman1001)
- Added openocd shikra support based on @ninjastyle82 patch to deprecated iceman fork (@iceman1001)

View File

@@ -102,7 +102,7 @@ static bool get_input_data_from_file(uint32_t *tag, char *inputfile) {
rdv40_spiffs_read_as_filetype(inputfile, mem, size, RDV40_SPIFFS_SAFETY_SAFE);
now = size / 9;
now = (size + 1) / 9;
for (int i = 0; i < now; i++) {
for (int j = 0; j < 4; j++) {
tag[i] |= (hex2int(mem[2 * j + 9 * i]) << 4 | hex2int(mem[2 * j + 1 + 9 * i])) << ((3 - j) * 8);

View File

@@ -472,6 +472,7 @@ int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
// Perform the PACE protocol by replaying given APDUs
//-----------------------------------------------------------------------------
void EPA_PACE_Replay(PacketCommandNG *c) {
uint32_t timings[ARRAYLEN(apdu_lengths_replay)] = {0};
// if an APDU has been passed, save it

View File

@@ -319,7 +319,7 @@ void BootROM(void) {
if ((common_area.command == COMMON_AREA_COMMAND_ENTER_FLASH_MODE) ||
(!common_area.flags.button_pressed && BUTTON_PRESS()) ||
(*(uint32_t*)_osimage_entry == 0xffffffffU)) {
(*(uint32_t *)_osimage_entry == 0xffffffffU)) {
flash_mode();
} else {
// clear button status, even if button still pressed

View File

@@ -12,9 +12,9 @@
#include "cmddata.h"
#include <stdio.h>
#include <string.h>
#include <limits.h> // for CmdNorm INT_MIN && INT_MAX
#include <math.h> // pow
#include <ctype.h> // tolower
#include <limits.h> // for CmdNorm INT_MIN && INT_MAX
#include <math.h> // pow
#include <ctype.h> // tolower
#include "commonutil.h" // ARRAYLEN
#include "cmdparser.h" // for command_t
#include "ui.h" // for show graph controls
@@ -28,7 +28,7 @@
#include "mifare/ndef.h"
#include "cliparser.h"
#include "cmdlft55xx.h" // print...
#include "crypto/asn1utils.h" // ASN1 decode / print
#include "crypto/asn1utils.h" // ASN1 decode / print
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
size_t DemodBufferLen = 0;

View File

@@ -474,13 +474,13 @@ static int CmdFlashMemInfo(const char *Cmd) {
// load private
res = mbedtls_pk_parse_keyfile(&pkctx, path, NULL);
free(path);
//res = mbedtls_pk_parse_public_keyfile(&pkctx, path);
if (res == 0) {
PrintAndLogEx(NORMAL, " ( " _GREEN_("ok") " )");
} else {
PrintAndLogEx(NORMAL, " ( " _RED_("fail") " )");
mbedtls_pk_free(&pkctx);
free(path);
return PM3_EFILE;
}
@@ -489,7 +489,6 @@ static int CmdFlashMemInfo(const char *Cmd) {
PrintAndLogEx(FAILED, "failed to allocate rsa context memory");
return PM3_EMALLOC;
}
free(path);
got_private = true;
} else {

View File

@@ -33,7 +33,7 @@
bool APDUInFramingEnable = true;
static int CmdHelp(const char *Cmd);
static int waitCmd(bool i_select, uint32_t timeout);
static int waitCmd(bool i_select, uint32_t timeout, bool verbose);
static const manufactureName manufactureMapping[] = {
// ID, "Vendor Country"
@@ -1187,7 +1187,6 @@ static int CmdHF14AAPDU(const char *Cmd) {
}
static int CmdHF14ACmdRaw(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a raw",
"Sends raw bytes over ISO14443a. With option to use TOPAZ 14a mode.",
@@ -1205,13 +1204,13 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
arg_lit0("r", NULL, "do not read response"),
arg_lit0("s", NULL, "active signal field ON with select"),
arg_int0("t", "timeout", "<ms>", "timeout in milliseconds"),
arg_lit0("v", "verbose", "Verbose output"),
arg_lit0(NULL, "topaz", "use Topaz protocol to send command"),
arg_strx1(NULL, NULL, "<hex>", "raw bytes to send"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
bool active = arg_get_lit(ctx, 1);
uint16_t numbits = (uint16_t)arg_get_int_def(ctx, 2, 0);
bool crc = arg_get_lit(ctx, 3);
@@ -1220,11 +1219,12 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
bool reply = (arg_get_lit(ctx, 6) == false);
bool active_select = arg_get_lit(ctx, 7);
uint32_t timeout = (uint32_t)arg_get_int_def(ctx, 8, 0);
bool topazmode = arg_get_lit(ctx, 9);
bool verbose = arg_get_lit(ctx, 9);
bool topazmode = arg_get_lit(ctx, 10);
int datalen = 0;
uint8_t data[PM3_CMD_DATA_SIZE];
CLIGetHexWithReturn(ctx, 10, data, &datalen);
CLIGetHexWithReturn(ctx, 11, data, &datalen);
CLIParserFree(ctx);
bool bTimeout = (timeout) ? true : false;
@@ -1290,14 +1290,14 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
if (reply) {
int res = 0;
if (active_select)
res = waitCmd(true, timeout);
res = waitCmd(true, timeout, verbose);
if (res == PM3_SUCCESS && datalen > 0)
waitCmd(false, timeout);
waitCmd(false, timeout, verbose);
}
return PM3_SUCCESS;
}
static int waitCmd(bool i_select, uint32_t timeout) {
static int waitCmd(bool i_select, uint32_t timeout, bool verbose) {
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, timeout + 1500)) {
@@ -1305,16 +1305,24 @@ static int waitCmd(bool i_select, uint32_t timeout) {
if (i_select) {
len = (resp.oldarg[1] & 0xFFFF);
if (len) {
PrintAndLogEx(SUCCESS, "Card selected. UID[%u]:", len);
if (verbose) {
PrintAndLogEx(SUCCESS, "Card selected. UID[%u]:", len);
} else {
return PM3_SUCCESS;
}
} else {
PrintAndLogEx(WARNING, "Can't select card.");
}
} else {
PrintAndLogEx(SUCCESS, "received " _YELLOW_("%u") " bytes", len);
if (verbose) {
PrintAndLogEx(SUCCESS, "received " _YELLOW_("%u") " bytes", len);
}
}
if (!len)
if (len == 0) {
return PM3_ESOFT;
}
uint8_t *data = resp.data.asBytes;

View File

@@ -1051,8 +1051,6 @@ static bool emrtd_connect(bool *use_14b) {
}
static bool emrtd_do_auth(char *documentnumber, char *dob, char *expiry, bool BAC_available, bool *BAC, uint8_t *ssc, uint8_t *ks_enc, uint8_t *ks_mac, bool *use_14b) {
uint8_t response[EMRTD_MAX_FILE_SIZE] = { 0x00 };
int resplen = 0;
// Select MRTD applet
if (emrtd_select_file(EMRTD_P1_SELECT_BY_NAME, EMRTD_AID_MRTD, *use_14b) == false) {
@@ -1069,6 +1067,8 @@ static bool emrtd_do_auth(char *documentnumber, char *dob, char *expiry, bool BA
// Select EF_DG1
emrtd_select_file(EMRTD_P1_SELECT_BY_EF, dg_table[EF_DG1].fileid, *use_14b);
int resplen = 0;
uint8_t response[EMRTD_MAX_FILE_SIZE] = { 0x00 };
if (emrtd_read_file(response, &resplen, NULL, NULL, NULL, false, *use_14b) == false) {
*BAC = true;
PrintAndLogEx(INFO, "Authentication is enforced. Will attempt external authentication.");
@@ -1090,7 +1090,6 @@ static bool emrtd_do_auth(char *documentnumber, char *dob, char *expiry, bool BA
return false;
}
}
return true;
}
@@ -1760,6 +1759,7 @@ static int emrtd_parse_ef_sod_hashes(uint8_t *data, size_t datalen, uint8_t *has
case 0x30: {
// iceman: if these two calls fails, feels like we should have a better check in place
bool res = emrtd_lds_get_data_by_tag(hashlist + offset + e_fieldlen + 1, e_datalen, hashidstr, &hashidstrlen, 0x02, 0x00, false, false, 0);
(void)res;
res = emrtd_lds_get_data_by_tag(hashlist + offset + e_fieldlen + 1, e_datalen, hash, &hashlen, 0x04, 0x00, false, false, 0);
(void)res;
if (hashlen <= 64) {

View File

@@ -1217,11 +1217,10 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
mbedtls_des3_context ctx;
mbedtls_des3_set2key_dec(&ctx, key);
uint8_t dec_data[8] = {0};
// decrypt user supplied data
if (have_data) {
uint8_t dec_data[8] = {0};
if (use_sc) {
Decrypt(enc_data, dec_data);
} else {

View File

@@ -870,13 +870,13 @@ void annotateMfDesfire(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
snprintf(exp, size, "DELETE FILE");
break;
case MFDES_AUTHENTICATE:
snprintf(exp, size, "AUTH NATIVE (keyNo %d)", cmd[pos + 1]);
snprintf(exp, size, "AUTH NATIVE (keyNo %d)", cmd[pos + 4]);
break; // AUTHENTICATE_NATIVE
case MFDES_AUTHENTICATE_ISO:
snprintf(exp, size, "AUTH ISO (keyNo %d)", cmd[pos + 1]);
snprintf(exp, size, "AUTH ISO (keyNo %d)", cmd[pos + 4]);
break; // AUTHENTICATE_STANDARD
case MFDES_AUTHENTICATE_AES:
snprintf(exp, size, "AUTH AES (keyNo %d)", cmd[pos + 1]);
snprintf(exp, size, "AUTH AES (keyNo %d)", cmd[pos + 4]);
break;
case MFDES_AUTHENTICATE_EV2F:
snprintf(exp, size, "AUTH EV2 First");

View File

@@ -833,11 +833,11 @@ static int handler_desfire_auth(mfdes_authinput_t *payload, mfdes_auth_res_t *rp
}
}
// else {
/*
cmd[0] = AUTHENTICATE;
cmd[1] = payload->keyno;
len = DesfireAPDU(cmd, 2, resp);
*/
/*
cmd[0] = AUTHENTICATE;
cmd[1] = payload->keyno;
len = DesfireAPDU(cmd, 2, resp);
*/
//}
if (!recv_len) {
@@ -1260,7 +1260,7 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
// C4 01 A0B08090E0F0C0D02030001060704050 03
// 19 bytes
//uint8_t csPkt[30] = {0x00};
csPkt[0] = 0xC4;
csPkt[0] = MFDES_CHANGE_KEY;
memcpy(&csPkt[1], data, 18);
desfire_crc32(csPkt, 19, data + 1 + cmdcnt);
@@ -1280,8 +1280,18 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
cmdcnt += 2;
break;
case AS_NEW:
desfire_crc32_append(data, cmdcnt);
if (new_algo == MFDES_ALGO_AES) {
// AES Checksum must cover : C4<KeyNo> <PrevKey XOR Newkey> <NewKeyVer>
// C4 01 A0B08090E0F0C0D02030001060704050 03
csPkt[0] = 0xC4;
memcpy(&csPkt[1], data, 18);
desfire_crc32(csPkt, 19, data + 1 + cmdcnt);
} else {
desfire_crc32_append(data + 1, cmdcnt);
}
cmdcnt += 4;
// desfire_crc32_append(data, cmdcnt);
// cmdcnt += 4;
break;
}
}
@@ -1293,7 +1303,6 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
memcpy(&data[1], p, cmdcnt);
apdu.data = data;
uint32_t recv_len = 0;
uint16_t sw = 0;
@@ -1303,13 +1312,22 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
int res = send_desfire_cmd(&apdu, false, NULL, &recv_len, &sw, 0, true);
if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, _RED_(" Can't change key -> %s"), GetErrorString(res, &sw));
PrintAndLogEx(WARNING, _RED_("can't change key -> %s"), GetErrorString(res, &sw));
DropFieldDesfire();
return res;
}
size_t sn = recv_len;
if (new_algo == MFDES_ALGO_AES)
{
// AES expects us to Calculate CMAC for status byte : OK 0x00 (0x91 00)
// As such if we get this far without an error, we should be good
// Since we are dropping the field, we dont need to maintain the CMAC etc.
// Setting sn = 1 will allow the post process to just exit (as status only)
sn = 1;
}
p = mifare_cryto_postprocess_data(tag, data, &sn, MDCM_PLAIN | CMAC_COMMAND | CMAC_VERIFY);
// Should be finished processing the changekey so lets ensure the field is dropped.
@@ -1319,9 +1337,11 @@ static int mifare_desfire_change_key(uint8_t key_no, uint8_t *new_key, uint8_t n
/*
Note in my testing on an EV1, the AES password did change, with the number of returned bytes was 8, expected 9 <status><8 byte cmac>
As such !p is true and the code reports "Error on changing key"; so comment back to user until its fixed.
Note: as at 19 May 2021, with the sn = 1 patch above, this should no longer be reachable!
*/
if (new_algo == MFDES_ALGO_AES) {
PrintAndLogEx(WARNING, "AES password may have been changed, please check new password with the auth command.");
PrintAndLogEx(WARNING, "AES Key may have been changed, please check new password with the auth command.");
}
return PM3_ESOFT;
@@ -1890,10 +1910,21 @@ static int handler_desfire_readdata(mfdes_data_t *data, MFDES_FILE_TYPE_T type,
uint16_t sw = 0;
uint32_t resplen = 0;
size_t plen = apdu.Lc;
uint8_t *p = mifare_cryto_preprocess_data(tag, (uint8_t *)data, &plen, 0, MDCM_PLAIN | CMAC_COMMAND);
apdu.Lc = (uint8_t)plen;
apdu.data = p;
// we need the CMD 0xBD <data> to calc the CMAC
uint8_t tmp_data[8]; // Since the APDU is hardcoded to 7 bytes of payload 7+1 = 8 is enough.
tmp_data[0] = 0xBD;
memcpy(&tmp_data[1], data, 7);
// size_t plen = apdu.Lc;
// uint8_t *p = mifare_cryto_preprocess_data(tag, (uint8_t *)data, &plen, 0, MDCM_PLAIN | CMAC_COMMAND);
// apdu.Lc = (uint8_t)plen;
// apdu.data = p;
size_t plen = 8;
uint8_t *p = mifare_cryto_preprocess_data(tag, tmp_data, &plen, 0, MDCM_PLAIN | CMAC_COMMAND);
// apdu data does not need the cmd, so use the original read command data.
apdu.Lc = 7;
apdu.data = (uint8_t *)data;
int res = send_desfire_cmd(&apdu, false, data->data, &resplen, &sw, 0, true);
if (res != PM3_SUCCESS) {
@@ -1953,11 +1984,12 @@ static int handler_desfire_writedata(mfdes_data_t *data, MFDES_FILE_TYPE_T type,
uint32_t recvlen = 0;
int res = PM3_SUCCESS;
uint16_t sw = 0;
uint8_t tmp[59] = {0};
uint8_t tmp[60] = {0};
mfdes_data_t sdata;
sAPDU apdu = {0x90, MFDES_WRITE_DATA, 0x00, 0x00, 0, (uint8_t *) &sdata}; // 0x3D
tmp[0] = data->fileno;
apdu.data = tmp;
tmp[0] = MFDES_WRITE_DATA;
tmp[1] = data->fileno;
apdu.data = &tmp[1]; // tmp[0] is holding the OPCODE for macd calc, so we dont want it in the apdu
if (type == MFDES_RECORD_FILE) apdu.INS = MFDES_WRITE_RECORD;
while (datatowrite) {
@@ -1967,21 +1999,34 @@ static int handler_desfire_writedata(mfdes_data_t *data, MFDES_FILE_TYPE_T type,
else
datasize = datatowrite;
tmp[1] = offset & 0xFF;
tmp[2] = (offset >> 8) & 0xFF;
tmp[3] = (offset >> 16) & 0xFF;
tmp[4] = datasize & 0xFF;
tmp[5] = (datasize >> 8) & 0xFF;
tmp[6] = (datasize >> 16) & 0xFF;
// Build packet to pre-process (using CMD FN OFFSET LEN DATA)
tmp[2] = offset & 0xFF;
tmp[3] = (offset >> 8) & 0xFF;
tmp[4] = (offset >> 16) & 0xFF;
tmp[5] = datasize & 0xFF;
tmp[6] = (datasize >> 8) & 0xFF;
tmp[7] = (datasize >> 16) & 0xFF;
memcpy(&tmp[8], (uint8_t *)&data->data[offset], datasize);
// size_t plen = datasize;
// uint8_t *p = mifare_cryto_preprocess_data(tag, (uint8_t *)&data->data[pos], &plen, 0, cs | MAC_COMMAND | CMAC_COMMAND | ENC_COMMAND);
size_t plen = datasize + 8;
uint8_t *p = mifare_cryto_preprocess_data(tag, tmp, &plen, 8, cs | MAC_COMMAND | CMAC_COMMAND | ENC_COMMAND);
size_t plen = datasize;
uint8_t *p = mifare_cryto_preprocess_data(tag, (uint8_t *)&data->data[pos], &plen, 0, cs | MAC_COMMAND | CMAC_COMMAND | ENC_COMMAND);
if (plen != -1) datasize = (uint8_t)plen;
memcpy(&tmp[7], p, datasize);
// Copy actual data as needed to create APDU Format
if (plen != -1) {
memcpy(&tmp[8], &p[8], plen - 8);
apdu.Lc = plen - 1; //need to drop the OpCode from plen
}
apdu.Lc = datasize + 1 + 3 + 3;
/*
// we dont want to change the value of datasize, so delt with above without change
// Doing so can create wrong offsets and endless loop.
if (plen != -1) datasize = (uint8_t)plen;
memcpy(&tmp[7], p, datasize);
apdu.Lc = datasize + 1 + 3 + 3;
*/
res = send_desfire_cmd(&apdu, false, NULL, &recvlen, &sw, 0, true);
if (res != PM3_SUCCESS) {
@@ -2019,8 +2064,8 @@ static int handler_desfire_deletefile(uint8_t file_no) {
return res;
}
static int handler_desfire_clearrecordfile(uint8_t file_no) {
if (file_no > 0x1F)
static int handler_desfire_clear_record_file(uint8_t file_no) {
if (file_no > 0x1F)
return PM3_EINVARG;
sAPDU apdu = {0x90, MFDES_CLEAR_RECORD_FILE, 0x00, 0x00, 1, &file_no}; // 0xEB
@@ -2639,7 +2684,7 @@ static int CmdHF14ADesClearRecordFile(const char *Cmd) {
return PM3_ESOFT;
}
int res = handler_desfire_clearrecordfile(fno);
int res = handler_desfire_clear_record_file(fno);
if (res == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "Successfully cleared record file.");
} else {
@@ -3570,12 +3615,23 @@ static int CmdHF14ADesInfo(const char *Cmd) {
if (res == PM3_SUCCESS) {
static const char STANDALONE_DESFIRE[] = { 0x75, 0x77, 0x81, 0x02};
static const char JCOP_DESFIRE[] = { 0x75, 0xf7, 0xb1, 0x02 };
static const char JCOP3_DESFIRE[] = { 0x78, 0x77, 0x71, 0x02 };
if (str_startswith((const char *)card.ats + 1, STANDALONE_DESFIRE)) {
PrintAndLogEx(INFO, "Standalone DESFire");
}
if (str_startswith((const char *)card.ats + 1, JCOP_DESFIRE)) {
PrintAndLogEx(INFO, "JCOP DESFire");
if (card.sak == 0x20) {
if (card.ats_len >= 5) {
if (str_startswith((const char *)card.ats + 1, STANDALONE_DESFIRE)) {
PrintAndLogEx(INFO, "Standalone DESFire");
}
if (str_startswith((const char *)card.ats + 1, JCOP_DESFIRE)) {
PrintAndLogEx(INFO, "JCOP DESFire");
}
}
if (card.ats_len == 4) {
if (str_startswith((const char *)card.ats + 1, JCOP3_DESFIRE)) {
PrintAndLogEx(INFO, "JCOP3 DESFire");
}
}
}
}
@@ -4063,18 +4119,9 @@ static int CmdHF14ADesBruteApps(const char *Cmd) {
}
static int CmdHF14ADesChangeKey(const char *Cmd) {
//DropFieldDesfire();
// NR DESC KEYLENGHT
// ------------------------
// 1 = DES 8
// 2 = 3DES 16
// 3 = 3K 3DES 24
// 4 = AES 16
uint8_t keylength = 8;
uint8_t newkeylength = 8;
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes changekey",
"Changes MIFARE DESFire Key\n"
"Change MIFARE DESFire Key.\n"
"Make sure to select aid or authenticate aid before running this command.",
"hf mfdes changekey -n 0 -t 1 -k 0000000000000000 -u 1 -j 0102030405060708 -> DES, keynumber 0"
);
@@ -4105,6 +4152,14 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
uint8_t aesversion = arg_get_int_def(ctx, 6, 0);
CLIParserFree(ctx);
//DropFieldDesfire();
// NR DESC KEYLENGHT
// ------------------------
// 1 = DES 8
// 2 = 3DES 16
// 3 = 3K 3DES 24
// 4 = AES 16
uint8_t keylength = 8;
if (cmdAuthAlgo == MFDES_ALGO_AES) {
keylength = 16;
} else if (cmdAuthAlgo == MFDES_ALGO_3DES) {
@@ -4115,6 +4170,7 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
keylength = 24;
}
uint8_t newkeylength = 8;
if (newcmdAuthAlgo == MFDES_ALGO_AES) {
newkeylength = 16;
} else if (newcmdAuthAlgo == MFDES_ALGO_3DES) {
@@ -4126,37 +4182,36 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
}
if (res_klen || (keylen < 8) || (keylen > 24)) {
PrintAndLogEx(ERR, "Specified key must have %d bytes length.", keylen);
PrintAndLogEx(ERR, "Specified key must have %d bytes length", keylen);
return PM3_EINVARG;
}
if (res_newklen || (newkeylen < 8) || (newkeylen > 24)) {
PrintAndLogEx(ERR, "Specified key must have %d bytes length.", newkeylen);
PrintAndLogEx(ERR, "Specified new key must have %d bytes length", newkeylen);
return PM3_EINVARG;
}
if (keylen != keylength) {
PrintAndLogEx(WARNING, "Key must include %d HEX symbols", keylength);
PrintAndLogEx(WARNING, "Key must include %d hex symbols, got %d", keylength, keylen);
return PM3_EINVARG;
}
if (newkeylen != newkeylength) {
PrintAndLogEx(WARNING, "New key must include %d HEX symbols", keylength);
PrintAndLogEx(WARNING, "New key must include %d hex symbols, got %d", keylength, newkeylen);
return PM3_EINVARG;
}
PrintAndLogEx(INFO, "changing key number 0x%02x", cmdKeyNo);
PrintAndLogEx(INFO, "old key: %s (%s)", sprint_hex_inrow(key, keylen), getEncryptionAlgoStr(cmdAuthAlgo));
PrintAndLogEx(INFO, "new key: %s (%s)", sprint_hex_inrow(newkey, newkeylen), getEncryptionAlgoStr(newcmdAuthAlgo));
PrintAndLogEx(INFO, "changing key number " _YELLOW_("0x%02x"), cmdKeyNo);
PrintAndLogEx(INFO, "old key: %s ( %s )", sprint_hex_inrow(key, keylen), getEncryptionAlgoStr(cmdAuthAlgo));
PrintAndLogEx(INFO, "new key: %s ( %s )", sprint_hex_inrow(newkey, newkeylen), getEncryptionAlgoStr(newcmdAuthAlgo));
int error = mifare_desfire_change_key(cmdKeyNo, newkey, newcmdAuthAlgo, key, cmdAuthAlgo, aesversion);
if (error == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, " Successfully changed key.");
int res = mifare_desfire_change_key(cmdKeyNo, newkey, newcmdAuthAlgo, key, cmdAuthAlgo, aesversion);
if (res == PM3_SUCCESS) {
PrintAndLogEx(SUCCESS, "Change key ( " _GREEN_("ok") " )");
} else {
PrintAndLogEx(SUCCESS, " Error on changing key.");
return PM3_ESOFT;
PrintAndLogEx(FAILED, "Change key ( " _RED_("fail") " )");
}
return PM3_SUCCESS;
return res;
}

View File

@@ -56,6 +56,7 @@ uint8_t default_3des_keys[][16] = {
uint8_t default_pwd_pack[][4] = {
{0xFF, 0xFF, 0xFF, 0xFF}, // PACK 0x00,0x00 -- factory default
{0x4E, 0x45, 0x78, 0x54},
};
uint32_t UL_TYPES_ARRAY[] = {

View File

@@ -268,7 +268,7 @@ static void lookupChipID(uint32_t iChipID, uint32_t mem_used) {
break;
}
PrintAndLogEx(NORMAL, " --= %s " _YELLOW_("%uK") " bytes ( " _YELLOW_("%2.1f%%") " used )"
PrintAndLogEx(NORMAL, " --= %s " _YELLOW_("%uK") " bytes ( " _YELLOW_("%2.0f%%") " used )"
, asBuff
, mem_avail
, mem_avail == 0 ? 0.0f : (float)mem_used / (mem_avail * 1024) * 100

View File

@@ -48,13 +48,13 @@ static int CmdHelp(const char *Cmd);
*/
// Construct the graph for emulating an EM410X tag
static void em410x_construct_emul_graph(uint8_t *uid, uint8_t clock) {
static void em410x_construct_emul_graph(uint8_t *uid, uint8_t clock, uint8_t gap) {
// clear our graph
ClearGraph(true);
// write 16 zero bit sledge
for (uint8_t i = 0; i < 20; i++)
for (uint8_t i = 0; i < gap; i++)
AppendGraph(false, clock, 0);
// write 9 start bits
@@ -403,13 +403,15 @@ static int CmdEM410xSim(const char *Cmd) {
"Enables simulation of EM 410x card.\n"
"Simulation runs until the button is pressed or another USB command is issued.",
"lf em 410x sim --id 0F0368568B\n"
"lf em 410x sim --id 0F0368568B --clk 32"
"lf em 410x sim --id 0F0368568B --clk 32\n"
"lf em 410x sim --id 0F0368568B --gap 0"
);
void *argtable[] = {
arg_param_begin,
arg_u64_0(NULL, "clk", "<dec>", "<32|64> clock (default 64)"),
arg_str1(NULL, "id", "<hex>", "ID number (5 hex bytes)"),
arg_u64_0(NULL, "gap", "<dec>", "gap (0's) between ID repeats (default 20)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@@ -417,6 +419,7 @@ static int CmdEM410xSim(const char *Cmd) {
// clock is 64 in EM410x tags
int clk = arg_get_u32_def(ctx, 1, 64);
int uid_len = 0;
int gap = arg_get_u32_def(ctx, 3, 20);
uint8_t uid[5] = {0};
CLIGetHexWithReturn(ctx, 2, uid, &uid_len);
CLIParserFree(ctx);
@@ -427,7 +430,7 @@ static int CmdEM410xSim(const char *Cmd) {
}
PrintAndLogEx(SUCCESS, "Starting simulating UID "_YELLOW_("%s")" clock: "_YELLOW_("%d"), sprint_hex_inrow(uid, sizeof(uid)), clk);
em410x_construct_emul_graph(uid, clk);
em410x_construct_emul_graph(uid, clk, gap);
CmdLFSim("");
return PM3_SUCCESS;
}
@@ -447,13 +450,14 @@ static int CmdEM410xBrute(const char *Cmd) {
arg_u64_0(NULL, "clk", "<dec>", "<32|64> clock (default 64)"),
arg_u64_0(NULL, "delay", "<dec>", "pause delay in milliseconds between UIDs simulation (default 1000ms)"),
arg_str1("f", "file", "<hex>", "file with UIDs in HEX format, one per line"),
arg_u64_0(NULL, "gap", "<dec>", "gap (0's) between ID repeats (default 20)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
// clock default 64 in EM410x
uint32_t clk = arg_get_u32_def(ctx, 1, 64);
int gap = arg_get_u32_def(ctx, 4, 20);
// default pause time: 1 second
uint32_t delay = arg_get_u32_def(ctx, 2, 1000);
@@ -548,7 +552,7 @@ static int CmdEM410xBrute(const char *Cmd) {
, sprint_hex_inrow(testuid, sizeof(testuid))
);
em410x_construct_emul_graph(testuid, clk);
em410x_construct_emul_graph(testuid, clk, gap);
lfsim_upload_gb();

View File

@@ -1852,14 +1852,11 @@ int CmdEM4x05Unlock(const char *Cmd) {
PrintAndLogEx(INFO, "Old protection word => " _YELLOW_("%08X"), search_value);
char bitstring[9] = {0};
for (int i = 0; i < 8; i++) {
bitstring[i] = (bitflips & (0xF << ((7 - i) * 4))) ? 'x' : '.';
bitstring[i] = (bitflips & (0xFU << ((7 - i) * 4))) ? 'x' : '.';
}
// compute number of bits flipped
PrintAndLogEx(INFO, "Bitflips: %2u events => %s", bitcount32(bitflips), bitstring);
PrintAndLogEx(INFO, "New protection word => " _CYAN_("%08X") "\n", word14b);
PrintAndLogEx(INFO, "Try " _YELLOW_("`lf em 4x05_dump`"));
}

View File

@@ -18,8 +18,7 @@
#include "commonutil.h"
#include "pmflash.h"
#include "cmdflashmemspiffs.h"
#define BYTES2UINT32(x) ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | (x[3]))
#include "em4x50.h"
static int CmdHelp(const char *Cmd);
@@ -465,12 +464,12 @@ int CmdEM4x50Chk(const char *Cmd) {
}
size_t datalen = 0;
uint8_t data[FLASH_MEM_MAX_SIZE] = {0x0};
uint8_t data[100000] = {0x0};
uint8_t *keys = data;
uint32_t key_count = 0;
int res = loadFileDICTIONARY(filename, data, &datalen, 4, &key_count);
if (res || !key_count)
if ((res != PM3_SUCCESS) || (key_count == 0))
return PM3_EFILE;
PrintAndLogEx(INFO, "You can cancel this operation by pressing the pm3 button");

View File

@@ -19,9 +19,6 @@
#define LOCKBIT_0 BITMASK(6)
#define LOCKBIT_1 BITMASK(7)
#define BYTES2UINT16(x) ((x[1] << 8) | (x[0]))
#define BYTES2UINT32(x) ((x[3] << 24) | (x[2] << 16) | (x[1] << 8) | (x[0]))
#define INDEX_TO_BLOCK(x) (((32-x)/2)-1)
static int CmdHelp(const char *Cmd);

View File

@@ -65,7 +65,7 @@ int ExecuteCryptoTests(bool verbose, bool ignore_time, bool include_slow_tests)
PrintAndLogEx(WARNING, "Repeat timing test " _RED_("%d"), i + 1);
}
if (res && !ignore_time) TestFail = true;
*/
*/
res = mbedtls_ctr_drbg_self_test(verbose);
if (res) TestFail = true;

View File

@@ -285,7 +285,7 @@ void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t le
return;
}
uint8_t *buffer = malloc(padded_data_length(len, kbs));
uint8_t *buffer = calloc(padded_data_length(len, kbs), sizeof(uint8_t));
memcpy(buffer, data, len);
@@ -315,8 +315,8 @@ void mifare_kdf_an10922(const desfirekey_t key, const uint8_t *data, size_t len)
cmac_generate_subkeys(key, MCD_SEND);
uint8_t *buffer = malloc(kbs2);
uint8_t *ivect = malloc(kbs);
uint8_t *buffer = calloc(kbs2, sizeof(uint8_t));
uint8_t *ivect = calloc(kbs, sizeof(uint8_t));
memset(ivect, 0, kbs);
@@ -556,7 +556,7 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
void *res = data;
void *edata = NULL;
tag->crypto_buffer_size = *nbytes * 2;
tag->crypto_buffer = (uint8_t *)malloc(tag->crypto_buffer_size);
tag->crypto_buffer = (uint8_t *)calloc(tag->crypto_buffer_size, sizeof(uint8_t));
uint8_t first_cmac_byte = 0x00;
@@ -592,7 +592,7 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
}
size_t edl = enciphered_data_length(tag, *nbytes, communication_settings);
edata = malloc(edl);
edata = calloc(edl, sizeof(uint8_t));
memcpy(edata, data, *nbytes);
memset((uint8_t *)edata + *nbytes, 0, edl - *nbytes);

View File

@@ -217,6 +217,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
char *cmd = NULL;
bool execCommand = (script_cmd != NULL);
bool fromInteractive = false;
uint16_t script_cmd_len = 0;
if (execCommand) {
script_cmd_len = strlen(script_cmd);
@@ -309,10 +310,10 @@ check_script:
} else {
// If there is a script command
if (execCommand) {
prompt_ctx = PROXPROMPT_CTX_SCRIPTCMD;
prompt_ctx = stdinOnPipe ? PROXPROMPT_CTX_STDIN : PROXPROMPT_CTX_SCRIPTCMD;
cmd = str_dup(script_cmd);
if (cmd != NULL)
if ((cmd != NULL) && (! fromInteractive))
printprompt = true;
uint16_t len = strlen(script_cmd) + 1;
@@ -329,8 +330,6 @@ check_script:
// if there is a pipe from stdin
if (stdinOnPipe) {
prompt_ctx = PROXPROMPT_CTX_STDIN;
// clear array
memset(script_cmd_buf, 0, sizeof(script_cmd_buf));
// get
@@ -338,13 +337,15 @@ check_script:
PrintAndLogEx(ERR, "STDIN unexpected end, exit...");
break;
}
execCommand = true;
stayInCommandLoop = true;
fromInteractive = false;
script_cmd = script_cmd_buf;
script_cmd_len = strlen(script_cmd);
strcreplace(script_cmd, script_cmd_len, ';', '\0');
// remove linebreaks
strcleanrn(script_cmd_buf, sizeof(script_cmd_buf));
cmd = str_dup(script_cmd_buf);
if (cmd != NULL)
printprompt = true;
strcleanrn(script_cmd, script_cmd_len);
goto check_script;
} else {
#ifdef HAVE_READLINE
rl_event_hook = check_comm;
@@ -358,7 +359,17 @@ check_script:
memcpy_filter_ansi(prompt_filtered, prompt, sizeof(prompt_filtered), !session.supports_colors);
g_pendingPrompt = true;
#ifdef HAVE_READLINE
cmd = readline(prompt_filtered);
script_cmd = readline(prompt_filtered);
if (script_cmd != NULL) {
execCommand = true;
stayInCommandLoop = true;
fromInteractive = true;
script_cmd_len = strlen(script_cmd);
strcreplace(script_cmd, script_cmd_len, ';', '\0');
// remove linebreaks
strcleanrn(script_cmd, script_cmd_len);
goto check_script;
}
#else
printf("%s", prompt_filtered);
cmd = NULL;

View File

@@ -305,7 +305,7 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea
*(tmp++) = c;
// check if a line break is needed and we have room to print it in our array
if (breaks) {
if (breaks > 1) {
if (((i + 1) % breaks) == 0) {
*(tmp++) = '\n';
@@ -826,7 +826,9 @@ int binarraytohex(char *target, const size_t targetlen, char *source, size_t src
x += (source[s] << (3 - i));
i++;
if (i == 4) {
if (t >= targetlen - 2) return r;
if (t >= targetlen - 2) {
return r;
}
sprintf(target + t, "%X", x);
t++;
r += 4;
@@ -835,16 +837,20 @@ int binarraytohex(char *target, const size_t targetlen, char *source, size_t src
}
} else {
if (i > 0) {
if (t >= targetlen - 5) return r;
w = 0;
if (t >= targetlen - 5) {
return r;
}
sprintf(target + t, "%X[%i]", x, i);
t += 4;
r += i;
x = 0;
i = 0;
w = 1;
}
if (w == 0) {
if (t >= targetlen - 2) return r;
if (t >= targetlen - 2) {
return r;
}
sprintf(target + t, " ");
t++;
}

View File

@@ -1206,6 +1206,47 @@ static bool Unpack_pw39(wiegand_message_t *packed, wiegand_card_t *card) {
return true;
}
static bool Pack_bc40(wiegand_card_t *card, wiegand_message_t *packed, bool preamble) {
memset(packed, 0, sizeof(wiegand_message_t));
if (card->FacilityCode > 0xFFF) return false; // Can't encode FC.
if (card->CardNumber > 0xFFFFF) return false; // Can't encode CN.
if (card->IssueLevel > 0) return false; // Not used in this format
if (card->OEM > 0x7F) return false; // Not used in this format
packed->Length = 39; // Set number of bits
set_linear_field(packed, card->OEM, 0, 7);
// cost center 12
set_linear_field(packed, card->FacilityCode, 7, 12);
set_linear_field(packed, card->CardNumber, 19, 19);
set_bit_by_position(packed,
oddparity32(get_linear_field(packed, 19, 19))
, 39);
if (preamble)
return add_HID_header(packed);
return true;
}
static bool Unpack_bc40(wiegand_message_t *packed, wiegand_card_t *card) {
memset(card, 0, sizeof(wiegand_card_t));
if (packed->Length != 39) return false; // Wrong length? Stop here.
card->OEM = get_linear_field(packed, 0, 7);
card->FacilityCode = get_linear_field(packed, 7, 12);
card->CardNumber = get_linear_field(packed, 19, 19);
card->ParityValid =
(get_bit_by_position(packed, 39) == oddparity32(get_linear_field(packed, 19, 19)));
return true;
}
// ---------------------------------------------------------------------------------------------------
void print_desc_wiegand(cardformat_t *fmt, wiegand_message_t *packed) {
@@ -1324,6 +1365,7 @@ static const cardformat_t FormatTable[] = {
{"P10001", Pack_P10001, Unpack_P10001, "HID P10001 Honeywell 40-bit", {1, 1, 0, 1, 0}}, // from cardinfo.barkweb.com.au
{"Casi40", Pack_CasiRusco40, Unpack_CasiRusco40, "Casi-Rusco 40-bit", {1, 0, 0, 0, 0}}, // from cardinfo.barkweb.com.au
{"C1k48s", Pack_C1k48s, Unpack_C1k48s, "HID Corporate 1000 48-bit std", {1, 1, 0, 0, 1}}, // imported from old pack/unpack
{"BC40", Pack_bc40, Unpack_bc40, "Bundy TimeClock 40-bit", {1, 1, 0, 1, 1}}, // from
{NULL, NULL, NULL, NULL, {0, 0, 0, 0, 0}} // Must null terminate array
};
@@ -1341,7 +1383,7 @@ void HIDListFormats(void) {
++i;
}
PrintAndLogEx(INFO, "------------------------------------------------------------");
PrintAndLogEx(INFO, "Available card formats: " _YELLOW_("%u"), ARRAYLEN(FormatTable));
PrintAndLogEx(INFO, "Available card formats: " _YELLOW_("%" PRIu64), ARRAYLEN(FormatTable));
PrintAndLogEx(NORMAL, "");
return;
}

View File

@@ -176,19 +176,19 @@ bool add_HID_header(wiegand_message_t *data) {
return false;
if (data->Length >= 64) {
data->Top |= 1 << (data->Length - 64); // leading 1: start bit
data->Top |= 0x09e00000; // Extended-length header
data->Top |= 1U << (data->Length - 64); // leading 1: start bit
} else if (data->Length > 37) {
data->Mid |= 1 << (data->Length - 32); // leading 1: start bit
data->Top |= 0x09e00000; // Extended-length header
data->Mid |= 1U << (data->Length - 32); // leading 1: start bit
} else if (data->Length == 37) {
// No header bits added to 37-bit cards
} else if (data->Length >= 32) {
data->Mid |= 0x20; // Bit 37; standard header
data->Mid |= 1 << (data->Length - 32); // leading 1: start bit
data->Mid |= 1U << (data->Length - 32); // leading 1: start bit
} else {
data->Mid |= 0x20; // Bit 37; standard header
data->Bot |= 1 << data->Length; // leading 1: start bit
data->Bot |= 1U << data->Length; // leading 1: start bit
}
return true;
}

View File

@@ -131,6 +131,15 @@ extern bool tearoff_enabled;
#endif
#endif
// convert 2 bytes to U16
#ifndef BYTES2UINT16
# define BYTES2UINT16(x) ((x[1] << 8) | (x[0]))
#endif
// convert 4 bytes to U32
#ifndef BYTES2UINT32
# define BYTES2UINT32(x) ((x[3] << 24) | (x[2] << 16) | (x[1] << 8) | (x[0]))
#endif
#define EVEN 0
#define ODD 1

View File

@@ -11,6 +11,8 @@
#ifndef EM4X50_H__
#define EM4X50_H__
#include "common.h"
#define EM4X50_NO_WORDS 34
// special words
@@ -45,8 +47,6 @@
#define TIMEOUT_CMD 3000
#define DUMP_FILESIZE 136
#define BYTES2UINT32(x) ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | (x[3]))
typedef struct {
bool addr_given;
bool pwd_given;

View File

@@ -35,7 +35,6 @@
# define FLASH_MEM_MAX_4K_SECTOR 0x3F000
#endif
#ifndef FLASH_MEM_ID_LEN
# define FLASH_MEM_ID_LEN 8
#endif
@@ -79,4 +78,9 @@ typedef struct {
uint8_t signature[FLASH_MEM_SIGNATURE_LEN];
} PACKED rdv40_validation_t;
// SPIFFS current allocates 128kb of the 256kb available.
#ifndef FLASH_SPIFFS_ALLOCATED_SIZE
# define FLASH_SPIFFS_ALLOCATED_SIZE (1024 * 128)
#endif
#endif // __PMFLASH_H

View File

@@ -41,12 +41,12 @@
#define SSC_CLOCK_MODE_SELECT(x) ((x) << 0)
#define SSC_FRAME_MODE_BITS_IN_WORD(x) (((x)-1) << 0)
#define MC_FLASH_COMMAND_KEY ((0x5a) << 24)
#define MC_FLASH_COMMAND_KEY ((0x5A) << 24)
#define MC_FLASH_MODE_FLASH_WAIT_STATES(x) ((x) << 8)
#define MC_FLASH_MODE_MASTER_CLK_IN_MHZ(x) (((x)+((x)/2)) << 16)
#define MC_FLASH_COMMAND_PAGEN(x) ((x) << 8)
#define RST_CONTROL_KEY (0xa5 << 24)
#define RST_CONTROL_KEY (0xA5U << 24)
#define PMC_MAIN_OSC_STARTUP_DELAY(x) ((x) << 8)
#define PMC_PLL_DIVISOR(x) (x)

View File

@@ -97,7 +97,10 @@ static int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile) {
memcpy(ring_buffer, fpga_config + current_in, bytes_to_copy);
int cmp_bytes = LZ4_compress_HC_continue(lz4_streamhc, ring_buffer, outbuf, bytes_to_copy, outsize_max);
if (cmp_bytes < 0 ){
fprintf(stderr, "(lz4 - zlib_compress) error, got negative number of bytes from LZ4_compress_HC_continue call. got %d ", cmp_bytes);
return (EXIT_FAILURE);
}
fwrite(&cmp_bytes, sizeof(int), 1, outfile);
fwrite(outbuf, sizeof(char), cmp_bytes, outfile);
@@ -118,7 +121,7 @@ static int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile) {
fprintf(stdout, "compressed %u input bytes to %d output bytes\n", total_size, current_out);
if (current_out == 0) {
fprintf(stderr, "Error in lz4");
fprintf(stderr, "error in lz4");
return (EXIT_FAILURE);
}
return (EXIT_SUCCESS);
@@ -204,18 +207,27 @@ static int bitparse_find_section(FILE *infile, char section_name, unsigned int *
break;
}
unsigned int current_length = 0;
int tmp;
switch (current_name) {
case 'e':
/* Four byte length field */
current_length += fgetc(infile) << 24;
current_length += fgetc(infile) << 16;
current_length += fgetc(infile) << 8;
current_length += fgetc(infile) << 0;
for (int i = 0; i < 4; i++) {
tmp = fgetc(infile);
if (tmp < 0 ) {
break;
}
current_length += tmp << (24 - (i * 8));
}
numbytes += 4;
break;
default: /* Fall through, two byte length field */
current_length += fgetc(infile) << 8;
current_length += fgetc(infile) << 0;
for (int i = 0; i < 2; i++) {
tmp = fgetc(infile);
if (tmp < 0 ) {
break;
}
current_length += tmp << (8 - (i * 8));
}
numbytes += 2;
break;
}
@@ -290,6 +302,7 @@ static int FpgaGatherVersion(FILE *infile, char *infile_name, char *dst, int len
for (uint16_t i = 0; i < fpga_info_len; i++) {
char c = (char)fgetc(infile);
if (i < sizeof(tempstr)) {
if (c == ' ') c = '0';
tempstr[i] = c;
}
}

View File

@@ -1,5 +1,5 @@
MYSRCPATHS = ../../common ../../common/crapto1
MYSRCS = crypto1.c crapto1.c bucketsort.c iso14443crc.c sleep.c
MYSRCS = crypto1.c crapto1.c bucketsort.c iso14443crc.c sleep.c util_posix.c
MYINCLUDES = -I../../include -I../../common
MYCFLAGS =
MYDEFS =

View File

@@ -1,11 +1,5 @@
#define __STDC_FORMAT_MACROS
#if !defined(_WIN64)
#if defined(_WIN32) || defined(__WIN32__)
# define _USE_32BIT_TIME_T 1
#endif
#endif
#include <inttypes.h>
#include <stdio.h>
#include <stdbool.h>
@@ -13,11 +7,11 @@
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <ctype.h>
#include "crapto1/crapto1.h"
#include "protocol.h"
#include "iso14443crc.h"
#include "util_posix.h"
#define AEND "\x1b[0m"
#define _RED_(s) "\x1b[31m" s AEND
@@ -74,11 +68,11 @@ uint8_t cmds[8][2] = {
{MIFARE_CMD_TRANSFER, 0}
};
int global_counter = 0;
int global_found = 0;
int global_found_candidate = 0;
uint64_t global_candiate_key = 0;
size_t thread_count = 2;
//static int global_counter = 0;
static int global_found = 0;
static int global_found_candidate = 0;
static uint64_t global_candiate_key = 0;
static int thread_count = 2;
static int param_getptr(const char *line, int *bg, int *en, int paramnum) {
int i;
@@ -390,7 +384,7 @@ static void *brute_thread(void *arguments) {
nt = count << 16 | prng_successor(count, 16);
if (!candidate_nonce(args->xored, nt, args->ev1))
if (candidate_nonce(args->xored, nt, args->ev1) == false)
continue;
p64 = prng_successor(nt, 64);
@@ -420,14 +414,17 @@ static void *brute_thread(void *arguments) {
// check if cmd exists
uint8_t isOK = checkValidCmd(decrypted);
(void)isOK;
if (isOK == false) {
printf(_RED_("<-- not a valid cmd\n"));
pthread_mutex_unlock(&print_lock);
continue;
}
// Add a crc-check.
isOK = checkCRC(decrypted);
if (isOK == false) {
printf(_RED_("<-- not a valid cmd\n"));
printf(_RED_("<-- not a valid crc\n"));
pthread_mutex_unlock(&print_lock);
free(revstate);
continue;
} else {
printf("<-- valid cmd\n");
@@ -440,7 +437,6 @@ static void *brute_thread(void *arguments) {
lfsr_rollback_word(revstate, nr_enc, 1);
lfsr_rollback_word(revstate, uid ^ nt, 0);
crypto1_get_lfsr(revstate, &key);
free(revstate);
if (args->ev1) {
// if it was EV1, we know for sure xxxAAAAAAAA recovery
@@ -450,11 +446,13 @@ static void *brute_thread(void *arguments) {
printf("\nKey candidate [ " _GREEN_("....%08" PRIx64) " ]\n\n", key & 0xFFFFFFFF);
__sync_fetch_and_add(&global_found, 1);
}
__sync_fetch_and_add(&global_candiate_key, key);
//release lock
pthread_mutex_unlock(&print_lock);
__sync_fetch_and_add(&global_candiate_key, key);
free(revstate);
break;
}
free(revstate);
}
free(args);
return NULL;
@@ -463,7 +461,7 @@ static void *brute_thread(void *arguments) {
static void *brute_key_thread(void *arguments) {
struct thread_key_args *args = (struct thread_key_args *) arguments;
uint64_t key;
uint64_t key = args->part_key;
uint8_t local_enc[args->enc_len];
memcpy(local_enc, args->enc, args->enc_len);
@@ -473,7 +471,7 @@ static void *brute_key_thread(void *arguments) {
break;
}
key = (count << 32 | args->part_key);
key |= (count << 32);
// Init cipher with key
struct Crypto1State *pcs = crypto1_create(key);
@@ -489,13 +487,13 @@ static void *brute_key_thread(void *arguments) {
for (int i = 0; i < args->enc_len; i++)
dec[i] = crypto1_byte(pcs, 0x00, 0) ^ local_enc[i];
crypto1_deinit(pcs);
crypto1_destroy(pcs);
// check if cmd exists
uint8_t isOK = checkValidCmdByte(dec, args->enc_len);
if (isOK == false) {
if (checkValidCmdByte(dec, args->enc_len) == false) {
continue;
}
__sync_fetch_and_add(&global_found, 1);
// lock this section to avoid interlacing prints from different threats
pthread_mutex_lock(&print_lock);
@@ -503,7 +501,6 @@ static void *brute_key_thread(void *arguments) {
printf("dec: %s\n", sprint_hex_inrow_ex(dec, args->enc_len, 0));
printf("\nValid Key found [ " _GREEN_("%012" PRIx64) " ]\n\n", key);
pthread_mutex_unlock(&print_lock);
__sync_fetch_and_add(&global_found, 1);
break;
}
free(args);
@@ -568,7 +565,7 @@ int main(int argc, char *argv[]) {
printf("next encrypted cmd... %s\n", sprint_hex_inrow_ex(enc, enc_len, 0));
}
clock_t t1 = clock();
uint64_t t1 = msclock();
uint16_t nt_par = parity_from_err(nt_enc, nt_par_err);
uint16_t ar_par = parity_from_err(ar_enc, ar_par_err);
uint16_t at_par = parity_from_err(at_enc, at_par_err);
@@ -582,7 +579,7 @@ int main(int argc, char *argv[]) {
thread_count = 2;
#endif /* _WIN32 */
printf("\nBruteforce using " _YELLOW_("%zu") " threads\n", thread_count);
printf("\nBruteforce using " _YELLOW_("%d") " threads\n", thread_count);
printf("looking for the last bytes of the encrypted tagnonce\n");
pthread_t threads[thread_count];
@@ -591,7 +588,7 @@ int main(int argc, char *argv[]) {
pthread_mutex_init(&print_lock, NULL);
// one thread T0 for none EV1.
struct thread_args *a = malloc(sizeof(struct thread_args));
struct thread_args *a = calloc(1, sizeof(struct thread_args));
a->xored = xored;
a->thread = 0;
a->idx = 0;
@@ -600,7 +597,7 @@ int main(int argc, char *argv[]) {
// the rest of available threads to EV1 scenario
for (int i = 0; i < thread_count - 1; ++i) {
struct thread_args *b = malloc(sizeof(struct thread_args));
struct thread_args *b = calloc(1, sizeof(struct thread_args));
b->xored = xored;
b->thread = i + 1;
b->idx = i;
@@ -612,8 +609,8 @@ int main(int argc, char *argv[]) {
for (int i = 0; i < thread_count; ++i)
pthread_join(threads[i], NULL);
t1 = clock() - t1;
printf("execution time %.2f sec\n", (float)t1 / 1000000.0);
t1 = msclock() - t1;
printf("execution time " _YELLOW_("%.2f") " sec\n", (float)t1 / 1000.0);
if (!global_found && !global_found_candidate) {
@@ -631,11 +628,11 @@ int main(int argc, char *argv[]) {
global_found_candidate = 0;
printf("\n----------- " _CYAN_("Phase 2") " ------------------------\n");
printf("uid.......... %08x\n", uid);
printf("partial key.. %08x\n", (uint32_t)(global_candiate_key & 0xFFFFFFFF));
printf("nt enc....... %08x\n", nt_enc);
printf("nr enc....... %08x\n", nr_enc);
printf("next encrypted cmd: %s\n", sprint_hex_inrow_ex(enc, enc_len, 0));
printf("uid.................. %08x\n", uid);
printf("partial key.......... %08x\n", (uint32_t)(global_candiate_key & 0xFFFFFFFF));
printf("nt enc............... %08x\n", nt_enc);
printf("nr enc............... %08x\n", nr_enc);
printf("next encrypted cmd... %s\n", sprint_hex_inrow_ex(enc, enc_len, 0));
printf("\nlooking for the upper 16 bits of key\n");
fflush(stdout);

View File

@@ -9,12 +9,6 @@
#define __STDC_FORMAT_MACROS
#if !defined(_WIN64)
#if defined(_WIN32) || defined(__WIN32__)
# define _USE_32BIT_TIME_T 1
#endif
#endif
#include <inttypes.h>
#include <stdio.h>
#include <stdbool.h>
@@ -23,10 +17,16 @@
#include <stdlib.h>
#include <unistd.h>
#include "ctype.h"
#include <time.h>
#include "crapto1/crapto1.h"
#include "protocol.h"
#include "iso14443crc.h"
#include <util_posix.h>
#define AEND "\x1b[0m"
#define _RED_(s) "\x1b[31m" s AEND
#define _GREEN_(s) "\x1b[32m" s AEND
#define _YELLOW_(s) "\x1b[33m" s AEND
#define _CYAN_(s) "\x1b[36m" s AEND
// a global mutex to prevent interlaced printing from different threads
pthread_mutex_t print_lock;
@@ -41,26 +41,24 @@ typedef struct thread_args {
uint32_t part_key;
uint32_t nt_enc;
uint32_t nr_enc;
uint16_t enc_len;
uint8_t enc[ENC_LEN]; // next encrypted command + a full read/write
} targs;
//------------------------------------------------------------------
uint8_t cmds[] = {
ISO14443A_CMD_READBLOCK,
ISO14443A_CMD_WRITEBLOCK,
MIFARE_AUTH_KEYA,
MIFARE_AUTH_KEYB,
MIFARE_CMD_INC,
MIFARE_CMD_DEC,
MIFARE_CMD_RESTORE,
MIFARE_CMD_TRANSFER
uint8_t cmds[8][2] = {
{ISO14443A_CMD_READBLOCK, 18},
{ISO14443A_CMD_WRITEBLOCK, 18},
{MIFARE_AUTH_KEYA, 0},
{MIFARE_AUTH_KEYB, 0},
{MIFARE_CMD_INC, 6},
{MIFARE_CMD_DEC, 6},
{MIFARE_CMD_RESTORE, 6},
{MIFARE_CMD_TRANSFER, 0}
};
int global_counter = 0;
int global_fin_flag = 0;
int global_found = 0;
int global_found_candidate = 0;
size_t thread_count = 2;
static int global_found = 0;
static int thread_count = 2;
static int param_getptr(const char *line, int *bg, int *en, int paramnum) {
int i;
@@ -174,67 +172,71 @@ static char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const si
return buf;
}
static bool checkValidCmdByte(uint8_t *cmd, uint16_t n) {
bool ok = false;
for (int i = 0; i < 8; ++i) {
if (cmd[0] == cmds[i][0]) {
if (n >= 4)
ok = CheckCrc14443(CRC_14443_A, cmd, 4);
if (cmds[i][1] > 0 && n >= cmds[i][1])
ok = CheckCrc14443(CRC_14443_A, cmd + 4, cmds[i][1]);
if (ok) {
return true;
}
}
}
return false;
}
static void *brute_thread(void *arguments) {
//int shift = (int)arg;
struct thread_args *args = (struct thread_args *) arguments;
uint64_t key; // recovered key candidate
int found = 0;
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs = &mpcs;
uint8_t local_enc[ENC_LEN] = {0};
memcpy(local_enc, args->enc, sizeof(local_enc));
uint64_t key = args->part_key;
uint8_t local_enc[args->enc_len];
memcpy(local_enc, args->enc, args->enc_len);
for (uint64_t count = args->idx; count < 0xFFFF; count += thread_count) {
found = global_found;
if (found) {
if (__atomic_load_n(&global_found, __ATOMIC_ACQUIRE) == 1) {
break;
}
key = (count << 32 | args->part_key);
key |= count << 32;
// Init cipher with key
pcs = crypto1_create(key);
struct Crypto1State *pcs = crypto1_create(key);
// NESTED decrypt nt with help of new key
// if (args->use_nested)
// crypto1_word(pcs, args->nt_enc ^ args->uid, 1) ^ args->nt_enc;
// else
crypto1_word(pcs, args->nt_enc ^ args->uid, 1);
crypto1_word(pcs, args->nr_enc, 1);
crypto1_word(pcs, 0, 0);
crypto1_word(pcs, 0, 0);
// decrypt 22 bytes
uint8_t dec[ENC_LEN] = {0};
for (int i = 0; i < ENC_LEN; i++)
uint8_t dec[args->enc_len];
for (int i = 0; i < args->enc_len; i++)
dec[i] = crypto1_byte(pcs, 0x00, 0) ^ local_enc[i];
crypto1_deinit(pcs);
crypto1_destroy(pcs);
if (CheckCrc14443(CRC_14443_A, dec, 4)) {
// check crc-16 in the end
if (CheckCrc14443(CRC_14443_A, dec + 4, 18)) {
// lock this section to avoid interlacing prints from different threats
pthread_mutex_lock(&print_lock);
printf("\nValid Key found: [%012" PRIx64 "]\n", key);
printf("enc: %s\n", sprint_hex_inrow_ex(local_enc, ENC_LEN, 0));
printf(" xx crcA crcA\n");
printf("dec: %s\n", sprint_hex_inrow_ex(dec, ENC_LEN, 0));
pthread_mutex_unlock(&print_lock);
__sync_fetch_and_add(&global_found, 1);
}
if (checkValidCmdByte(dec, args->enc_len) == false) {
continue;
}
__sync_fetch_and_add(&global_found, 1);
// lock this section to avoid interlacing prints from different threats
pthread_mutex_lock(&print_lock);
printf("\nenc: %s\n", sprint_hex_inrow_ex(local_enc, args->enc_len, 0));
printf("dec: %s\n", sprint_hex_inrow_ex(dec, args->enc_len, 0));
printf("\nValid Key found [ " _GREEN_("%012" PRIx64) " ]\n\n", key);
pthread_mutex_unlock(&print_lock);
break;
}
free(args);
return NULL;
}
@@ -245,7 +247,7 @@ static int usage(void) {
}
int main(int argc, char *argv[]) {
printf("Mifare classic nested auth key recovery. Phase 2.\n");
printf("Mifare classic nested auth key recovery Phase 2\n");
if (argc < 3) return usage();
uint32_t uid = 0; // serial number
@@ -263,13 +265,13 @@ int main(int argc, char *argv[]) {
param_gethex_to_eol(argv[5], 0, enc, sizeof(enc), &enc_len);
printf("-------------------------------------------------\n");
printf("uid.......... %08x\n", uid);
printf("partial key.. %08x\n", part_key);
printf("nt enc....... %08x\n", nt_enc);
printf("nr enc....... %08x\n", nr_enc);
printf("next encrypted cmd: %s\n", sprint_hex_inrow_ex(enc, ENC_LEN, 0));
printf("uid.................. %08x\n", uid);
printf("partial key.......... %08x\n", part_key);
printf("nt enc............... %08x\n", nt_enc);
printf("nr enc............... %08x\n", nr_enc);
printf("next encrypted cmd... %s\n", sprint_hex_inrow_ex(enc, enc_len, 0));
clock_t t1 = clock();
uint64_t t1 = msclock();
#if !defined(_WIN32) || !defined(__WIN32__)
thread_count = sysconf(_SC_NPROCESSORS_CONF);
@@ -277,7 +279,7 @@ int main(int argc, char *argv[]) {
thread_count = 2;
#endif /* _WIN32 */
printf("\nBruteforce using %zu threads to find upper 16bits of key\n", thread_count);
printf("\nBruteforce using %d threads to find upper 16bits of key\n", thread_count);
pthread_t threads[thread_count];
@@ -286,14 +288,15 @@ int main(int argc, char *argv[]) {
// threads
for (int i = 0; i < thread_count; ++i) {
struct thread_args *a = malloc(sizeof(struct thread_args));
struct thread_args *a = calloc(1, sizeof(struct thread_args));
a->thread = i;
a->idx = i;
a->uid = uid;
a->part_key = part_key;
a->nt_enc = nt_enc;
a->nr_enc = nr_enc;
memcpy(a->enc, enc, sizeof(a->enc));
a->enc_len = enc_len;
memcpy(a->enc, enc, enc_len);
pthread_create(&threads[i], NULL, brute_thread, (void *)a);
}
@@ -301,13 +304,13 @@ int main(int argc, char *argv[]) {
for (int i = 0; i < thread_count; ++i)
pthread_join(threads[i], NULL);
if (!global_found && !global_found_candidate) {
if (global_found == false) {
printf("\nFailed to find a key\n\n");
}
t1 = clock() - t1;
t1 = msclock() - t1;
if (t1 > 0)
printf("Execution time: %.0f ticks\n", (float)t1);
printf("execution time " _YELLOW_("%.2f") " sec\n", (float)t1 / 1000.0);
// clean up mutex
pthread_mutex_destroy(&print_lock);

View File

@@ -0,0 +1,137 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// utilities requiring Posix library functions
//-----------------------------------------------------------------------------
// ensure availability even with -std=c99; must be included before
#if !defined(_WIN32)
//#define _POSIX_C_SOURCE 199309L // need nanosleep()
#define _POSIX_C_SOURCE 200112L // need localtime_r()
#else
#include <windows.h>
#endif
#include "util_posix.h"
#include <stdint.h>
#include <time.h>
// Timer functions
#if !defined (_WIN32)
#include <errno.h>
static void nsleep(uint64_t n) {
struct timespec timeout;
timeout.tv_sec = n / 1000000000;
timeout.tv_nsec = n % 1000000000;
while (nanosleep(&timeout, &timeout) && errno == EINTR);
}
void msleep(uint32_t n) {
nsleep(1000000 * (uint64_t)n);
}
#endif // _WIN32
#ifdef __APPLE__
#ifndef CLOCK_MONOTONIC
#define CLOCK_MONOTONIC (1)
#endif
#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME (2)
#endif
#include <sys/time.h>
#include <mach/clock.h>
#include <mach/mach.h>
#include <mach/mach_time.h>
/* clock_gettime is not implemented on OSX prior to 10.12 */
int _civet_clock_gettime(int clk_id, struct timespec *t);
int _civet_clock_gettime(int clk_id, struct timespec *t) {
memset(t, 0, sizeof(*t));
if (clk_id == CLOCK_REALTIME) {
struct timeval now;
int rv = gettimeofday(&now, NULL);
if (rv) {
return rv;
}
t->tv_sec = now.tv_sec;
t->tv_nsec = now.tv_usec * 1000;
return 0;
} else if (clk_id == CLOCK_MONOTONIC) {
static uint64_t clock_start_time = 0;
static mach_timebase_info_data_t timebase_info = {0, 0};
uint64_t now = mach_absolute_time();
if (clock_start_time == 0) {
mach_timebase_info(&timebase_info);
clock_start_time = now;
}
now = (uint64_t)((double)(now - clock_start_time)
* (double)timebase_info.numer
/ (double)timebase_info.denom);
t->tv_sec = now / 1000000000;
t->tv_nsec = now % 1000000000;
return 0;
}
return -1; // EINVAL - Clock ID is unknown
}
/* if clock_gettime is declared, then __CLOCK_AVAILABILITY will be defined */
#ifdef __CLOCK_AVAILABILITY
/* If we compiled with Mac OSX 10.12 or later, then clock_gettime will be declared
* but it may be NULL at runtime. So we need to check before using it. */
int _civet_safe_clock_gettime(int clk_id, struct timespec *t);
int _civet_safe_clock_gettime(int clk_id, struct timespec *t) {
if (clock_gettime) {
return clock_gettime(clk_id, t);
}
return _civet_clock_gettime(clk_id, t);
}
#define clock_gettime _civet_safe_clock_gettime
#else
#define clock_gettime _civet_clock_gettime
#endif
#endif
// a milliseconds timer for performance measurement
uint64_t msclock(void) {
#if defined(_WIN32)
#include <sys/types.h>
// WORKAROUND FOR MinGW (some versions - use if normal code does not compile)
// It has no _ftime_s and needs explicit inclusion of timeb.h
#include <sys/timeb.h>
struct _timeb t;
_ftime(&t);
return 1000 * (uint64_t)t.time + t.millitm;
// NORMAL CODE (use _ftime_s)
//struct _timeb t;
//if (_ftime_s(&t)) {
// return 0;
//} else {
// return 1000 * t.time + t.millitm;
//}
#else
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return (1000 * (uint64_t)t.tv_sec + t.tv_nsec / 1000000);
#endif
}

View File

@@ -0,0 +1,26 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// utilities requiring Posix library functions
//-----------------------------------------------------------------------------
#ifndef UTIL_POSIX_H__
#define UTIL_POSIX_H__
#include "common.h"
#ifdef _WIN32
# include <windows.h>
# define sleep(n) Sleep(1000 *(n))
# define msleep(n) Sleep((n))
#else
void msleep(uint32_t n); // sleep n milliseconds
#endif // _WIN32
uint64_t msclock(void); // a milliseconds clock
#endif

View File

@@ -275,8 +275,8 @@ while true; do
if $TESTALL || $TESTMFNONCEBRUTE; then
echo -e "\n${C_BLUE}Testing mf_nonce_brute:${C_NC} ${MFNONCEBRUTEBIN:=./tools/mf_nonce_brute/mf_nonce_brute}"
if ! CheckFileExist "mf_nonce_brute exists" "$MFNONCEBRUTEBIN"; then break; fi
# if ! CheckExecute slow "mf_nonce_brute test" "$MFNONCEBRUTEBIN 9c599b32 5a920d85 1011 98d76b77 d6c6e870 0000 ca7e0b63 0111 3e709c8a" "Key found \[.*ffffffffffff.*\]"; then break; fi
if ! CheckExecute slow "mf_nonce_brute test" "$MFNONCEBRUTEBIN 96519578 d7e3c6ac 0011 cd311951 9da49e49 0010 2bb22e00 0100 a4f7f398" "Key found \[.*3b7e4fd575ad.*\]"; then break; fi
if ! CheckExecute slow "mf_nonce_brute test" "$MFNONCEBRUTEBIN 9c599b32 5a920d85 1011 98d76b77 d6c6e870 0000 ca7e0b63 0111 3e709c8a" "Key found \[.*ffffffffffff.*\]"; then break; fi
# if ! CheckExecute slow "mf_nonce_brute test" "$MFNONCEBRUTEBIN 96519578 d7e3c6ac 0011 cd311951 9da49e49 0010 2bb22e00 0100 a4f7f398" "Key found \[.*3b7e4fd575ad.*\]"; then break; fi
fi
# hitag2crack not yet part of "all"
# if $TESTALL || $TESTHITAG2CRACK; then
@@ -351,6 +351,12 @@ while true; do
if ! CheckExecute "proxmark help text ISO7816" "$CLIENTBIN -t 2>&1" "ISO7816"; then break; fi
if ! CheckExecute "proxmark help text hardnested" "$CLIENTBIN -t 2>&1" "hardnested"; then break; fi
if ! CheckExecute "proxmark full help dump" "$CLIENTBIN --fulltext 2>&1" "Full help dump done"; then break; fi
if ! CheckExecute "proxmark multi cmds 1/2" "$CLIENTBIN -c 'rem foo;rem bar'" "remark: foo"; then break; fi
if ! CheckExecute "proxmark multi cmds 2/2" "$CLIENTBIN -c 'rem foo;rem bar'" "remark: bar"; then break; fi
if ! CheckExecute "proxmark multi stdin 1/4" "echo 'rem foo;rem bar;quit' |$CLIENTBIN" "remark: foo"; then break; fi
if ! CheckExecute "proxmark multi stdin 2/4" "echo 'rem foo;rem bar;quit' |$CLIENTBIN" "remark: bar"; then break; fi
if ! CheckExecute "proxmark multi stdin 3/4" "echo -e 'rem foo\nrem bar;quit' |$CLIENTBIN" "remark: foo"; then break; fi
if ! CheckExecute "proxmark multi stdin 4/4" "echo -e 'rem foo\nrem bar;quit' |$CLIENTBIN" "remark: bar"; then break; fi
echo -e "\n${C_BLUE}Testing data manipulation:${C_NC}"
if ! CheckExecute "reveng readline test" "$CLIENTBIN -c 'reveng -h;reveng -D'" "CRC-64/GO-ISO"; then break; fi