NEW: HF MFU SETPWD - set password to a Ultralight C tag.

NEW: HF MFU SETUID - set UID to a magic UL / UL-C tag.   *not implemented*
CHG: minor alignment for "Hf list" output.
CHG: removed unneeded function parameters to the ultralight commands
CHG: the const MAX_MIFARE_FRAME_SIZE is changed to MAX_FRAME_SIZE in the ultralight commands since the UL-Ev1 can have bigger frames than 18bytes.
CHG: adding DES support for the Ultralight-c read commands on deviceside.
This commit is contained in:
iceman1001 2015-03-30 16:24:03 +02:00
parent 4076250660
commit aa60d1560e
11 changed files with 507 additions and 282 deletions

View file

@ -12,18 +12,17 @@
#include "../common/usb_cdc.h"
#include "../common/cmd.h"
#include "../include/proxmark3.h"
#include "../include/hitag2.h"
#include "apps.h"
#include "util.h"
#include "printf.h"
#include "string.h"
#include <stdarg.h>
#include "legicrf.h"
#include "../include/hitag2.h"
#include "lfsampling.h"
#include "BigBuf.h"
#ifdef WITH_LCD
#include "LCD.h"
#endif
@ -826,7 +825,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
case CMD_MIFAREU_READBL:
MifareUReadBlock(c->arg[0],c->d.asBytes);
MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
break;
case CMD_MIFAREUC_AUTH1:
MifareUC_Auth1(c->arg[0],c->d.asBytes);
@ -836,10 +835,16 @@ void UsbPacketReceived(uint8_t *packet, int len)
break;
case CMD_MIFAREU_READCARD:
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
break;
break;
case CMD_MIFAREUC_READCARD:
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
break;
case CMD_MIFAREUC_SETPWD:
MifareUSetPwd(c->arg[0], c->d.asBytes);
break;
//case CMD_MIFAREU_SETUID:
//MifareUSetUid(c->arg[0], c->d.asBytes);
//break;
case CMD_MIFARE_READSC:
MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
@ -848,10 +853,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
break;
case CMD_MIFAREU_WRITEBL_COMPAT:
MifareUWriteBlock(c->arg[0], c->d.asBytes);
break;
break;
case CMD_MIFAREU_WRITEBL:
MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
break;
MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
break;
case CMD_MIFARE_NESTED:
MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
@ -895,6 +900,25 @@ void UsbPacketReceived(uint8_t *packet, int len)
SniffMifare(c->arg[0]);
break;
//mifare desfire
case CMD_MIFARE_DESFIRE_READBL: break;
case CMD_MIFARE_DESFIRE_WRITEBL: break;
case CMD_MIFARE_DESFIRE_AUTH1:
MifareDES_Auth1(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
case CMD_MIFARE_DESFIRE_AUTH2:
//MifareDES_Auth2(c->arg[0],c->d.asBytes);
break;
case CMD_MIFARE_DES_READER:
//readermifaredes(c->arg[0], c->arg[1], c->d.asBytes);
break;
case CMD_MIFARE_DESFIRE_INFO:
MifareDesfireGetInformation();
break;
case CMD_MIFARE_DESFIRE:
MifareSendCommand(c->arg[0], c->arg[1], c->d.asBytes);
break;
#endif
#ifdef WITH_ICLASS

View file

@ -22,8 +22,6 @@
#include "BigBuf.h"
#include "../include/hitag2.h"
#include "../include/mifare.h"
//#include <openssl/des.h>
//#include <openssl/aes.h>
//#include "des.h"
//#include "aes.h"
#include "desfire.h"
@ -196,6 +194,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); // Work with "magic Chinese" card
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareCIdent(); // is "magic chinese" card?
void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
//desfire
void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain);

View file

