mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-19 12:59:44 -07:00
hf list mf 1st auth works
This commit is contained in:
parent
edd4c8385b
commit
747885a6ed
3 changed files with 44 additions and 12 deletions
|
@ -434,11 +434,15 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DecodeMifareData(frame, data_len, isResponse, mfData, &mfDataLen)) {
|
if (DecodeMifareData(frame, data_len, isResponse, mfData, &mfDataLen)) {
|
||||||
annotateIso14443a(explanation, sizeof(explanation), mfData, mfDataLen);
|
memset(explanation, 0x00, sizeof(explanation));
|
||||||
|
if (!isResponse) {
|
||||||
|
explanation[0] = '>';
|
||||||
|
annotateIso14443a(&explanation[1], sizeof(explanation) - 1, mfData, mfDataLen);
|
||||||
|
}
|
||||||
|
uint8_t crcc = iso14443A_CRC_check(isResponse, mfData, mfDataLen);
|
||||||
PrintAndLog(" | * | dec |%-64s | %-4s| %s",
|
PrintAndLog(" | * | dec |%-64s | %-4s| %s",
|
||||||
sprint_hex(mfData, mfDataLen),
|
sprint_hex(mfData, mfDataLen),
|
||||||
"",
|
(crcc == 0 ? "!crc" : (crcc == 1 ? " ok " : " ")),
|
||||||
(true) ? explanation : "");
|
(true) ? explanation : "");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@ enum MifareAuthSeq {
|
||||||
masNt,
|
masNt,
|
||||||
masNrAr,
|
masNrAr,
|
||||||
masAt,
|
masAt,
|
||||||
|
masAuthComplete,
|
||||||
masFirstData,
|
masFirstData,
|
||||||
masData,
|
masData,
|
||||||
masDataNested,
|
|
||||||
masError,
|
masError,
|
||||||
};
|
};
|
||||||
static enum MifareAuthSeq MifareAuthState;
|
static enum MifareAuthSeq MifareAuthState;
|
||||||
|
@ -73,9 +73,6 @@ uint8_t mifare_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
|
||||||
{
|
{
|
||||||
switch(MifareAuthState) {
|
switch(MifareAuthState) {
|
||||||
case masNone:
|
case masNone:
|
||||||
case masFirstData:
|
|
||||||
case masData:
|
|
||||||
case masDataNested:
|
|
||||||
case masError:
|
case masError:
|
||||||
return iso14443A_CRC_check(isResponse, data, len);
|
return iso14443A_CRC_check(isResponse, data, len);
|
||||||
default:
|
default:
|
||||||
|
@ -231,7 +228,7 @@ void annotateMifare(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize, uint8
|
||||||
case masAt:
|
case masAt:
|
||||||
if (cmdsize == 4 && isResponse) {
|
if (cmdsize == 4 && isResponse) {
|
||||||
snprintf(exp,size,"AUTH: at (enc)");
|
snprintf(exp,size,"AUTH: at (enc)");
|
||||||
MifareAuthState = masFirstData;
|
MifareAuthState = masAuthComplete;
|
||||||
AuthData.at_enc = bytes_to_num(cmd, 4);
|
AuthData.at_enc = bytes_to_num(cmd, 4);
|
||||||
AuthData.at_enc_par = parity[0];
|
AuthData.at_enc_par = parity[0];
|
||||||
return;
|
return;
|
||||||
|
@ -243,14 +240,26 @@ void annotateMifare(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize, uint8
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isResponse)
|
if (!isResponse && ((MifareAuthState == masNone) || (MifareAuthState == masError)))
|
||||||
annotateIso14443a(exp, size, cmd, cmdsize);
|
annotateIso14443a(exp, size, cmd, cmdsize);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, bool isResponse, uint8_t *mfData, size_t *mfDataLen) {
|
bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, bool isResponse, uint8_t *mfData, size_t *mfDataLen) {
|
||||||
|
static struct Crypto1State *traceCrypto1;
|
||||||
|
uint64_t mfLastKey;
|
||||||
|
|
||||||
*mfDataLen = 0;
|
*mfDataLen = 0;
|
||||||
|
|
||||||
|
if (MifareAuthState == masAuthComplete) {
|
||||||
|
if (traceCrypto1) {
|
||||||
|
crypto1_destroy(traceCrypto1);
|
||||||
|
}
|
||||||
|
|
||||||
|
MifareAuthState = masFirstData;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmdsize > 32)
|
if (cmdsize > 32)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -267,7 +276,7 @@ bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, bool isResponse, uint8_t *m
|
||||||
uint64_t lfsr = 0;
|
uint64_t lfsr = 0;
|
||||||
crypto1_get_lfsr(revstate, &lfsr);
|
crypto1_get_lfsr(revstate, &lfsr);
|
||||||
crypto1_destroy(revstate);
|
crypto1_destroy(revstate);
|
||||||
// LastKey = lfsr;
|
mfLastKey = lfsr;
|
||||||
PrintAndLog(" | * | key | probable key:%x%x Prng:%s ks2:%08x ks3:%08x | |",
|
PrintAndLog(" | * | key | probable key:%x%x Prng:%s ks2:%08x ks3:%08x | |",
|
||||||
(unsigned int)((lfsr & 0xFFFFFFFF00000000) >> 32), (unsigned int)(lfsr & 0xFFFFFFFF),
|
(unsigned int)((lfsr & 0xFFFFFFFF00000000) >> 32), (unsigned int)(lfsr & 0xFFFFFFFF),
|
||||||
validate_prng_nonce(AuthData.nt) ? "WEAK": "HARD",
|
validate_prng_nonce(AuthData.nt) ? "WEAK": "HARD",
|
||||||
|
@ -275,17 +284,34 @@ bool DecodeMifareData(uint8_t *cmd, uint8_t cmdsize, bool isResponse, uint8_t *m
|
||||||
ks3);
|
ks3);
|
||||||
|
|
||||||
AuthData.first_auth = false;
|
AuthData.first_auth = false;
|
||||||
|
|
||||||
|
traceCrypto1 = lfsr_recovery64(ks2, ks3);
|
||||||
} else {
|
} else {
|
||||||
printf("uid:%x nt:%x ar_enc:%x at_enc:%x\n", AuthData.uid, AuthData.nt, AuthData.ar_enc, AuthData.at_enc);
|
printf("uid:%x nt:%x ar_enc:%x at_enc:%x\n", AuthData.uid, AuthData.nt, AuthData.ar_enc, AuthData.at_enc);
|
||||||
|
|
||||||
|
// check last used key
|
||||||
|
if (mfLastKey) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// check default keys
|
||||||
|
|
||||||
|
// nested
|
||||||
|
if (validate_prng_nonce(AuthData.nt)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
//hardnested
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
MifareAuthState = masData;
|
MifareAuthState = masData;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MifareAuthState == masData) {
|
if (MifareAuthState == masData && traceCrypto1) {
|
||||||
|
memcpy(mfData, cmd, cmdsize);
|
||||||
|
mf_crypto1_decrypt(traceCrypto1, mfData, cmdsize, 0);
|
||||||
|
*mfDataLen = cmdsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return *mfDataLen > 0;
|
return *mfDataLen > 0;
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
|
#include "crapto1/crapto1.h"
|
||||||
|
|
||||||
// defaults
|
// defaults
|
||||||
// timeout in units. (ms * 106)/10 or us*0.0106
|
// timeout in units. (ms * 106)/10 or us*0.0106
|
||||||
|
@ -62,5 +63,6 @@ extern int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t
|
||||||
extern int mfCIdentify();
|
extern int mfCIdentify();
|
||||||
extern int DetectClassicPrng(void);
|
extern int DetectClassicPrng(void);
|
||||||
extern bool validate_prng_nonce(uint32_t nonce);
|
extern bool validate_prng_nonce(uint32_t nonce);
|
||||||
|
extern void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue