diff --git a/client/mifarehost.c b/client/mifarehost.c index fe1a8edb..49541921 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -903,3 +903,46 @@ int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, return 0; } +/* 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); +} diff --git a/client/mifarehost.h b/client/mifarehost.h index 118d55cc..09a78ae3 100644 --- a/client/mifarehost.h +++ b/client/mifarehost.h @@ -14,6 +14,7 @@ #include #include #include "data.h" +#include "crapto1/crapto1.h" // defaults // timeout in units. (ms * 106)/10 or us*0.0106 @@ -60,5 +61,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