@ -378,6 +378,44 @@ void tdes_dec(void* out, void* in, const uint8_t* key){
des_dec(out, out, (uint8_t*)key + 0);
}
void tdes_2key_enc(void* out, const void* in, size_t length, const void* key){
if( length % 8 ) return;
uint8_t* tin = (uint8_t*) in;
uint8_t* tout = (uint8_t*) out;
while( length > 0 )
{
des_enc(tout, tin, (uint8_t*)key + 0);
des_dec(tout, tout, (uint8_t*)key + 8);
des_enc(tout, tout, (uint8_t*)key + 0);
tin += 8;
tout += 8;
length -= 8;
}
}
void tdes_2key_dec(void* out, const void* in, size_t length, const void* key){
if( length % 8 ) return;
uint8_t* tin = (uint8_t*) in;
uint8_t* tout = (uint8_t*) out;
while( length > 0 )
{
des_dec(tout, tin, (uint8_t*)key + 0);
des_enc(tout, tout, (uint8_t*)key + 8);
des_dec(tout, tout, (uint8_t*)key + 0);
tin += 8;
tout += 8;
length -= 8;
}
}
/******************************************************************************/

View file

@ -96,6 +96,9 @@ void tdes_enc(void* out, const void* in, const void* key);
* \param key pointer to the key (192 bit = 24 byte)
*/
void tdes_dec(void* out, const void* in, const void* key);
void tdes_2key_enc(void* out, const void* in, size_t length, const void* key);
void tdes_2key_dec(void* out, const void* in, size_t length, const void* key);
#endif /*DES_H_*/

View file

