mirror of
https://github.com/Proxmark/proxmark3.git
synced 2024-09-21 07:16:24 +08:00
Merge branch 'master' into 14a_rework3
This commit is contained in:
commit
378d3406ca
|
@ -13,6 +13,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
- `hf mf nested` Check keys after they have found (Merlok)
|
||||
- `hf mf chk` Move main cycle to arm (Merlok)
|
||||
- Changed proxmark command line parameter `flush` to `-f` or `-flush` (Merlok)
|
||||
- Changed `hf 14a reader` to just reqest-anticilission-select sequence (Merlok)
|
||||
|
||||
### Fixed
|
||||
- Changed start sequence in Qt mode (fix: short commands hangs main Qt thread) (Merlok)
|
||||
|
@ -32,6 +33,8 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
- Added to proxmark command line parameters `w` - wait 20s for serial port (Merlok)
|
||||
- Added to proxmark command line parameters `c` and `l` - execute command and lua script from command line (Merlok)
|
||||
- Added to proxmark ability to execute commands from stdin (pipe) (Merlok)
|
||||
- Added `hf 14a info` and moved there functionality from `hf 14a reader` (Merlok)
|
||||
- Added to `hf 14a info` detection of weak prng from Iceman1001 fork (Merlok)
|
||||
|
||||
## [3.0.1][2017-06-08]
|
||||
|
||||
|
|
|
@ -1821,7 +1821,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
|||
}
|
||||
|
||||
// PICC compilant with iso14443a-4 ---> (SAK & 0x20 != 0)
|
||||
if( (sak & 0x20) == 0) return 2;
|
||||
if( (sak & 0x20) == 0) return 2;
|
||||
|
||||
if (!no_rats) {
|
||||
// Request for answer to select
|
||||
|
|
|
@ -220,8 +220,10 @@ int CmdHF14AInfo(const char *Cmd)
|
|||
PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]);
|
||||
PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
|
||||
|
||||
bool isMifareClassic = true;
|
||||
switch (card.sak) {
|
||||
case 0x00:
|
||||
isMifareClassic = false;
|
||||
|
||||
//***************************************test****************
|
||||
// disconnect
|
||||
|
@ -456,6 +458,19 @@ int CmdHF14AInfo(const char *Cmd)
|
|||
// try to see if card responses to "chinese magic backdoor" commands.
|
||||
mfCIdentify();
|
||||
|
||||
if (isMifareClassic) {
|
||||
switch(DetectClassicPrng()) {
|
||||
case 0:
|
||||
PrintAndLog("Prng detection: HARDEND (hardnested)");
|
||||
break;
|
||||
case 1:
|
||||
PrintAndLog("Prng detection: WEAK");
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Prng detection error.");
|
||||
}
|
||||
}
|
||||
|
||||
return select_status;
|
||||
}
|
||||
|
||||
|
|
|
@ -903,3 +903,72 @@ int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** validate_prng_nonce
|
||||
* Determine if nonce is deterministic. ie: Suspectable to Darkside attack.
|
||||
* returns
|
||||
* true = weak prng
|
||||
* false = hardend prng
|
||||
*/
|
||||
bool validate_prng_nonce(uint32_t nonce) {
|
||||
uint16_t *dist = 0;
|
||||
uint16_t x, i;
|
||||
|
||||
dist = malloc(2 << 16);
|
||||
if(!dist)
|
||||
return -1;
|
||||
|
||||
// init prng table:
|
||||
for (x = i = 1; i; ++i) {
|
||||
dist[(x & 0xff) << 8 | x >> 8] = i;
|
||||
x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
|
||||
}
|
||||
|
||||
uint32_t res = (65535 - dist[nonce >> 16] + dist[nonce & 0xffff]) % 65535;
|
||||
|
||||
free(dist);
|
||||
return (res == 16);
|
||||
}
|
||||
|
||||
/* Detect Tag Prng,
|
||||
* function performs a partial AUTH, where it tries to authenticate against block0, key A, but only collects tag nonce.
|
||||
* the tag nonce is check to see if it has a predictable PRNG.
|
||||
* @returns
|
||||
* TRUE if tag uses WEAK prng (ie Now the NACK bug also needs to be present for Darkside attack)
|
||||
* FALSE is tag uses HARDEND prng (ie hardnested attack possible, with known key)
|
||||
*/
|
||||
int DetectClassicPrng(void){
|
||||
|
||||
UsbCommand resp, respA;
|
||||
uint8_t cmd[] = {0x60, 0x00}; // MIFARE_AUTH_KEYA
|
||||
uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS;
|
||||
|
||||
UsbCommand c = {CMD_READER_ISO_14443a, {flags, sizeof(cmd), 0}};
|
||||
memcpy(c.d.asBytes, cmd, sizeof(cmd));
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommand(&c);
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
PrintAndLog("PRNG UID: Reply timeout.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if select tag failed.
|
||||
if (resp.arg[0] == 0) {
|
||||
PrintAndLog("PRNG error: selecting tag failed, can't detect prng.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &respA, 5000)) {
|
||||
PrintAndLog("PRNG data: Reply timeout.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check respA
|
||||
if (respA.arg[0] != 4) {
|
||||
PrintAndLog("PRNG data error: Wrong length: %d", respA.arg[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t nonce = bytes_to_num(respA.d.asBytes, respA.arg[0]);
|
||||
return validate_prng_nonce(nonce);
|
||||
}
|
||||
|
|
|
@ -60,5 +60,6 @@ extern int saveTraceCard(void);
|
|||
extern int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len);
|
||||
|
||||
extern int mfCIdentify();
|
||||
extern int DetectClassicPrng(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -426,7 +426,6 @@ int nonce_distance(uint32_t from, uint32_t to)
|
|||
return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t fastfwd[2][8] = {
|
||||
{ 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB},
|
||||
{ 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980}};
|
||||
|
|
Loading…
Reference in a new issue