mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-02-25 16:13:58 +08:00
Merge pull request #153 from AdamLaurie/master
add support for raw block 3/4 iclass keys
This commit is contained in:
commit
c578d3412c
2 changed files with 49 additions and 16 deletions
|
@ -49,6 +49,7 @@ of stream transmissions (marshmellow)
|
||||||
- Revised workflow for StandAloneMode14a (Craig Young)
|
- Revised workflow for StandAloneMode14a (Craig Young)
|
||||||
- EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers)
|
- EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers)
|
||||||
- 'hw version' only talks to ARM at startup, after that the info is cached. (pwpiwi)
|
- 'hw version' only talks to ARM at startup, after that the info is cached. (pwpiwi)
|
||||||
|
- Added `r` option to iclass functions - allows key to be provided in raw block 3/4 format
|
||||||
|
|
||||||
## [2.2.0][2015-07-12]
|
## [2.2.0][2015-07-12]
|
||||||
|
|
||||||
|
|
|
@ -500,7 +500,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool use_credit_key, bool elite, bool verbose) {
|
static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool use_credit_key, bool elite, bool rawkey, bool verbose) {
|
||||||
uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||||
uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||||
|
|
||||||
|
@ -508,7 +508,11 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//get div_key
|
//get div_key
|
||||||
|
if(rawkey)
|
||||||
|
memcpy(div_key, KEY, 8);
|
||||||
|
else
|
||||||
HFiClassCalcDivKey(CSN, KEY, div_key, elite);
|
HFiClassCalcDivKey(CSN, KEY, div_key, elite);
|
||||||
|
PrintAndLog("Authing with %s: %02x%02x%02x%02x%02x%02x%02x%02x", rawkey ? "raw key" : "diversified key", div_key[0],div_key[1],div_key[2],div_key[3],div_key[4],div_key[5],div_key[6],div_key[7]);
|
||||||
|
|
||||||
doMAC(CCNR, div_key, MAC);
|
doMAC(CCNR, div_key, MAC);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
|
@ -530,7 +534,7 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u
|
||||||
}
|
}
|
||||||
|
|
||||||
int usage_hf_iclass_dump(void) {
|
int usage_hf_iclass_dump(void) {
|
||||||
PrintAndLog("Usage: hf iclass dump f <fileName> k <Key> c <CreditKey> e\n");
|
PrintAndLog("Usage: hf iclass dump f <fileName> k <Key> c <CreditKey> e|r\n");
|
||||||
PrintAndLog("Options:");
|
PrintAndLog("Options:");
|
||||||
PrintAndLog(" f <filename> : specify a filename to save dump to");
|
PrintAndLog(" f <filename> : specify a filename to save dump to");
|
||||||
PrintAndLog(" k <Key> : *Access Key as 16 hex symbols or 1 hex to select key from memory");
|
PrintAndLog(" k <Key> : *Access Key as 16 hex symbols or 1 hex to select key from memory");
|
||||||
|
@ -538,6 +542,7 @@ int usage_hf_iclass_dump(void) {
|
||||||
PrintAndLog(" e : If 'e' is specified, the key is interpreted as the 16 byte");
|
PrintAndLog(" e : If 'e' is specified, the key is interpreted as the 16 byte");
|
||||||
PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
|
PrintAndLog(" Custom Key (KCus), which can be obtained via reader-attack");
|
||||||
PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
|
PrintAndLog(" See 'hf iclass sim 2'. This key should be on iclass-format");
|
||||||
|
PrintAndLog(" r : If 'r' is specified, the key is interpreted as raw block 3/4");
|
||||||
PrintAndLog(" NOTE: * = required");
|
PrintAndLog(" NOTE: * = required");
|
||||||
PrintAndLog("Samples:");
|
PrintAndLog("Samples:");
|
||||||
PrintAndLog(" hf iclass dump k 001122334455667B");
|
PrintAndLog(" hf iclass dump k 001122334455667B");
|
||||||
|
@ -567,6 +572,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
|
||||||
bool have_credit_key = false;
|
bool have_credit_key = false;
|
||||||
bool use_credit_key = false;
|
bool use_credit_key = false;
|
||||||
bool elite = false;
|
bool elite = false;
|
||||||
|
bool rawkey = false;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
|
|
||||||
|
@ -631,6 +637,11 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
rawkey = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -674,9 +685,9 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
|
||||||
}
|
}
|
||||||
ul_switch_off_field();
|
ul_switch_off_field();
|
||||||
// authenticate debit key and get div_key - later store in dump block 3
|
// authenticate debit key and get div_key - later store in dump block 3
|
||||||
if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, false)){
|
if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){
|
||||||
//try twice - for some reason it sometimes fails the first time...
|
//try twice - for some reason it sometimes fails the first time...
|
||||||
if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, false)){
|
if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){
|
||||||
ul_switch_off_field();
|
ul_switch_off_field();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -714,9 +725,9 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
|
||||||
ul_switch_off_field();
|
ul_switch_off_field();
|
||||||
memset(MAC,0,4);
|
memset(MAC,0,4);
|
||||||
// AA2 authenticate credit key and git c_div_key - later store in dump block 4
|
// AA2 authenticate credit key and git c_div_key - later store in dump block 4
|
||||||
if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false)){
|
if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){
|
||||||
//try twice - for some reason it sometimes fails the first time...
|
//try twice - for some reason it sometimes fails the first time...
|
||||||
if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false)){
|
if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){
|
||||||
ul_switch_off_field();
|
ul_switch_off_field();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -776,10 +787,10 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool verbose) {
|
static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool verbose) {
|
||||||
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
||||||
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||||
if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, verbose))
|
if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
|
@ -812,6 +823,7 @@ int usage_hf_iclass_writeblock(void) {
|
||||||
PrintAndLog(" k <Key> : Access Key as 16 hex symbols or 1 hex to select key from memory");
|
PrintAndLog(" k <Key> : Access Key as 16 hex symbols or 1 hex to select key from memory");
|
||||||
PrintAndLog(" c : If 'c' is specified, the key set is assumed to be the credit key\n");
|
PrintAndLog(" c : If 'c' is specified, the key set is assumed to be the credit key\n");
|
||||||
PrintAndLog(" e : If 'e' is specified, elite computations applied to key");
|
PrintAndLog(" e : If 'e' is specified, elite computations applied to key");
|
||||||
|
PrintAndLog(" r : If 'r' is specified, no computations applied to key");
|
||||||
PrintAndLog("Samples:");
|
PrintAndLog("Samples:");
|
||||||
PrintAndLog(" hf iclass writeblk b 0A d AAAAAAAAAAAAAAAA k 001122334455667B");
|
PrintAndLog(" hf iclass writeblk b 0A d AAAAAAAAAAAAAAAA k 001122334455667B");
|
||||||
PrintAndLog(" hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c");
|
PrintAndLog(" hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c");
|
||||||
|
@ -828,6 +840,7 @@ int CmdHFiClass_WriteBlock(const char *Cmd) {
|
||||||
char tempStr[50] = {0};
|
char tempStr[50] = {0};
|
||||||
bool use_credit_key = false;
|
bool use_credit_key = false;
|
||||||
bool elite = false;
|
bool elite = false;
|
||||||
|
bool rawkey= false;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00)
|
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||||
|
@ -883,6 +896,11 @@ int CmdHFiClass_WriteBlock(const char *Cmd) {
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
rawkey = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -892,13 +910,13 @@ int CmdHFiClass_WriteBlock(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdp < 6) return usage_hf_iclass_writeblock();
|
if (cmdp < 6) return usage_hf_iclass_writeblock();
|
||||||
int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, true);
|
int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, true);
|
||||||
ul_switch_off_field();
|
ul_switch_off_field();
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usage_hf_iclass_clone(void) {
|
int usage_hf_iclass_clone(void) {
|
||||||
PrintAndLog("Usage: hf iclass clone f <tagfile.bin> b <first block> l <last block> k <KEY> e c");
|
PrintAndLog("Usage: hf iclass clone f <tagfile.bin> b <first block> l <last block> k <KEY> c e|r");
|
||||||
PrintAndLog("Options:");
|
PrintAndLog("Options:");
|
||||||
PrintAndLog(" f <filename>: specify a filename to clone from");
|
PrintAndLog(" f <filename>: specify a filename to clone from");
|
||||||
PrintAndLog(" b <Block> : The first block to clone as 2 hex symbols");
|
PrintAndLog(" b <Block> : The first block to clone as 2 hex symbols");
|
||||||
|
@ -906,6 +924,7 @@ int usage_hf_iclass_clone(void) {
|
||||||
PrintAndLog(" k <Key> : Access Key as 16 hex symbols or 1 hex to select key from memory");
|
PrintAndLog(" k <Key> : Access Key as 16 hex symbols or 1 hex to select key from memory");
|
||||||
PrintAndLog(" c : If 'c' is specified, the key set is assumed to be the credit key\n");
|
PrintAndLog(" c : If 'c' is specified, the key set is assumed to be the credit key\n");
|
||||||
PrintAndLog(" e : If 'e' is specified, elite computations applied to key");
|
PrintAndLog(" e : If 'e' is specified, elite computations applied to key");
|
||||||
|
PrintAndLog(" r : If 'r' is specified, no computations applied to key");
|
||||||
PrintAndLog("Samples:");
|
PrintAndLog("Samples:");
|
||||||
PrintAndLog(" hf iclass clone f iclass_tagdump-121345.bin b 06 l 1A k 1122334455667788 e");
|
PrintAndLog(" hf iclass clone f iclass_tagdump-121345.bin b 06 l 1A k 1122334455667788 e");
|
||||||
PrintAndLog(" hf iclass clone f iclass_tagdump-121345.bin b 05 l 19 k 0");
|
PrintAndLog(" hf iclass clone f iclass_tagdump-121345.bin b 05 l 19 k 0");
|
||||||
|
@ -924,6 +943,7 @@ int CmdHFiClassCloneTag(const char *Cmd) {
|
||||||
uint8_t dataLen = 0;
|
uint8_t dataLen = 0;
|
||||||
bool use_credit_key = false;
|
bool use_credit_key = false;
|
||||||
bool elite = false;
|
bool elite = false;
|
||||||
|
bool rawkey = false;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00)
|
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||||
|
@ -987,6 +1007,11 @@ int CmdHFiClassCloneTag(const char *Cmd) {
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
rawkey = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -1026,7 +1051,7 @@ int CmdHFiClassCloneTag(const char *Cmd) {
|
||||||
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
||||||
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||||
|
|
||||||
if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, true))
|
if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, true))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
UsbCommand w = {CMD_ICLASS_CLONE,{startblock,endblock}};
|
UsbCommand w = {CMD_ICLASS_CLONE,{startblock,endblock}};
|
||||||
|
@ -1059,11 +1084,11 @@ int CmdHFiClassCloneTag(const char *Cmd) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool verbose) {
|
static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose) {
|
||||||
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
|
||||||
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||||
|
|
||||||
if (!select_and_auth(KEY, MAC, div_key, (keyType==0x18), elite, verbose))
|
if (!select_and_auth(KEY, MAC, div_key, (keyType==0x18), elite, rawkey, verbose))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
|
@ -1086,12 +1111,13 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite,
|
||||||
}
|
}
|
||||||
|
|
||||||
int usage_hf_iclass_readblock(void) {
|
int usage_hf_iclass_readblock(void) {
|
||||||
PrintAndLog("Usage: hf iclass readblk b <Block> k <Key> c e\n");
|
PrintAndLog("Usage: hf iclass readblk b <Block> k <Key> c e|r\n");
|
||||||
PrintAndLog("Options:");
|
PrintAndLog("Options:");
|
||||||
PrintAndLog(" b <Block> : The block number as 2 hex symbols");
|
PrintAndLog(" b <Block> : The block number as 2 hex symbols");
|
||||||
PrintAndLog(" k <Key> : Access Key as 16 hex symbols or 1 hex to select key from memory");
|
PrintAndLog(" k <Key> : Access Key as 16 hex symbols or 1 hex to select key from memory");
|
||||||
PrintAndLog(" c : If 'c' is specified, the key set is assumed to be the credit key\n");
|
PrintAndLog(" c : If 'c' is specified, the key set is assumed to be the credit key\n");
|
||||||
PrintAndLog(" e : If 'e' is specified, elite computations applied to key");
|
PrintAndLog(" e : If 'e' is specified, elite computations applied to key");
|
||||||
|
PrintAndLog(" r : If 'r' is specified, no computations applied to key");
|
||||||
PrintAndLog("Samples:");
|
PrintAndLog("Samples:");
|
||||||
PrintAndLog(" hf iclass readblk b 06 k 0011223344556677");
|
PrintAndLog(" hf iclass readblk b 06 k 0011223344556677");
|
||||||
PrintAndLog(" hf iclass readblk b 1B k 0011223344556677 c");
|
PrintAndLog(" hf iclass readblk b 1B k 0011223344556677 c");
|
||||||
|
@ -1107,6 +1133,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
|
||||||
uint8_t dataLen = 0;
|
uint8_t dataLen = 0;
|
||||||
char tempStr[50] = {0};
|
char tempStr[50] = {0};
|
||||||
bool elite = false;
|
bool elite = false;
|
||||||
|
bool rawkey = false;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00)
|
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||||
|
@ -1153,6 +1180,11 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
rawkey = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -1163,7 +1195,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
|
||||||
|
|
||||||
if (cmdp < 4) return usage_hf_iclass_readblock();
|
if (cmdp < 4) return usage_hf_iclass_readblock();
|
||||||
|
|
||||||
return ReadBlock(KEY, blockno, keyType, elite, true);
|
return ReadBlock(KEY, blockno, keyType, elite, rawkey, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHFiClass_loclass(const char *Cmd) {
|
int CmdHFiClass_loclass(const char *Cmd) {
|
||||||
|
|
Loading…
Reference in a new issue