@ -90,64 +90,50 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){
byte_t isOK = 0;
byte_t dataoutbuf[16] = {0x00};
uint8_t uid[10] = {0x00};
uint32_t cuid;
uint32_t cuid = 0x00;
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Can't select card");
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
OnError(0);
return;
};
if(mifare_ultra_auth1(cuid, dataoutbuf)){
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Authentication part1: Fail.");
if(mifare_ultra_auth1(dataoutbuf)){
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication part1: Fail.");
OnError(1);
return;
}
isOK = 1;
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
DbpString("AUTH 1 FINISHED");
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");
cmd_send(CMD_ACK,isOK,cuid,0,dataoutbuf,11);
cmd_send(CMD_ACK,1,cuid,0,dataoutbuf,11);
LEDsoff();
}
void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){
uint32_t cuid = arg0;
uint8_t key[16] = {0x00};
byte_t isOK = 0;
byte_t dataoutbuf[16] = {0x00};
memcpy(key, datain, 16);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
if(mifare_ultra_auth2(cuid, key, dataoutbuf)){
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Authentication part2: Fail...");
if(mifare_ultra_auth2(key, dataoutbuf)){
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication part2: Fail...");
OnError(1);
return;
}
isOK = 1;
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
DbpString("AUTH 2 FINISHED");
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 2 FINISHED");
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,11);
cmd_send(CMD_ACK,1,0,0,dataoutbuf,11);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
@ -157,62 +143,55 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
uint8_t blockNo = arg0;
byte_t dataout[16] = {0x00};
uint8_t uid[10] = {0x00};
uint8_t key[8] = {0x00};
uint32_t cuid;
bool usePwd = false;
uint8_t key[16] = {0x00};
bool usePwd = (arg1 == 1);
usePwd = (arg1 == 1);
// use password
if ( usePwd )
memcpy(key, datain, 8);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
int len = iso14443a_select_card(uid, NULL, &cuid);
int len = iso14443a_select_card(uid, NULL, NULL);
if(!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
OnError(1);
return;
};
}
// authenticate here.
if ( usePwd ) {
uint8_t a[8] = { 0x01 };
uint8_t b[8] = { 0x00 };
uint8_t enc_b[8] = { 0x00 };
uint8_t ab[16] = { 0x00 };
uint8_t transKey[8] = { 0x00 };
memcpy(key, datain, 16);
// Dbprintf("KEY: %02x %02x %02x %02x %02x %02x %02x %02x", key[0],key[1],key[2],key[3],key[4],key[5],key[6],key[7] );
// Dbprintf("KEY: %02x %02x %02x %02x %02x %02x %02x %02x", key[8],key[9],key[10],key[11],key[12],key[13],key[14],key[15] );
uint8_t a[8] = {1,1,1,1,1,1,1,1 };
uint8_t b[8] = {0x00};
uint8_t enc_b[8] = {0x00};
uint8_t ab[16] = {0x00};
uint8_t enc_ab[16] = {0x00};
uint8_t enc_key[8] = {0x00};
uint16_t len;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);
if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
OnError(1);
return;
if (len != 11) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
OnError(1);
return;
}
// memcpy(dataout, receivedAnswer, 11);
// tag nonce.
memcpy(enc_b,receivedAnswer+1,8);
// decrypt nonce.
des_dec(enc_b, b, key );
tdes_2key_dec(b, enc_b, 8, key );
Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x", enc_b[0],enc_b[1],enc_b[2],enc_b[3],enc_b[4],enc_b[5],enc_b[6],enc_b[7] );
Dbprintf(" B: %02x %02x %02x %02x %02x %02x %02x %02x", b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7] );
rol(b,8);
memcpy(ab ,a,8);
@ -222,44 +201,51 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] );
// encrypt
des_enc(ab, ab, key);
tdes_2key_enc(enc_ab, ab, 16, key);
Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] );
Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] );
Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", enc_ab[0],enc_ab[1],enc_ab[2],enc_ab[3],enc_ab[4],enc_ab[5],enc_ab[6],enc_ab[7] );
Dbprintf("e_enc_ab: %02x %02x %02x %02x %02x %02x %02x %02x", enc_ab[8],enc_ab[9],enc_ab[10],enc_ab[11],enc_ab[12],enc_ab[13],enc_ab[14],enc_ab[15] );
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, ab, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, enc_ab, receivedAnswer, receivedAnswerPar, NULL);
if (len != 11) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
OnError(1);
return;
}
//
memcpy(transKey, receivedAnswer+1, 8);
Dbprintf("TRANSACTIONKEY: %02x %02x %02x %02x %02x %02x %02x %02x", transKey[0],transKey[1],transKey[2],transKey[3],
transKey[4],transKey[5],transKey[6],transKey[7] );
// the tags' encryption of our nonce, A.
memcpy(enc_key, receivedAnswer+1, 8);
// clear B.
memset(b, 0x00, 8);
// decrypt
tdes_2key_dec(b, enc_key, 8, key );
if ( memcmp(a, b, 8) == 0 )
Dbprintf("Verified key");
else
Dbprintf("failed authentication");
Dbprintf("a: %02x %02x %02x %02x %02x %02x %02x %02x", a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7] );
Dbprintf("b: %02x %02x %02x %02x %02x %02x %02x %02x", b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7] );
}
len = mifare_ultra_readblock(cuid, blockNo, dataout);
if(len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
if( mifare_ultra_readblock(blockNo, dataout) ) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
OnError(2);
return;
};
}
len = mifare_ultra_halt(cuid);
if(len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
if( mifare_ultra_halt() ) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
OnError(3);
return;
};
}
cmd_send(CMD_ACK,1,0,0,dataout,16);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
//-----------------------------------------------------------------------------
// Select, Authenticate, Read a MIFARE tag.
// read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes)
@ -333,60 +319,47 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
// params
uint8_t sectorNo = arg0;
int Pages = arg1;
int count_Pages = 0;
int countpages = 0;
byte_t dataout[176] = {0x00};;
uint8_t uid[10] = {0x00};
uint32_t cuid;
uint32_t cuid = 0x00;
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
if (MF_DBGLEVEL >= MF_DBG_ALL)
Dbprintf("Pages %d",Pages);
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
int len = iso14443a_select_card(uid, NULL, &cuid);
int len = iso14443a_select_card(NULL, NULL, &cuid);
if (!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Can't select card (RC:%d)",len);
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);
OnError(1);
return;
}
for (int i = 0; i < Pages; i++){
len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i);
len = mifare_ultra_readblock(sectorNo * 4 + i, dataout + 4 * i);
if (len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Read block %d error",i);
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block %d error",i);
OnError(2);
return;
} else {
count_Pages++;
countpages++;
}
}
len = mifare_ultra_halt(cuid);
len = mifare_ultra_halt();
if (len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Halt error");
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
OnError(3);
return;
}
if (MF_DBGLEVEL >= MF_DBG_ALL) {
Dbprintf("Pages read %d", count_Pages);
}
if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Pages read %d", countpages);
len = 16*4; //64 bytes
// Read a UL-C
if (Pages == 44 && count_Pages > 16)
if (Pages == 44 && countpages > 16)
len = 176;
cmd_send(CMD_ACK, 1, 0, 0, dataout, len);
@ -469,94 +442,144 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
uint8_t blockNo = arg0;
byte_t blockdata[16] = {0x00};
memcpy(blockdata, datain,16);
memcpy(blockdata, datain, 16);
// variables
byte_t isOK = 0;
uint8_t uid[10] = {0x00};
uint32_t cuid;
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
if(!iso14443a_select_card(uid, NULL, NULL)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
OnError(0);
return;
};
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_ultra_writeblock(blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(0);
return; };
if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
break;
};
if(mifare_ultra_halt()) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
OnError(0);
return;
};
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
cmd_send(CMD_ACK,isOK,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
cmd_send(CMD_ACK,1,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
byte_t blockdata[4] = {0x00};
memcpy(blockdata, datain,4);
// variables
byte_t isOK = 0;
uint8_t uid[10] = {0x00};
uint32_t cuid;
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
if(!iso14443a_select_card(uid, NULL, NULL)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
OnError(0);
return;
};
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
if(mifare_ultra_special_writeblock(blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(0);
return;
};
if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
break;
};
if(mifare_ultra_halt()) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
OnError(0);
return;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
isOK = 1;
break;
}
cmd_send(CMD_ACK,1,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
uint8_t pwd[16] = {0x00};
byte_t blockdata[4] = {0x00};
memcpy(pwd, datain, 16);
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
cmd_send(CMD_ACK,isOK,0,0,0,0);
if(!iso14443a_select_card(NULL, NULL, NULL)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
OnError(0);
return;
};
blockdata[0] = pwd[7];
blockdata[1] = pwd[6];
blockdata[2] = pwd[5];
blockdata[3] = pwd[4];
if(mifare_ultra_special_writeblock( 44, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(44);
return;
};
blockdata[0] = pwd[3];
blockdata[1] = pwd[2];
blockdata[2] = pwd[1];
blockdata[3] = pwd[0];
if(mifare_ultra_special_writeblock( 45, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(45);
return;
};
blockdata[0] = pwd[15];
blockdata[1] = pwd[14];
blockdata[2] = pwd[13];
blockdata[3] = pwd[12];
if(mifare_ultra_special_writeblock( 46, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(46);
return;
};
blockdata[0] = pwd[11];
blockdata[1] = pwd[10];
blockdata[2] = pwd[9];
blockdata[3] = pwd[8];
if(mifare_ultra_special_writeblock( 47, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(47);
return;
};
if(mifare_ultra_halt()) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
OnError(0);
return;
};
cmd_send(CMD_ACK,1,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
@ -1203,28 +1226,25 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
byte_t dataout[11] = {0x00};
uint8_t uid[10] = {0x00};
uint32_t cuid;
uint32_t cuid = 0x00;
clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
int len = iso14443a_select_card(uid, NULL, &cuid);
if(!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Can't select card");
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
OnError(1);
return;
};
if(mifare_desfire_des_auth1(cuid, dataout)){
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Authentication part1: Fail.");
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication part1: Fail.");
OnError(4);
return;
}
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");
cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));
}
@ -1232,22 +1252,20 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
uint32_t cuid = arg0;
uint8_t key[16] = {0x00};
byte_t isOK = 0;
byte_t dataout[12] = {0x00};
byte_t isOK = 0;
memcpy(key, datain, 16);
isOK = mifare_desfire_des_auth2(cuid, key, dataout);
if( isOK) {
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
Dbprintf("Authentication part2: Failed");
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication part2: Failed");
OnError(4);
return;
}
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)
DbpString("AUTH 2 FINISHED");
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 2 FINISHED");
cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);

View file

@ -288,20 +288,17 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
}
// mifare ultralight commands
int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
int mifare_ultra_auth1(uint8_t *blockData){
uint16_t len;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);
if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
if (len != 11) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
}
if (len != 11)
return 1;
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
@ -313,20 +310,17 @@ int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
return 0;
}
int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
int mifare_ultra_auth2(uint8_t *key, uint8_t *blockData){
uint16_t len;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
if (len != 11) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
}
if (len != 11)
return 1;
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
@ -338,32 +332,27 @@ int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
return 0;
}
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)
{
uint16_t len;
uint8_t bt[2];
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
}
if (len != 18) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd Error: card timeout. len: %x", len);
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: card timeout. len: %x", len);
return 2;
}
memcpy(bt, receivedAnswer + 16, 2);
AppendCrc14443a(receivedAnswer, 16);
if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Cmd CRC response error.");
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd CRC response error.");
return 3;
}
@ -419,13 +408,13 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
return 0;
}
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData)
{
uint16_t len;
uint8_t par[3] = {0}; // enough for 18 parity bits
uint8_t d_block[18] = {0x00};
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
// command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
@ -451,7 +440,7 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
return 0;
}
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData)
{
uint16_t len;
uint8_t d_block[8] = {0x00};
@ -489,7 +478,7 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
return 0;
}
int mifare_ultra_halt(uint32_t uid)
int mifare_ultra_halt()
{
uint16_t len;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
@ -654,8 +643,8 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){
int len;
// load key, keynumber
uint8_t data[2]={0x0a, 0x00};
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL);
if (len == 1) {
@ -684,8 +673,8 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
data[0] = 0xAF;
memcpy(data+1,key,16);
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
uint8_t receivedAnswer[MAX_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL);

View file

@ -62,14 +62,14 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested);
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_auth1(uint32_t cuid, uint8_t *blockData);
int mifare_ultra_auth2(uint32_t cuid, uint8_t *key, uint8_t *blockData);
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_auth1(uint8_t *blockData);
int mifare_ultra_auth2(uint8_t *key, uint8_t *blockData);
int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData);
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_special_writeblock(uint8_t blockNo, uint8_t *blockData);
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid);
int mifare_ultra_halt(uint32_t uid);
int mifare_ultra_halt();
// desfire
int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing);

