code style, code clean up of redundant functions, comments, its many minor fixes across the platform. Sorry for not making 20 commits

This commit is contained in:
iceman1001
2025-02-21 15:38:33 +01:00
parent 6bb7199a7b
commit cef07dedf6
57 changed files with 672 additions and 521 deletions
+7
View File
@@ -45,6 +45,13 @@ jobs:
- name: Install dependencies
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-arm-none-eabi libnewlib-dev qtbase5-dev libbz2-dev liblz4-dev libbluetooth-dev libpython3-dev python3 python3-dev libpython3-all-dev liblua5.4-dev liblua5.4-0 lua5.4 sed libssl-dev
- name: Install Python dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install setuptools
python3 -m pip install ansicolors sslcrypto
if [ -f requirements.txt ]; then python3 -m pip install -r requirements.txt; fi
- name: Checkout repository
uses: actions/checkout@v4
+4 -2
View File
@@ -321,9 +321,10 @@ bool RAMFUNC LogTraceBits(const uint8_t *btBytes, uint16_t bitLen, uint32_t time
// Emulator memory
int emlSet(const uint8_t *data, uint32_t offset, uint32_t length) {
uint8_t *mem = BigBuf_get_EM_addr();
if (!mem) {
if (mem == NULL) {
return PM3_EMALLOC;
}
if (offset + length <= CARD_MEMORY_SIZE) {
memcpy(mem + offset, data, length);
return PM3_SUCCESS;
@@ -335,9 +336,10 @@ int emlSet(const uint8_t *data, uint32_t offset, uint32_t length) {
int emlGet(uint8_t *out, uint32_t offset, uint32_t length) {
uint8_t *mem = BigBuf_get_EM_addr();
if (!mem) {
if (mem == NULL) {
return PM3_EMALLOC;
}
if (offset + length <= CARD_MEMORY_SIZE) {
memcpy(out, mem + offset, length);
return PM3_SUCCESS;
+4 -4
View File
@@ -311,7 +311,7 @@ void WriteTagToFlash(uint32_t uid, size_t size) {
uint32_t len = size;
uint8_t data[(size * (16 * 64)) / 1024];
emlGetMem(data, 0, (size * 64) / 1024);
emlGetMem_xt(data, 0, (size * 64) / 1024, MIFARE_BLOCK_SIZE);
char dest[SPIFFS_OBJ_NAME_LEN];
uint8_t buid[4];
@@ -646,7 +646,7 @@ failtag:
emlClearMem();
uint8_t mblock[16];
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
emlGetMem_xt(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1, MIFARE_BLOCK_SIZE);
for (uint8_t t = 0; t < 2; t++) {
memcpy(mblock + t * 10, foundKey[t][sectorNo], 6);
}
@@ -807,7 +807,7 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
emlSetMem_xt(dataoutbuf, FirstBlockOfSector(s) + blockNo, 1, 16);
} else {
// sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1);
emlGetMem_xt(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1, MIFARE_BLOCK_SIZE);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem_xt(dataoutbuf2, FirstBlockOfSector(s) + blockNo, 1, 16);
}
@@ -878,7 +878,7 @@ void saMifareMakeTag(void) {
int flags = 0;
for (int blockNum = 0; blockNum < 16 * 4; blockNum++) {
uint8_t mblock[16];
emlGetMem(mblock, blockNum, 1);
emlGetMem_xt(mblock, blockNum, 1, MIFARE_BLOCK_SIZE);
// switch on field and send magic sequence
if (blockNum == 0)
flags = 0x08 + 0x02;
+1 -1
View File
@@ -500,7 +500,7 @@ void RunMod(void) {
uint8_t mblock[MIFARE_BLOCK_SIZE];
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; ++sectorNo) {
if (validKey[0][sectorNo] || validKey[1][sectorNo]) {
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
emlGetMem_xt(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1, MIFARE_BLOCK_SIZE);
for (uint8_t keyType = 0; keyType < 2; ++keyType) {
if (validKey[keyType][sectorNo]) {
memcpy(mblock + keyType * 10, foundKey[keyType][sectorNo], 6);
+1 -1
View File
@@ -150,7 +150,7 @@ void RunMod(void) {
} else if (playing && selected == 2) {
// Now it work only with HID Corporate 1000 (35bit), but is easily extensible to others RFID.
// It is necessary only to calculate the correct parity.
// Brute force code
// Check if the badge is an HID Corporate 1000
if ((high[selected] & 0xFFFFFFF8) != 0x28) {
+2 -2
View File
@@ -46,7 +46,7 @@ void RunMod(void) {
StandAloneMode();
Dbprintf(">> LF HID proxII bruteforce v2 a.k.a Prox2Brute Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
uint32_t high = 0, low = 0;
uint32_t high = 0;
uint32_t fac = FACILITY_CODE, cardnum = 0;
@@ -78,7 +78,7 @@ void RunMod(void) {
if (BUTTON_HELD(1000) == BUTTON_HOLD) break; // long button press (>=1sec) exit
// calculate the new LF low value including Card number, Facility code and checksum
low = (cardnum << 1) | (fac << 17);
uint32_t low = (cardnum << 1) | (fac << 17);
low |= oddparity32((low >> 1) & 0xFFF);
low |= evenparity32((low >> 13) & 0xFFF) << 25;
add_HID_preamble(NULL, &high, &low, 26);
+45 -12
View File
@@ -1370,7 +1370,11 @@ static void PacketReceived(PacketCommandNG *packet) {
// involved in dealing with emulator memory. But if it is called later, it might
// destroy the Emulator Memory.
//-----------------------------------------------------------------------------
EmlClearIso15693();
// Resetting the bitstream also frees the BigBuf memory, so we do this here to prevent
// an inconvenient reset in the future by Iso15693InitTag
FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15);
BigBuf_Clear_EM();
reply_ng(CMD_HF_ISO15693_EML_CLEAR, PM3_SUCCESS, NULL, 0);
break;
}
case CMD_HF_ISO15693_EML_SETMEM: {
@@ -1402,7 +1406,7 @@ static void PacketReceived(PacketCommandNG *packet) {
return;
}
uint8_t *buf = BigBuf_malloc(payload->length);
uint8_t *buf = BigBuf_calloc(payload->length);
emlGet(buf, payload->offset, payload->length);
LED_B_ON();
reply_ng(CMD_HF_ISO15693_EML_GETMEM, PM3_SUCCESS, buf, payload->length);
@@ -1677,7 +1681,7 @@ static void PacketReceived(PacketCommandNG *packet) {
EMVsim(payload->flags, payload->exitAfter, payload->uid, payload->atqa, payload->sak);
break;
}
#endif
#endif
case CMD_HF_ISO14443A_SIMULATE: {
struct p {
uint8_t tagtype;
@@ -1890,36 +1894,65 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_MIFARE_EML_MEMCLR: {
MifareEMemClr();
reply_ng(CMD_HF_MIFARE_EML_MEMCLR, PM3_SUCCESS, NULL, 0);
//-----------------------------------------------------------------------------
// Work with emulator memory
//
// Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not
// involved in dealing with emulator memory. But if it is called later, it might
// destroy the Emulator Memory.
//-----------------------------------------------------------------------------
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Not only clears the emulator memory,
// also sets default MIFARE values for sector trailers.
emlClearMem();
reply_ng(CMD_HF_MIFARE_EML_MEMCLR, PM3_SUCCESS, NULL, 0);
break;
}
case CMD_HF_MIFARE_EML_MEMSET: {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
struct p {
uint8_t blockno;
uint16_t blockno;
uint8_t blockcnt;
uint8_t blockwidth;
uint8_t data[];
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// backwards compat... default bytewidth
if (payload->blockwidth == 0)
payload->blockwidth = 16;
if (payload->blockwidth == 0) {
payload->blockwidth = MIFARE_BLOCK_SIZE;
}
emlSetMem_xt(payload->data, payload->blockno, payload->blockcnt, payload->blockwidth);
break;
}
case CMD_HF_MIFARE_EML_MEMGET: {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
struct p {
uint8_t blockno;
uint16_t blockno;
uint8_t blockcnt;
uint8_t blockwidth;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
MifareEMemGet(payload->blockno, payload->blockcnt);
//
size_t size = payload->blockno * payload->blockwidth;
if (size > PM3_CMD_DATA_SIZE) {
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0);
return;
}
uint8_t *buf = BigBuf_calloc(size);
emlGetMem_xt(buf, payload->blockno, payload->blockcnt, payload->blockwidth); // data, block num, blocks count (max 4)
LED_B_ON();
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_SUCCESS, buf, size);
LED_B_OFF();
BigBuf_free_keep_EM();
break;
}
case CMD_HF_MIFARE_EML_LOAD: {
+107 -74
View File
@@ -133,7 +133,9 @@ void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, ui
}
void aes128_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[16]) {
if (length % 8) return;
if (length % 8) {
return;
}
uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out;
@@ -143,7 +145,9 @@ void aes128_nxp_receive(const void *in, void *out, size_t length, const void *ke
}
void aes128_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[16]) {
if (length % 8) return;
if (length % 8) {
return;
}
uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out;
@@ -152,12 +156,15 @@ void aes128_nxp_send(const void *in, void *out, size_t length, const void *key,
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_ENCRYPT, length, iv, tin, tout);
}
void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key) {
uint8_t data[8];
memcpy(data, value, 8);
for (int n = 0; n < 8; n++) {
void Desfire_des_key_new(const uint8_t *value, desfirekey_t key) {
uint8_t data[8] = {0};
memcpy(data, value, sizeof(data));
for (size_t n = 0; n < sizeof(data); n++) {
data[n] &= 0xFE;
}
Desfire_des_key_new_with_version(data, key);
}
@@ -246,22 +253,24 @@ void Desfire_key_set_version(desfirekey_t key, uint8_t version) {
void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key) {
uint8_t buffer[24];
uint8_t buffer[24] = {0};
switch (authkey->type) {
case T_DES:
case T_DES: {
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
Desfire_des_key_new_with_version(buffer, key);
break;
case T_3DES:
}
case T_3DES: {
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 4, 4);
memcpy(buffer + 12, rndb + 4, 4);
Desfire_3des_key_new_with_version(buffer, key);
break;
case T_3K3DES:
}
case T_3K3DES: {
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 6, 4);
@@ -270,22 +279,15 @@ void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfire
memcpy(buffer + 20, rndb + 12, 4);
Desfire_3k3des_key_new(buffer, key);
break;
case T_AES:
}
case T_AES: {
memcpy(buffer, rnda, 4);
memcpy(buffer + 4, rndb, 4);
memcpy(buffer + 8, rnda + 12, 4);
memcpy(buffer + 12, rndb + 12, 4);
Desfire_aes_key_new(buffer, key);
break;
}
}
static size_t key_macing_length(desfirekey_t key);
// iceman, see memxor inside string.c, dest/src swapped..
static void xor(const uint8_t *ivect, uint8_t *data, const size_t len) {
for (size_t i = 0; i < len; i++) {
data[i] ^= ivect[i];
}
}
}
@@ -306,7 +308,7 @@ void cmac_generate_subkeys(desfirekey_t key) {
// Used to compute CMAC on complete blocks
memcpy(key->cmac_sk1, l, kbs);
txor = l[0] & 0x80;
txor = (l[0] & 0x80);
lsl(key->cmac_sk1, kbs);
@@ -317,7 +319,7 @@ void cmac_generate_subkeys(desfirekey_t key) {
// Used to compute CMAC on the last block if non-complete
memcpy(key->cmac_sk2, key->cmac_sk1, kbs);
txor = key->cmac_sk1[0] & 0x80;
txor = (key->cmac_sk1[0] & 0x80);
lsl(key->cmac_sk2, kbs);
@@ -341,15 +343,14 @@ void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t le
while (len % kbs) {
buffer[len++] = 0x00;
}
xor(key->cmac_sk2, buffer + len - kbs, kbs);
xor(buffer + len - kbs, key->cmac_sk2, kbs);
} else {
xor(key->cmac_sk1, buffer + len - kbs, kbs);
xor(buffer + len - kbs, key->cmac_sk1, kbs);
}
mifare_cypher_blocks_chained(NULL, key, ivect, buffer, len, MCD_SEND, MCO_ENCYPHER);
memcpy(cmac, ivect, kbs);
//free(buffer);
}
size_t key_block_size(const desfirekey_t key) {
@@ -374,7 +375,7 @@ size_t key_block_size(const desfirekey_t key) {
/*
* Size of MACing produced with the key.
*/
static size_t key_macing_length(const desfirekey_t key) {
size_t key_macing_length(const desfirekey_t key) {
size_t mac_length = DESFIRE_MAC_LENGTH;
switch (key->type) {
case T_DES:
@@ -393,10 +394,11 @@ static size_t key_macing_length(const desfirekey_t key) {
* Size required to store nbytes of data in a buffer of size n*block_size.
*/
size_t padded_data_length(const size_t nbytes, const size_t block_size) {
if ((!nbytes) || (nbytes % block_size))
if ((!nbytes) || (nbytes % block_size)) {
return ((nbytes / block_size) + 1) * block_size;
else
} else {
return nbytes;
}
}
/*
@@ -412,12 +414,14 @@ size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int c
size_t crc_length = 0;
if (!(communication_settings & NO_CRC)) {
switch (DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
case AS_LEGACY: {
crc_length = 2;
break;
case AS_NEW:
}
case AS_NEW: {
crc_length = 4;
break;
}
}
}
@@ -428,18 +432,20 @@ size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int c
void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings) {
uint8_t *res = data;
uint8_t mac[4];
uint8_t mac[4] = {0};
size_t edl;
bool append_mac = true;
desfirekey_t key = DESFIRE(tag)->session_key;
if (!key)
desfirekey_t key = DESFIRE(tag)->session_key;
if (!key) {
return data;
}
switch (communication_settings & MDCM_MASK) {
case MDCM_PLAIN:
if (AS_LEGACY == DESFIRE(tag)->authentication_scheme)
case MDCM_PLAIN: {
if (AS_LEGACY == DESFIRE(tag)->authentication_scheme) {
break;
}
/*
* When using new authentication methods, PLAIN data transmission from
@@ -452,13 +458,16 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
*/
append_mac = false;
}
/* pass through */
case MDCM_MACED:
case MDCM_MACED: {
switch (DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
if (!(communication_settings & MAC_COMMAND))
case AS_LEGACY: {
if (!(communication_settings & MAC_COMMAND)) {
break;
}
/* pass through */
edl = padded_data_length(*nbytes - offset, key_block_size(DESFIRE(tag)->session_key)) + offset;
@@ -475,8 +484,9 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
// Copy again provided data (was overwritten by mifare_cypher_blocks_chained)
memcpy(res, data, *nbytes);
if (!(communication_settings & MAC_COMMAND))
if (!(communication_settings & MAC_COMMAND)) {
break;
}
// Append MAC
size_t bla = maced_data_length(DESFIRE(tag)->session_key, *nbytes - offset) + offset;
(void)bla++;
@@ -485,9 +495,12 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
*nbytes += 4;
break;
case AS_NEW:
if (!(communication_settings & CMAC_COMMAND))
}
case AS_NEW: {
if (!(communication_settings & CMAC_COMMAND)) {
break;
}
cmac(key, DESFIRE(tag)->ivect, res, *nbytes, DESFIRE(tag)->cmac);
if (append_mac) {
@@ -498,10 +511,11 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
*nbytes += DESFIRE_CMAC_LENGTH;
}
break;
}
}
break;
case MDCM_ENCIPHERED:
}
case MDCM_ENCIPHERED: {
/* |<-------------- data -------------->|
* |<--- offset -->| |
* +---------------+--------------------+-----+---------+
@@ -517,8 +531,10 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
* encypher()/decypher()
*/
if (!(communication_settings & ENC_COMMAND))
if (!(communication_settings & ENC_COMMAND)) {
break;
}
edl = enciphered_data_length(tag, *nbytes - offset, communication_settings) + offset;
// Fill in the crypto buffer with data ...
@@ -526,14 +542,16 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
if (!(communication_settings & NO_CRC)) {
// ... CRC ...
switch (DESFIRE(tag)->authentication_scheme) {
case AS_LEGACY:
case AS_LEGACY: {
AddCrc14A(res + offset, *nbytes - offset);
*nbytes += 2;
break;
case AS_NEW:
}
case AS_NEW: {
crc32_append(res, *nbytes);
*nbytes += 4;
break;
}
}
}
// ... and padding
@@ -543,32 +561,34 @@ void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes,
mifare_cypher_blocks_chained(tag, NULL, NULL, res + offset, *nbytes - offset, MCD_SEND, (AS_NEW == DESFIRE(tag)->authentication_scheme) ? MCO_ENCYPHER : MCO_DECYPHER);
break;
default:
}
default: {
*nbytes = -1;
res = NULL;
break;
}
}
return res;
}
void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes, int communication_settings) {
void *res = data;
uint8_t first_cmac_byte = 0x00;
desfirekey_t key = DESFIRE(tag)->session_key;
if (!key) {
return data;
}
// Return directly if we just have a status code.
if (1 == *nbytes) {
return res;
}
desfirekey_t key = DESFIRE(tag)->session_key;
if (!key) {
return data;
}
uint8_t first_cmac_byte = 0x00;
switch (communication_settings & MDCM_MASK) {
case MDCM_PLAIN: {
@@ -659,11 +679,12 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
break;
}
case MDCM_ENCIPHERED: {
(*nbytes)--;
bool verified = false;
int crc_pos = 0x00;
int end_crc_pos = 0x00;
uint8_t x;
/*
* AS_LEGACY:
@@ -742,8 +763,9 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
verified = true;
for (int n = end_crc_pos; n < *nbytes - 1; n++) {
uint8_t byte = ((uint8_t *)res)[n];
if (!((0x00 == byte) || ((0x80 == byte) && (n == end_crc_pos))))
if (!((0x00 == byte) || ((0x80 == byte) && (n == end_crc_pos)))) {
verified = false;
}
}
}
@@ -768,7 +790,7 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
break;
}
case AS_NEW: {
x = ((uint8_t *)res)[crc_pos - 1];
uint8_t x = ((uint8_t *)res)[crc_pos - 1];
((uint8_t *)res)[crc_pos - 1] = ((uint8_t *)res)[crc_pos];
((uint8_t *)res)[crc_pos] = x;
break;
@@ -802,9 +824,10 @@ void *mifare_cryto_postprocess_data(desfiretag_t tag, void *data, size_t *nbytes
void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect, MifareCryptoDirection direction, MifareCryptoOperation operation, size_t block_size) {
uint8_t ovect[DESFIRE_MAX_CRYPTO_BLOCK_SIZE];
if (direction == MCD_SEND) {
xor(ivect, data, block_size);
xor(data, ivect, block_size);
} else {
memcpy(ovect, data, block_size);
}
@@ -812,70 +835,80 @@ void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect,
uint8_t edata[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
switch (key->type) {
case T_DES:
case T_DES: {
switch (operation) {
case MCO_ENCYPHER:
case MCO_ENCYPHER: {
//DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
des_encrypt(edata, data, key->data);
break;
case MCO_DECYPHER:
}
case MCO_DECYPHER: {
//DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
des_decrypt(edata, data, key->data);
break;
}
}
break;
case T_3DES:
}
case T_3DES: {
switch (operation) {
case MCO_ENCYPHER:
case MCO_ENCYPHER: {
mbedtls_des3_set2key_enc(&ctx3, key->data);
mbedtls_des3_crypt_ecb(&ctx3, data, edata);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
break;
case MCO_DECYPHER:
}
case MCO_DECYPHER: {
mbedtls_des3_set2key_dec(&ctx3, key->data);
mbedtls_des3_crypt_ecb(&ctx3, data, edata);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
break;
}
}
break;
case T_3K3DES:
}
case T_3K3DES: {
switch (operation) {
case MCO_ENCYPHER:
case MCO_ENCYPHER: {
mbedtls_des3_set3key_enc(&ctx3, key->data);
mbedtls_des3_crypt_ecb(&ctx3, data, edata);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_ENCRYPT);
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_DECRYPT);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_ENCRYPT);
break;
case MCO_DECYPHER:
}
case MCO_DECYPHER: {
mbedtls_des3_set3key_dec(&ctx3, key->data);
mbedtls_des3_crypt_ecb(&ctx3, data, edata);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks3), DES_DECRYPT);
// DES_ecb_encrypt ((DES_cblock *) edata, (DES_cblock *) data, &(key->ks2), DES_ENCRYPT);
// DES_ecb_encrypt ((DES_cblock *) data, (DES_cblock *) edata, &(key->ks1), DES_DECRYPT);
break;
}
}
break;
case T_AES:
}
case T_AES: {
switch (operation) {
case MCO_ENCYPHER: {
mbedtls_aes_init(&actx);
mbedtls_aes_setkey_enc(&actx, key->data, 128);
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_ENCRYPT, sizeof(edata), ivect, data, edata);
mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_ENCRYPT, data, edata);
break;
}
case MCO_DECYPHER: {
mbedtls_aes_init(&actx);
mbedtls_aes_setkey_dec(&actx, key->data, 128);
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_DECRYPT, sizeof(edata), ivect, edata, data);
mbedtls_aes_crypt_ecb(&actx, MBEDTLS_AES_DECRYPT, data, edata);
break;
}
}
break;
}
}
memcpy(data, edata, block_size);
@@ -883,7 +916,7 @@ void mifare_cypher_single_block(desfirekey_t key, uint8_t *data, uint8_t *ivect,
if (direction == MCD_SEND) {
memcpy(ivect, data, block_size);
} else {
xor(ivect, data, block_size);
xor(data, ivect, block_size);
memcpy(ivect, ovect, block_size);
}
}
+3 -1
View File
@@ -183,7 +183,7 @@ void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, ui
void aes128_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[16]);
void aes128_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[16]);
void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key);
void Desfire_des_key_new(const uint8_t *value, desfirekey_t key);
void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key);
void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key);
void Desfire_3des_key_new_with_version(const uint8_t value[16], desfirekey_t key);
@@ -207,4 +207,6 @@ size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int c
void cmac_generate_subkeys(desfirekey_t key);
void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac);
size_t key_macing_length(desfirekey_t key);
#endif
+4 -3
View File
@@ -125,7 +125,7 @@ void ExecuteEMVSim(uint8_t *receivedCmd, uint16_t receivedCmd_len, uint8_t *rece
Dbprintf("");
// use annotate to give some hints about the command
annotate(&receivedCmd[1], receivedCmd_len-1);
annotate(&receivedCmd[1], receivedCmd_len - 1);
// This is a common request from the reader which we can just immediately respond to since we know we can't
// handle it.
@@ -141,7 +141,7 @@ void ExecuteEMVSim(uint8_t *receivedCmd, uint16_t receivedCmd_len, uint8_t *rece
currentState = GENERATE_AC;
memcpy(receivedCmd, (unsigned char[]){ 0x03, 0x80, 0xae, 0x80, 0x00, 0x1d }, 6);
memcpy(receivedCmd, (unsigned char[]) { 0x03, 0x80, 0xae, 0x80, 0x00, 0x1d }, 6);
for (int i = 0; i < 29; i++) {
receivedCmd[6 + i] = receivedCmd[12 + i];
@@ -240,7 +240,8 @@ void ExecuteEMVSim(uint8_t *receivedCmd, uint16_t receivedCmd_len, uint8_t *rece
0x20, 0x00, 0x9f, 0x26, 0x08, 0x56, 0xcb, 0x4e, 0xe1, 0xa4,
0xef, 0xac, 0x74, 0x9f, 0x27, 0x01, 0x80, 0x9f, 0x36, 0x02,
0x00, 0x07, 0x9f, 0x6c, 0x02, 0x3e, 0x00, 0x9f, 0x6e, 0x04,
0x20, 0x70, 0x00, 0x00, 0x90, 0x00, 0xff, 0xff};
0x20, 0x70, 0x00, 0x00, 0x90, 0x00, 0xff, 0xff
};
// do the replacement
template[0] = responseToReader[0]; // class bit 0
+1 -1
View File
@@ -1035,7 +1035,7 @@ static int hts_send_receive(const uint8_t *tx, size_t txlen, uint8_t *rx, size_t
Dbhexdump(*rxlen, response_bit, false);
Dbprintf("htS: skipping %d bit SOF", sof_bits);
if ((rx[0] >> (8 - sof_bits)) != ((1 << sof_bits) - 1)) {
if ((rx[0] >> (8 - sof_bits)) != ((1 << sof_bits) - 1)) {
DBG DbpString("htS: Warning, not all bits of SOF are 1");
}
}
+10 -10
View File
@@ -1455,7 +1455,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data,
// response to send, and send it.
// 'hf 14a sim'
//-----------------------------------------------------------------------------
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads,
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
uint8_t *ats, size_t ats_len) {
#define ATTACK_KEY_COUNT 16
@@ -1508,7 +1508,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_
.modulation_n = 0
};
if (SimulateIso14443aInit(tagType, flags, data, ats, ats_len, &responses, &cuid, counters, tearings, &pages) == false) {
if (SimulateIso14443aInit(tagType, flags, useruid, ats, ats_len, &responses, &cuid, counters, tearings, &pages) == false) {
BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
return;
@@ -1684,8 +1684,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_
// first blocks of emu are header
uint16_t start = block * 4 + MFU_DUMP_PREFIX_LENGTH;
uint8_t emdata[MAX_MIFARE_FRAME_SIZE];
emlGet(emdata, start, 16);
AddCrc14A(emdata, 16);
emlGet(emdata, start, MIFARE_BLOCK_SIZE);
AddCrc14A(emdata, MIFARE_BLOCK_SIZE);
EmSendCmd(emdata, sizeof(emdata));
numReads++; // Increment number of times reader requested a block
@@ -1703,8 +1703,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_
p_response = &responses[RESP_INDEX_UIDC1];
} else { // all other tags (16 byte block tags)
uint8_t emdata[MAX_MIFARE_FRAME_SIZE] = {0};
emlGet(emdata, block, 16);
AddCrc14A(emdata, 16);
emlGet(emdata, block, MIFARE_BLOCK_SIZE);
AddCrc14A(emdata, MIFARE_BLOCK_SIZE);
EmSendCmd(emdata, sizeof(emdata));
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
p_response = NULL;
@@ -1847,7 +1847,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_
}
if (memcmp(pwd, "\x00\x00\x00\x00", 4) == 0) {
Uint4byteToMemLe(pwd, ul_ev1_pwdgenB(data));
Uint4byteToMemLe(pwd, ul_ev1_pwdgenB(useruid));
if (g_dbglevel >= DBG_DEBUG) Dbprintf("Calc pwd... %02X %02X %02X %02X", pwd[0], pwd[1], pwd[2], pwd[3]);
}
@@ -4080,7 +4080,7 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
dynamic_response_info.response[0] = receivedCmd[0];
dynamic_response_info.response[1] = 0x00;
switch (receivedCmd[2+offset]) { // APDU Class Byte
switch (receivedCmd[2 + offset]) { // APDU Class Byte
// receivedCmd in this case is expecting to structured with possibly a CID, then the APDU command for SelectFile
// | IBlock (CID) | CID | APDU Command | CRC |
// or | IBlock (noCID) | APDU Command | CRC |
@@ -4092,8 +4092,8 @@ void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
// xx in this case is len of the AID value in hex
// aid len is found as a hex value in receivedCmd[6] (Index Starts at 0)
int received_aid_len = receivedCmd[5+offset];
uint8_t *received_aid = &receivedCmd[6+offset];
int received_aid_len = receivedCmd[5 + offset];
uint8_t *received_aid = &receivedCmd[6 + offset];
// aid enumeration flag
if ((flags & FLAG_ENUMERATE_AID) == FLAG_ENUMERATE_AID) {
+1 -1
View File
@@ -142,7 +142,7 @@ RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time);
RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time);
void RAMFUNC SniffIso14443a(uint8_t param);
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_t exitAfterNReads,
void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *useruid, uint8_t exitAfterNReads,
uint8_t *iRATs, size_t irats_len);
void SimulateIso14443aTagAID(uint8_t tagType, uint16_t flags, uint8_t *uid,
-8
View File
@@ -2117,14 +2117,6 @@ void Iso15693InitTag(void) {
StartCountSspClk();
}
void EmlClearIso15693(void) {
// Resetting the bitstream also frees the BigBuf memory, so we do this here to prevent
// an inconvenient reset in the future by Iso15693InitTag
FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15);
BigBuf_Clear_EM();
reply_ng(CMD_HF_ISO15693_EML_CLEAR, PM3_SUCCESS, NULL, 0);
}
// Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
// all demodulation performed in arm rather than host. - greg
void SimTagIso15693(const uint8_t *uid, uint8_t block_size) {
-1
View File
@@ -46,7 +46,6 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo
//void RecordRawAdcSamplesIso15693(void);
void AcquireRawAdcSamplesIso15693(void);
void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader
void EmlClearIso15693(void);
void SimTagIso15693(const uint8_t *uid, uint8_t block_size); // simulate an ISO15693 tag
void BruteforceIso15693Afi(uint32_t flags); // find an AFI of a tag
void SendRawCommand15693(iso15_raw_cmd_t *packet); // send arbitrary commands from CLI
+2 -2
View File
@@ -944,7 +944,7 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, int16_t *remainder) {
}
}
bool add_HID_preamble(uint32_t *hi2, uint32_t *hi, uint32_t *lo, uint8_t length){
bool add_HID_preamble(uint32_t *hi2, uint32_t *hi, uint32_t *lo, uint8_t length) {
// Invalid value
if (length > 84 || length == 0)
return false;
@@ -963,7 +963,7 @@ bool add_HID_preamble(uint32_t *hi2, uint32_t *hi, uint32_t *lo, uint8_t length)
// No header bits added to 37-bit cards
} else if (length >= 32) {
*hi |= 0x20; // Bit 37; standard header
*hi |= 1U << (length - 32); // leading 1: start bit
*hi |= 1U << (length - 32); // leading 1: start bit
} else {
*hi |= 0x20; // Bit 37; standard header
*lo |= 1U << length; // leading 1: start bit
+1 -1
View File
@@ -24,7 +24,7 @@
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint16_t period_0, uint16_t period_1,
const uint8_t *symbol_extra, uint16_t *period_extra, uint8_t *command, bool verbose,
bool keep_field_on, uint32_t samples, bool ledcontrol);
void ReadTItag(bool ledcontrol);
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc, bool ledcontrol);
+131 -162
View File
@@ -2223,7 +2223,7 @@ OUT:
blockno = (32 * 4 + (i - 32) * 16) ^ 0xF;
}
// get ST
emlGetMem(block, blockno, 1);
emlGetMem_xt(block, blockno, 1, MIFARE_BLOCK_SIZE);
memcpy(block, k_sector[i].keyA, 6);
memcpy(block + 10, k_sector[i].keyB, 6);
@@ -2427,39 +2427,6 @@ void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint64_t key) {
}
//-----------------------------------------------------------------------------
// Work with emulator memory
//
// Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not
// involved in dealing with emulator memory. But if it is called later, it might
// destroy the Emulator Memory.
//-----------------------------------------------------------------------------
void MifareEMemClr(void) {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
emlClearMem();
}
void MifareEMemGet(uint8_t blockno, uint8_t blockcnt) {
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
//
size_t size = blockcnt * 16;
if (size > PM3_CMD_DATA_SIZE) {
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0);
return;
}
uint8_t *buf = BigBuf_malloc(size);
emlGetMem(buf, blockno, blockcnt); // data, block num, blocks count (max 4)
LED_B_ON();
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_SUCCESS, buf, size);
LED_B_OFF();
BigBuf_free_keep_EM();
}
//-----------------------------------------------------------------------------
// Load a card into the emulator memory
//
@@ -2471,12 +2438,15 @@ int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype, uint8_t *key) {
}
int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key) {
if ((keytype > MF_KEY_B) && (key == NULL)) {
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("Error, missing key");
}
return PM3_EINVARG;
}
LED_A_ON();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
@@ -2510,10 +2480,10 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key) {
// MFC 1K EV1, skip sector 16 since its lockdown
if (s == 16) {
// unknown sector trailer, keep the keys, set only the AC
uint8_t st[16] = {0x00};
emlGetMem(st, FirstBlockOfSector(s) + 3, 1);
uint8_t st[MIFARE_BLOCK_SIZE] = {0x00};
emlGetMem_xt(st, FirstBlockOfSector(s) + 3, 1, MIFARE_BLOCK_SIZE);
memcpy(st + 6, "\x70\xF0\xF8\x69", 4);
emlSetMem_xt(st, FirstBlockOfSector(s) + 3, 1, 16);
emlSetMem_xt(st, FirstBlockOfSector(s) + 3, 1, MIFARE_BLOCK_SIZE);
continue;
}
@@ -2556,7 +2526,8 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key) {
}
have_uid = true;
} else { // no need for anticollision. We can directly select the card
if (!bd_authenticated) { // no need to select if bd_authenticated with backdoor
if (bd_authenticated == false) { // no need to select if bd_authenticated with backdoor
if (iso14443a_fast_select_card(uid, cascade_levels) == 0) {
continue;
}
@@ -2565,7 +2536,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key) {
// Auth
if (keytype > MF_KEY_B) {
if (! bd_authenticated) {
if (bd_authenticated == false) {
ui64Key = bytes_to_num(key, 6);
if (mifare_classic_auth(pcs, cuid, 0, keytype, ui64Key, AUTH_FIRST)) {
retval = PM3_EFAILED;
@@ -2592,7 +2563,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key) {
#define MAX_RETRIES 2
uint8_t data[16] = {0x00};
uint8_t data[MIFARE_BLOCK_SIZE] = {0x00};
for (uint8_t b = 0; b < NumBlocksPerSector(s); b++) {
memset(data, 0x00, sizeof(data));
@@ -2614,18 +2585,18 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key) {
}
// No need to copy empty
if (memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16) == 0) {
if (memcmp(data, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sizeof(data)) == 0) {
break;
}
if (IsSectorTrailer(b)) {
// sector trailer, keep the keys, set only the AC
uint8_t st[16] = {0x00};
emlGetMem(st, tb, 1);
uint8_t st[MIFARE_BLOCK_SIZE] = {0x00};
emlGetMem_xt(st, tb, 1, MIFARE_BLOCK_SIZE);
memcpy(st + 6, data + 6, 4);
emlSetMem_xt(st, tb, 1, 16);
emlSetMem_xt(st, tb, 1, MIFARE_BLOCK_SIZE);
} else {
emlSetMem_xt(data, tb, 1, 16);
emlSetMem_xt(data, tb, 1, MIFARE_BLOCK_SIZE);
}
break;
}
@@ -2927,7 +2898,6 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
// variables
uint8_t rec[1] = {0x00};
uint8_t recpar[1] = {0x00};
uint8_t rats[4] = {ISO14443A_CMD_RATS, 0x80, 0x31, 0x73};
uint8_t rdblf0[4] = {ISO14443A_CMD_READBLOCK, 0xF0, 0x8D, 0x5f};
uint8_t rdbl00[4] = {ISO14443A_CMD_READBLOCK, 0x00, 0x02, 0xa8};
uint8_t gen4gdmAuth[4] = {MIFARE_MAGIC_GDM_AUTH_KEY, 0x00, 0x6C, 0x92};
@@ -2940,6 +2910,8 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
uint8_t *par = BigBuf_calloc(MAX_PARITY_SIZE);
uint8_t *buf = BigBuf_calloc(PM3_CMD_DATA_SIZE);
uint8_t *uid = BigBuf_calloc(10);
iso14a_card_select_t *card = (iso14a_card_select_t *) BigBuf_calloc(sizeof(iso14a_card_select_t));
uint16_t flag = MAGIC_FLAG_NONE;
uint32_t cuid = 0;
int res = 0;
@@ -2991,144 +2963,141 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
// reset card
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, false);
res = iso14443a_select_card(uid, card, &cuid, true, 0, false);
if (res) {
if (cuid == 0xAA55C396) {
flag |= MAGIC_FLAG_GEN_UNFUSED;
}
ReaderTransmit(rats, sizeof(rats), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (memcmp(card->ats, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10", 9) == 0) {
// test for some MFC gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(card->ats, "\x0D\x78\x00\x71\x02\x88\x49\xA1\x30\x20\x15\x06\x08\x56\x3D", 15) == 0) {
// test for some MFC 7b gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(card->ats, "\x0A\x78\x00\x81\x02\xDB\xA0\xC1\x19\x40\x2A\xB5", 12) == 0) {
// test for Ultralight magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(card->ats, "\x85\x00\x00\xA0\x00\x00\x0A\xC3\x00\x04\x03\x01\x01\x00\x0B\x03\x41\xDF", 18) == 0) {
// test for Ultralight EV1 magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(card->ats, "\x85\x00\x00\xA0\x0A\x00\x0A\xC3\x00\x04\x03\x01\x01\x00\x0B\x03\x16\xD7", 18) == 0) {
// test for some other Ultralight EV1 magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(card->ats, "\x85\x00\x00\xA0\x0A\x00\x0A\xB0\x00\x00\x00\x00\x00\x00\x00\x00\x18\x4D", 18) == 0) {
// test for some other Ultralight magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(card->ats, "\x85\x00\x00\xA0\x00\x00\x0A\xA5\x00\x04\x04\x02\x01\x00\x0F\x03\x79\x0C", 18) == 0) {
// test for NTAG213 magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
}
if (res) {
if (memcmp(buf, "\x09\x78\x00\x91\x02\xDA\xBC\x19\x10", 9) == 0) {
// test for some MFC gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(buf, "\x0D\x78\x00\x71\x02\x88\x49\xA1\x30\x20\x15\x06\x08\x56\x3D", 15) == 0) {
// test for some MFC 7b gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(buf, "\x0A\x78\x00\x81\x02\xDB\xA0\xC1\x19\x40\x2A\xB5", 12) == 0) {
// test for Ultralight magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(buf, "\x85\x00\x00\xA0\x00\x00\x0A\xC3\x00\x04\x03\x01\x01\x00\x0B\x03\x41\xDF", 18) == 0) {
// test for Ultralight EV1 magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(buf, "\x85\x00\x00\xA0\x0A\x00\x0A\xC3\x00\x04\x03\x01\x01\x00\x0B\x03\x16\xD7", 18) == 0) {
// test for some other Ultralight EV1 magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(buf, "\x85\x00\x00\xA0\x0A\x00\x0A\xB0\x00\x00\x00\x00\x00\x00\x00\x00\x18\x4D", 18) == 0) {
// test for some other Ultralight magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
} else if (memcmp(buf, "\x85\x00\x00\xA0\x00\x00\x0A\xA5\x00\x04\x04\x02\x01\x00\x0F\x03\x79\x0C", 18) == 0) {
// test for NTAG213 magic gen2
isGen2 = true;
flag |= MAGIC_FLAG_GEN_2;
// test for super card
ReaderTransmit(superGen1, sizeof(superGen1), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 22) {
uint8_t isGen = MAGIC_FLAG_SUPER_GEN1;
// check for super card gen2
// not available after RATS, reset card before executing
mf_reset_card();
iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
ReaderTransmit(rdbl00, sizeof(rdbl00), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 18) {
isGen = MAGIC_FLAG_SUPER_GEN2;
}
// test for super card
ReaderTransmit(superGen1, sizeof(superGen1), NULL);
flag |= isGen;
}
}
if (is_mfc == false) {
// magic ntag test
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res == 2) {
ReaderTransmit(rdblf0, sizeof(rdblf0), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 22) {
uint8_t isGen = MAGIC_FLAG_SUPER_GEN1;
// check for super card gen2
// not available after RATS, reset card before executing
mf_reset_card();
iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
ReaderTransmit(rdbl00, sizeof(rdbl00), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 18) {
isGen = MAGIC_FLAG_SUPER_GEN2;
}
flag |= isGen;
if (res == 18) {
flag |= MAGIC_FLAG_NTAG21X;
}
}
if (is_mfc == false) {
// magic ntag test
} else {
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
// CUID (with default sector 0 B key) test
// regular cards will NAK the WRITEBLOCK(0) command, while DirectWrite will ACK it
// if we do get an ACK, we immediately abort to ensure nothing is ever actually written
// only perform test if we haven't already identified Gen2. No need test if we have a positive identification already
if (isGen2 == false) {
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res == 2) {
ReaderTransmit(rdblf0, sizeof(rdblf0), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 18) {
flag |= MAGIC_FLAG_NTAG21X;
}
}
} else {
if (res) {
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
uint64_t tmpkey = bytes_to_num(key, 6);
if (mifare_classic_authex(pcs, cuid, 0, keytype, tmpkey, AUTH_FIRST, NULL, NULL) == 0) {
// CUID (with default sector 0 B key) test
// regular cards will NAK the WRITEBLOCK(0) command, while DirectWrite will ACK it
// if we do get an ACK, we immediately abort to ensure nothing is ever actually written
// only perform test if we haven't already identified Gen2. No need test if we have a positive identification already
if (isGen2 == false) {
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res) {
uint64_t tmpkey = bytes_to_num(key, 6);
if (mifare_classic_authex(pcs, cuid, 0, keytype, tmpkey, AUTH_FIRST, NULL, NULL) == 0) {
if ((mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, 0, buf, PM3_CMD_DATA_SIZE, par, NULL) == 1) && (buf[0] == 0x0A)) {
flag |= MAGIC_FLAG_GEN_2;
// turn off immediately to ensure nothing ever accidentally writes to the block
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
if ((mifare_sendcmd_short(pcs, 1, ISO14443A_CMD_WRITEBLOCK, 0, buf, PM3_CMD_DATA_SIZE, par, NULL) == 1) && (buf[0] == 0x0A)) {
flag |= MAGIC_FLAG_GEN_2;
// turn off immediately to ensure nothing ever accidentally writes to the block
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
crypto1_deinit(pcs);
}
}
// magic MFC Gen3 test 1
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res) {
ReaderTransmit(rdbl00, sizeof(rdbl00), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 18) {
flag |= MAGIC_FLAG_GEN_3;
}
}
// magic MFC Gen4 GDM magic auth test
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res) {
ReaderTransmit(gen4gdmAuth, sizeof(gen4gdmAuth), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 4) {
flag |= MAGIC_FLAG_GDM_AUTH;
}
}
// QL88 test
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res) {
if (mifare_classic_authex(pcs, cuid, 68, MF_KEY_B, 0x707B11FC1481, AUTH_FIRST, NULL, NULL) == 0) {
flag |= MAGIC_FLAG_QL88;
}
crypto1_deinit(pcs);
}
}
};
// magic MFC Gen3 test 1
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res) {
ReaderTransmit(rdbl00, sizeof(rdbl00), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 18) {
flag |= MAGIC_FLAG_GEN_3;
}
}
// magic MFC Gen4 GDM magic auth test
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res) {
ReaderTransmit(gen4gdmAuth, sizeof(gen4gdmAuth), NULL);
res = ReaderReceive(buf, PM3_CMD_DATA_SIZE, par);
if (res == 4) {
flag |= MAGIC_FLAG_GDM_AUTH;
}
}
// QL88 test
mf_reset_card();
res = iso14443a_select_card(uid, NULL, &cuid, true, 0, true);
if (res) {
if (mifare_classic_authex(pcs, cuid, 68, MF_KEY_B, 0x707B11FC1481, AUTH_FIRST, NULL, NULL) == 0) {
flag |= MAGIC_FLAG_QL88;
}
crypto1_deinit(pcs);
}
}
// GDM alt magic wakeup (20)
ReaderTransmitBitsPar(wupGDM1, 7, NULL, NULL);
-2
View File
@@ -43,8 +43,6 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem);
void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareChkKeys_file(uint8_t *fn);
void MifareEMemClr(void);
void MifareEMemGet(uint8_t blockno, uint8_t blockcnt);
int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key);
int MifareECardLoadExt(uint8_t sectorcnt, uint8_t keytype, uint8_t *key);
+86 -41
View File
@@ -48,8 +48,8 @@
#include "parity.h"
static bool IsKeyBReadable(uint8_t blockNo) {
uint8_t sector_trailer[16];
emlGetMem(sector_trailer, SectorTrailer(blockNo), 1);
uint8_t sector_trailer[MIFARE_BLOCK_SIZE] = {0};
emlGetMem_xt(sector_trailer, SectorTrailer(blockNo), 1, MIFARE_BLOCK_SIZE);
uint8_t AC = ((sector_trailer[7] >> 5) & 0x04)
| ((sector_trailer[8] >> 2) & 0x02)
| ((sector_trailer[8] >> 7) & 0x01);
@@ -57,55 +57,64 @@ static bool IsKeyBReadable(uint8_t blockNo) {
}
static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
uint8_t sector_trailer[16];
emlGetMem(sector_trailer, blockNo, 1);
uint8_t sector_trailer[MIFARE_BLOCK_SIZE] = {0};
emlGetMem_xt(sector_trailer, blockNo, 1, MIFARE_BLOCK_SIZE);
uint8_t AC = ((sector_trailer[7] >> 5) & 0x04)
| ((sector_trailer[8] >> 2) & 0x02)
| ((sector_trailer[8] >> 7) & 0x01);
switch (action) {
case AC_KEYA_READ: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_KEYA_READ");
}
return false;
}
case AC_KEYA_WRITE: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_KEYA_WRITE");
}
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01))
|| (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03)));
}
case AC_KEYB_READ: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_KEYB_READ");
}
return (keytype == AUTHKEYA && (AC == 0x00 || AC == 0x02 || AC == 0x01));
}
case AC_KEYB_WRITE: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_KEYB_WRITE");
}
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01))
|| (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03)));
}
case AC_AC_READ: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_AC_READ");
}
return ((keytype == AUTHKEYA)
|| (keytype == AUTHKEYB && !(AC == 0x00 || AC == 0x02 || AC == 0x01)));
}
case AC_AC_WRITE: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsTrailerAccessAllowed: AC_AC_WRITE");
}
return ((keytype == AUTHKEYA && (AC == 0x01))
|| (keytype == AUTHKEYB && (AC == 0x03 || AC == 0x05)));
}
default:
default: {
return false;
}
}
}
static bool IsDataAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
uint8_t sector_trailer[16];
emlGetMem(sector_trailer, SectorTrailer(blockNo), 1);
uint8_t sector_trailer[MIFARE_BLOCK_SIZE] = {0};
emlGetMem_xt(sector_trailer, SectorTrailer(blockNo), 1, MIFARE_BLOCK_SIZE);
uint8_t sector_block;
if (blockNo <= MIFARE_2K_MAXBLOCK) {
@@ -120,54 +129,62 @@ static bool IsDataAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action
AC = ((sector_trailer[7] >> 2) & 0x04)
| ((sector_trailer[8] << 1) & 0x02)
| ((sector_trailer[8] >> 4) & 0x01);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed: case 0x00 - %02x", AC);
}
break;
}
case 0x01: {
AC = ((sector_trailer[7] >> 3) & 0x04)
| ((sector_trailer[8] >> 0) & 0x02)
| ((sector_trailer[8] >> 5) & 0x01);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed: case 0x01 - %02x", AC);
}
break;
}
case 0x02: {
AC = ((sector_trailer[7] >> 4) & 0x04)
| ((sector_trailer[8] >> 1) & 0x02)
| ((sector_trailer[8] >> 6) & 0x01);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed: case 0x02 - %02x", AC);
}
break;
}
default:
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed: Error");
}
return false;
}
switch (action) {
case AC_DATA_READ: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed - AC_DATA_READ: OK");
}
return ((keytype == AUTHKEYA && !(AC == 0x03 || AC == 0x05 || AC == 0x07))
|| (keytype == AUTHKEYB && !(AC == 0x07)));
}
case AC_DATA_WRITE: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed - AC_DATA_WRITE: OK");
}
return ((keytype == AUTHKEYA && (AC == 0x00))
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x04 || AC == 0x06 || AC == 0x03)));
}
case AC_DATA_INC: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("IsDataAccessAllowed - AC_DATA_INC: OK");
}
return ((keytype == AUTHKEYA && (AC == 0x00))
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06)));
}
case AC_DATA_DEC_TRANS_REST: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("AC_DATA_DEC_TRANS_REST: OK");
}
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x06 || AC == 0x01))
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06 || AC == 0x01)));
}
@@ -252,29 +269,33 @@ bool MifareSimInit(uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t sak, tag
// Length: 4,7,or 10 bytes
if (IS_FLAG_UID_IN_EMUL(flags)) {
if (uid == NULL) {
uid = uid_tmp;
}
// Get UID, SAK, ATQA from EMUL
uint8_t block0[16];
emlGet(block0, 0, 16);
uint8_t block0[MIFARE_BLOCK_SIZE];
emlGet(block0, 0, MIFARE_BLOCK_SIZE);
// Check for 4 bytes uid: bcc corrected and single size uid bits in ATQA
if ((block0[0] ^ block0[1] ^ block0[2] ^ block0[3]) == block0[4] && (block0[6] & 0xc0) == 0) {
FLAG_SET_UID_IN_DATA(flags, 4);
memcpy(uid, block0, 4);
rSAK[0] = block0[5];
memcpy(rATQA, &block0[6], sizeof(rATQA));
}
// Check for 7 bytes UID: double size uid bits in ATQA
else if ((block0[8] & 0xc0) == 0x40) {
} else if ((block0[8] & 0xc0) == 0x40) {
// Check for 7 bytes UID: double size uid bits in ATQA
FLAG_SET_UID_IN_DATA(flags, 7);
memcpy(uid, block0, 7);
rSAK[0] = block0[7];
memcpy(rATQA, &block0[8], sizeof(rATQA));
} else {
Dbprintf("ERROR: " _RED_("Invalid dump. UID/SAK/ATQA not found"));
return false;
}
} else {
if (uid == NULL) {
Dbprintf("ERROR: " _RED_("Missing UID"));
@@ -288,16 +309,19 @@ bool MifareSimInit(uint16_t flags, uint8_t *uid, uint16_t atqa, uint8_t sak, tag
memcpy(rATQA, rATQA_Mini, sizeof(rATQA));
rSAK[0] = rSAK_Mini;
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare Mini ATQA/SAK");
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_1K_MAX_BYTES)) {
memcpy(rATQA, rATQA_1k, sizeof(rATQA));
rSAK[0] = rSAK_1k;
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 1K ATQA/SAK");
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_2K_MAX_BYTES)) {
memcpy(rATQA, rATQA_2k, sizeof(rATQA));
rSAK[0] = rSAK_2k;
*rats = rRATS;
*rats_len = sizeof(rRATS);
if (g_dbglevel > DBG_NONE) Dbprintf("Enforcing Mifare 2K ATQA/SAK with RATS support");
} else if (IS_FLAG_MF_SIZE(flags, MIFARE_4K_MAX_BYTES)) {
memcpy(rATQA, rATQA_4k, sizeof(rATQA));
rSAK[0] = rSAK_4k;
@@ -825,8 +849,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
// if key not known and FLAG_NESTED_AUTH_ATTACK and we have nt/nt_enc/parity, send recorded nt_enc and parity
if ((flags & FLAG_NESTED_AUTH_ATTACK) == FLAG_NESTED_AUTH_ATTACK) {
if (emlGetKey(cardAUTHSC, cardAUTHKEY) == 0) {
uint8_t buf[16] = {0};
emlGetMem(buf, (CARD_MEMORY_RF08S_OFFSET / MIFARE_BLOCK_SIZE) + cardAUTHSC, 1);
uint8_t buf[MIFARE_BLOCK_SIZE] = {0};
emlGetMem_xt(buf, (CARD_MEMORY_RF08S_OFFSET / MIFARE_BLOCK_SIZE) + cardAUTHSC, 1, MIFARE_BLOCK_SIZE);
if (buf[(cardAUTHKEY * 8) + 3] == 0xAA) { // extra check to tell we have nt/nt_enc/par_err
running_nested_auth_attack = true;
// nt
@@ -955,7 +979,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
// first block
if (blockNo == 4) {
p_em += blockNo * 16;
p_em += (blockNo * MIFARE_BLOCK_SIZE);
// TLV in NDEF, flip length between
// 4 | 03 21 D1 02 1C 53 70 91 01 09 54 02 65 6E 4C 69
// 0xFF means long length
@@ -970,7 +994,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
}
}
emlGetMem(response, blockNo, 1);
emlGetMem_xt(response, blockNo, 1, MIFARE_BLOCK_SIZE);
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK - ISO14443A_CMD_READBLOCK] Data Block[%d]: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", blockNo,
@@ -1010,11 +1034,11 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
}
} else {
if (IsAccessAllowed(blockNo, cardAUTHKEY, AC_DATA_READ) == false) {
memset(response, 0x00, 16); // datablock cannot be read
memset(response, 0x00, MIFARE_BLOCK_SIZE); // datablock cannot be read
if (g_dbglevel >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsAccessAllowed] Data block %d (0x%02x) cannot be read", blockNo, blockNo);
}
}
AddCrc14A(response, 16);
AddCrc14A(response, MIFARE_BLOCK_SIZE);
mf_crypto1_encrypt(pcs, response, MAX_MIFARE_FRAME_SIZE, response_par);
EmSendCmdPar(response, MAX_MIFARE_FRAME_SIZE, response_par);
FpgaDisableTracing();
@@ -1109,7 +1133,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
// case MFEMUL_WORK => CMD RATS
if (receivedCmd_len == 4 && receivedCmd_dec[0] == ISO14443A_CMD_RATS && (receivedCmd_dec[1] & 0xF0) <= 0x80 && (receivedCmd_dec[1] & 0x0F) <= 0x0e) {
if (rats && rats_len) {
if (encrypted_data) {
memcpy(response, rats, rats_len);
mf_crypto1_encrypt(pcs, response, rats_len, response_par);
@@ -1117,46 +1143,58 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
} else {
EmSendCmd(rats, rats_len);
}
FpgaDisableTracing();
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK] RCV RATS => ACK");
}
} else {
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
FpgaDisableTracing();
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK] RCV RATS => NACK");
}
}
break;
}
// case MFEMUL_WORK => ISO14443A_CMD_NXP_DESELECT
if (receivedCmd_len == 3 && receivedCmd_dec[0] == ISO14443A_CMD_NXP_DESELECT) {
if (rats && rats_len) {
// response back NXP_DESELECT
if (encrypted_data) {
memcpy(response, receivedCmd_dec, receivedCmd_len);
mf_crypto1_encrypt(pcs, response, receivedCmd_len, response_par);
EmSendCmdPar(response, receivedCmd_len, response_par);
} else
} else {
EmSendCmd(receivedCmd_dec, receivedCmd_len);
}
FpgaDisableTracing();
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK");
}
} else {
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
FpgaDisableTracing();
cardSTATE_TO_IDLE();
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK");
}
}
break;
}
// case MFEMUL_WORK => command not allowed
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("Received command not allowed, nacking");
}
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
FpgaDisableTracing();
break;
@@ -1164,14 +1202,16 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
// AUTH1
case MFEMUL_AUTH1: {
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("[MFEMUL_AUTH1] Enter case");
}
if (receivedCmd_len != 8) {
cardSTATE_TO_IDLE();
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len);
}
break;
}
@@ -1191,6 +1231,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
ar_nr_resp[0].state = NESTED;
finished = true;
}
if ((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) {
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
@@ -1267,12 +1308,16 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *uid, uint16_t
// WRITE BL2
case MFEMUL_WRITEBL2: {
if (receivedCmd_len == MAX_MIFARE_FRAME_SIZE) {
mf_crypto1_decryptEx(pcs, receivedCmd, receivedCmd_len, receivedCmd_dec);
if (CheckCrc14A(receivedCmd_dec, receivedCmd_len)) {
if (IsSectorTrailer(cardWRBL)) {
emlGetMem(response, cardWRBL, 1);
emlGetMem_xt(response, cardWRBL, 1, MIFARE_BLOCK_SIZE);
if (IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_KEYA_WRITE) == false) {
memcpy(receivedCmd_dec, response, 6); // don't change KeyA

Some files were not shown because too many files have changed in this diff Show More