View file

@ -604,8 +604,8 @@ int CmdHFList(const char *Cmd)
PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)");
PrintAndLog("iClass - Timings are not as accurate");
PrintAndLog("");
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |");
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|");
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |");
PrintAndLog("------------|------------|-----|-----------------------------------------------------------------|-----|--------------------|");
while(tracepos < traceLen)
{

View file

@ -12,12 +12,10 @@
#include "cmdhfmf.h"
#include "cmdhf14a.h"
#define MAX_ULTRA_BLOCKS 0x0f
#define MAX_ULTRAC_BLOCKS 0x2f
//#define MAX_ULTRAC_BLOCKS 0x2c
static int CmdHelp(const char *Cmd);
int CmdHF14AMfUInfo(const char *Cmd){
@ -76,8 +74,11 @@ int CmdHF14AMfUInfo(const char *Cmd){
int len = CmdHF14AMfucAuth("K 0");
// PrintAndLog("CODE: %d",len);
// Fix reading UL-C 's password higher blocks.
PrintAndLog("Seems to be a Ultralight %s", (len==0) ? "-C" :"");
return 0;
}
@ -154,9 +155,9 @@ int CmdHF14AMfUWrBl(const char *Cmd){
// Mifare Ultralight Read Single Block
//
int CmdHF14AMfURdBl(const char *Cmd){
uint8_t blockNo = -1;
UsbCommand resp;
uint8_t blockNo = -1;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
@ -168,26 +169,27 @@ int CmdHF14AMfURdBl(const char *Cmd){
blockNo = param_get8(Cmd, 0);
if (blockNo > MAX_ULTRA_BLOCKS){
PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight");
return 1;
}
PrintAndLog("--block no:0x%02X (%d)", (int)blockNo, blockNo);
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
uint8_t * data = resp.d.asBytes;
PrintAndLog("isOk: %02x", isOK);
if (isOK)
PrintAndLog("Data: %s", sprint_hex(data, 4));
uint8_t isOK = resp.arg[0] & 0xff;
if (isOK) {
uint8_t *data = resp.d.asBytes;
PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4));
}
else {
PrintAndLog("Failed reading block: (%02x)", isOK);
}
} else {
PrintAndLog("Command execute timeout");
PrintAndLog("Command execute time-out");
}
return 0;
}
@ -223,7 +225,7 @@ int CmdHF14AMfUDump(const char *Cmd){
PrintAndLog("Reads all pages from Mifare Ultralight or Ultralight-C tag.");
PrintAndLog("It saves binary dump into the file `filename.bin` or `cardUID.bin`");
PrintAndLog("Usage: hf mfu dump <c> <filename w/o .bin>");
PrintAndLog(" <c> optional cardtype c == Ultralight-C, if not defaults to Ultralight");
PrintAndLog(" <c> optional cardtype c == Ultralight-C, Defaults to Ultralight");
PrintAndLog(" sample: hf mfu dump");
PrintAndLog(" : hf mfu dump myfile");
PrintAndLog(" : hf mfu dump c myfile");
@ -247,7 +249,7 @@ int CmdHF14AMfUDump(const char *Cmd){
}
data = resp.d.asBytes;
} else {
PrintAndLog("Command execute timeout");
PrintAndLog("Command execute time-out");
return 0;
}
@ -375,12 +377,14 @@ void rol (uint8_t *data, const size_t len){
//
int CmdHF14AMfucAuth(const char *Cmd){
uint8_t default_keys[5][16] = {
uint8_t default_keys[7][16] = {
{ 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
{ 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 } // all ones
{ 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },// all ones
{ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF },// all FF
{ 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF } // 11 22 33
};
char cmdp = param_getchar(Cmd, 0);
@ -390,7 +394,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
//Change key to user defined one
if (cmdp == 'k' || cmdp == 'K'){
keyNo = param_get8(Cmd, 1);
if(keyNo > 4) errors = true;
if(keyNo > 6) errors = true;
}
if (cmdp == 'h' || cmdp == 'H') {
@ -400,11 +404,13 @@ int CmdHF14AMfucAuth(const char *Cmd){
if (errors) {
PrintAndLog("Usage: hf mfu cauth k <key number>");
PrintAndLog(" 0 (default): 3DES standard key");
PrintAndLog(" 1 : all zeros key");
PrintAndLog(" 1 : all 0x00 key");
PrintAndLog(" 2 : 0x00-0x0F key");
PrintAndLog(" 3 : nfc key");
PrintAndLog(" 4 : all ones key");
PrintAndLog(" sample : hf mfu cauth k");
PrintAndLog(" 4 : all 0x01 key");
PrintAndLog(" 5 : all 0xff key");
PrintAndLog(" 6 : 0x00-0xFF key");
PrintAndLog("\n sample : hf mfu cauth k");
PrintAndLog(" : hf mfu cauth k 3");
return 0;
}
@ -432,7 +438,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
memcpy(enc_random_b,data+1,8);
} else {
PrintAndLog("Auth failed");
return 2; // auth failed.
return 2;
}
} else {
PrintAndLog("Command execute timeout");
@ -441,7 +447,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
uint8_t iv[8] = { 0 };
PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
PrintAndLog(" enc(RndB):%s",sprint_hex(enc_random_b, 8));
des3_set2key_dec(&ctx, key);
@ -459,7 +465,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
memcpy(random_a_and_b ,random_a,8);
memcpy(random_a_and_b+8,random_b,8);
PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
PrintAndLog(" A+B:%s",sprint_hex(random_a_and_b, 16));
des3_set2key_enc(&ctx, key);
@ -471,7 +477,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
, random_a_and_b // unsigned char *output
);
PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
PrintAndLog("enc(A+B):%s",sprint_hex(random_a_and_b, 16));
//Auth2
UsbCommand d = {CMD_MIFAREUC_AUTH2, {cuid}};
@ -489,7 +495,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
uint8_t foo[8] = { 0 };
uint8_t bar[8] = { 0 };
memcpy(foo, data2+1, 8);
des3_set2key_enc(&ctx, key);
des3_set2key_dec(&ctx, key);
des3_crypt_cbc(&ctx // des3_context *ctx
, DES_DECRYPT // int mode
@ -499,7 +505,7 @@ int CmdHF14AMfucAuth(const char *Cmd){
, bar // unsigned char *output
);
PrintAndLog("BAR:%s",sprint_hex(bar, 8));
PrintAndLog("--> : %s : <-- Should be equal to our RndA",sprint_hex(bar, 8));
} else {
@ -613,6 +619,7 @@ int CmdTestDES(const char * cmd)
//
int CmdHF14AMfUCRdBl(const char *Cmd)
{
UsbCommand resp;
bool hasPwd = FALSE;
uint8_t blockNo = -1;
unsigned char key[16];
@ -622,7 +629,7 @@ int CmdHF14AMfUCRdBl(const char *Cmd)
PrintAndLog("Usage: hf mfu crdbl <block number> <password>");
PrintAndLog("");
PrintAndLog("sample: hf mfu crdbl 0");
PrintAndLog(" hf mfu crdbl 0 1122334455667788");
PrintAndLog(" hf mfu crdbl 0 112233445566778899AABBCCDDEEFF");
return 0;
}
@ -633,24 +640,19 @@ int CmdHF14AMfUCRdBl(const char *Cmd)
}
if (blockNo > MAX_ULTRAC_BLOCKS ){
PrintAndLog("Error: Maximum number of readable blocks is 47 for Ultralight-C Cards!");
PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C");
return 1;
}
// key
if ( strlen(Cmd) > 3){
if (param_gethex(Cmd, 1, key, 16)) {
PrintAndLog("Key must include %d HEX symbols", 16);
if (param_gethex(Cmd, 1, key, 32)) {
PrintAndLog("Key must include %d HEX symbols", 32);
return 1;
} else {
hasPwd = TRUE;
}
}
if ( hasPwd )
PrintAndLog("--block no: 0x%02X (%d) PWD: %s", (int)blockNo, blockNo, key);
else
PrintAndLog("--block no: 0x%02X (%d)", (int)blockNo, blockNo);
}
//Read Block
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
@ -659,17 +661,18 @@ int CmdHF14AMfUCRdBl(const char *Cmd)
memcpy(c.d.asBytes,key,16);
}
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
uint8_t *data = resp.d.asBytes;
PrintAndLog("isOk: %02x", isOK);
if (isOK)
PrintAndLog("Data: %s", sprint_hex(data, 4));
if (isOK) {
uint8_t *data = resp.d.asBytes;
PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4));
}
else {
PrintAndLog("Failed reading block: (%02x)", isOK);
}
} else {
PrintAndLog("Command execute timeout");
PrintAndLog("Command execute time-out");
}
return 0;
}
@ -744,6 +747,149 @@ int CmdHF14AMfUCWrBl(const char *Cmd){
return 0;
}
//
// Mifare Ultralight C - Set password
//
int CmdHF14AMfucSetPwd(const char *Cmd){
uint8_t pwd[16] = {0x00};
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu setpwd <password (32 hex symbols)>");
PrintAndLog(" [password] - (32 hex symbols)");
PrintAndLog("");
PrintAndLog("sample: hf mfu setpwd 000102030405060708090a0b0c0d0e0f");
PrintAndLog("");
return 0;
}
if (param_gethex(Cmd, 0, pwd, 32)) {
PrintAndLog("Password must include 32 HEX symbols");
return 1;
}
UsbCommand c = {CMD_MIFAREUC_SETPWD};
memcpy( c.d.asBytes, pwd, 16);
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
if ( (resp.arg[0] & 0xff) == 1)
PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd,16));
else{
PrintAndLog("Failed writing at block %d", resp.arg[1] & 0xff);
return 1;
}
}
else {
PrintAndLog("command execution time out");
return 1;
}
return 0;
}
//
// Mifare Ultraligh - Set UID
//
int CmdHF14AMfucSetUid(const char *Cmd){
uint8_t uid[7] = {0x00};
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu setuid <uid (14 hex symbols)>");
PrintAndLog(" [uid] - (14 hex symbols)");
PrintAndLog("");
PrintAndLog("sample: hf mfu setuid 11223344556677");
PrintAndLog("");
return 0;
}
if (param_gethex(Cmd, 0, uid, 14)) {
PrintAndLog("Password must include 14 HEX symbols");
return 1;
}
UsbCommand c = {CMD_MIFAREU_SETUID};
memcpy( c.d.asBytes, uid, 14);
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
if ( (resp.arg[0] & 0xff) == 1)
PrintAndLog("New UID: %s", sprint_hex(uid,14));
else{
PrintAndLog("Failed writing new uid");
return 1;
}
}
else {
PrintAndLog("command execution time out");
return 1;
}
return 0;
}
int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
uint8_t iv[8] = { 0x00 };
uint8_t block = 0x07;
uint8_t uid[] = { 0xF4,0xEA, 0x54, 0x8E };
uint8_t mifarekey[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
uint8_t masterkey[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
uint8_t mix[8] = { 0x00 };
uint8_t divkey[8] = { 0x00 };
memcpy(mix, mifarekey, 4);
mix[4] = mifarekey[4] ^ uid[0];
mix[5] = mifarekey[5] ^ uid[1];
mix[6] = block ^ uid[2];
mix[7] = uid[3];
des3_context ctx = { 0x00 };
des3_set2key_enc(&ctx, masterkey);
des3_crypt_cbc(&ctx // des3_context *ctx
, DES_ENCRYPT // int mode
, sizeof(mix) // size_t length
, iv // unsigned char iv[8]
, mix // const unsigned char *input
, divkey // unsigned char *output
);
PrintAndLog("3DES version");
PrintAndLog("Masterkey :\t %s", sprint_hex(masterkey,sizeof(masterkey)));
PrintAndLog("UID :\t %s", sprint_hex(uid, sizeof(uid)));
PrintAndLog("Sector :\t %0d", block);
PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekey, sizeof(mifarekey)));
PrintAndLog("Message :\t %s", sprint_hex(mix, sizeof(mix)));
PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
return 0;
}
// uint8_t * diversify_key(uint8_t * key){
// for(int i=0; i<16; i++){
// if(i<=6) key[i]^=cuid[i];
// if(i>6) key[i]^=cuid[i%7];
// }
// return key;
// }
// static void GenerateUIDe( uint8_t *uid, uint8_t len){
// for (int i=0; i<len; ++i){
// }
// return;
// }
//------------------------------------
// Menu Stuff
//------------------------------------
@ -753,12 +899,15 @@ static command_t CommandTable[] =
{"dbg", CmdHF14AMfDbg, 0,"Set default debug mode"},
{"info", CmdHF14AMfUInfo, 0,"Taginfo"},
{"dump", CmdHF14AMfUDump, 0,"Dump MIFARE Ultralight / Ultralight-C tag to binary file"},
{"rdbl", CmdHF14AMfURdBl, 0,"Read block - MIFARE Ultralight"},
{"rdbl", CmdHF14AMfURdBl, 0,"Read block - MIFARE Ultralight"},
{"wrbl", CmdHF14AMfUWrBl, 0,"Write block - MIFARE Ultralight"},
{"crdbl", CmdHF14AMfUCRdBl, 0,"Read block - MIFARE Ultralight C"},
{"cwrbl", CmdHF14AMfUCWrBl, 0,"Write MIFARE Ultralight C block"},
{"cauth", CmdHF14AMfucAuth, 0,"try a Ultralight C Authentication"},
{"crdbl", CmdHF14AMfUCRdBl, 0,"Read block - MIFARE Ultralight C"},
{"cwrbl", CmdHF14AMfUCWrBl, 0,"Write block - MIFARE Ultralight C"},
{"cauth", CmdHF14AMfucAuth, 0,"Ultralight C Authentication"},
//{"testdes", CmdTestDES , 1, "Test DES"},
{"setpwd", CmdHF14AMfucSetPwd , 1, "Set 3des password [Ultralight-C only]"},
{"setuid", CmdHF14AMfucSetUid , 1, "Set UID"},
{"gen", CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"},
{NULL, NULL, 0, NULL}
};

View file

@ -138,6 +138,8 @@ local _commands = {
CMD_MIFAREUC_AUTH1 = 0x0724,
CMD_MIFAREUC_AUTH2 = 0x0725,
CMD_MIFAREUC_READCARD = 0x0726,
CMD_MIFAREUC_SETPWD = 0x0727,
CMD_MIFAREU_SETUID = 0x0728,
--// mifare desfire
CMD_MIFARE_DESFIRE_READBL = 0x0728,

View file

@ -176,10 +176,13 @@ typedef struct{
#define CMD_MIFARE_CHKKEYS 0x0623
#define CMD_MIFARE_SNIFFER 0x0630
//ultralightC
#define CMD_MIFAREUC_AUTH1 0x0724
#define CMD_MIFAREUC_AUTH2 0x0725
#define CMD_MIFAREUC_READCARD 0x0726
#define CMD_MIFAREUC_SETPWD 0x0727
#define CMD_MIFAREU_SETUID 0x0728
// mifare desfire
#define CMD_MIFARE_DESFIRE_READBL 0x0728