mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-23 14:45:37 -07:00
commands sketches and iso select
command
This commit is contained in:
parent
0e07e86e45
commit
8319953ad7
3 changed files with 136 additions and 5 deletions
|
@ -19,6 +19,8 @@
|
|||
#define APDUCODE_TYPE_ERROR 3
|
||||
#define APDUCODE_TYPE_SECURITY 4
|
||||
|
||||
#define APDU_INCLUDE_LE_00 0x100
|
||||
|
||||
typedef struct {
|
||||
const char *ID;
|
||||
const uint8_t Type;
|
||||
|
|
|
@ -277,6 +277,34 @@ void DesfireAIDUintToByte(uint32_t aid, uint8_t *data) {
|
|||
data[2] = (aid >> 16) & 0xff;
|
||||
}
|
||||
|
||||
static uint8_t DesfireKeyToISOKey(DesfireCryptoAlgorythm keytype) {
|
||||
switch (keytype) {
|
||||
case T_DES:
|
||||
return 0x02;
|
||||
case T_3DES:
|
||||
return 0x02;
|
||||
case T_3K3DES:
|
||||
return 0x04;
|
||||
case T_AES:
|
||||
return 0x09;
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
static uint8_t DesfireGetRndLenForKey(DesfireCryptoAlgorythm keytype) {
|
||||
switch (keytype) {
|
||||
case T_DES:
|
||||
return 0x08;
|
||||
case T_3DES:
|
||||
return 0x08;
|
||||
case T_3K3DES:
|
||||
return 0x10;
|
||||
case T_AES:
|
||||
return 0x10;
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void DesfirePrintContext(DesfireContext *ctx) {
|
||||
PrintAndLogEx(INFO, "Key num: %d Key algo: %s Key[%d]: %s",
|
||||
ctx->keyNum,
|
||||
|
@ -311,7 +339,7 @@ void DesfirePrintContext(DesfireContext *ctx) {
|
|||
}
|
||||
}
|
||||
|
||||
static int DESFIRESendApdu(bool activate_field, sAPDU apdu, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) {
|
||||
static int DESFIRESendApduEx(bool activate_field, sAPDU apdu, uint16_t le, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) {
|
||||
if (result_len) *result_len = 0;
|
||||
if (sw) *sw = 0;
|
||||
|
||||
|
@ -327,7 +355,7 @@ static int DESFIRESendApdu(bool activate_field, sAPDU apdu, uint8_t *result, uin
|
|||
|
||||
// COMPUTE APDU
|
||||
int datalen = 0;
|
||||
if (APDUEncodeS(&apdu, false, 0x100, data, &datalen)) { // 100 == with Le
|
||||
if (APDUEncodeS(&apdu, false, le, data, &datalen)) { // 100 == with Le
|
||||
PrintAndLogEx(ERR, "APDU encoding error.");
|
||||
return PM3_EAPDU_ENCODEFAIL;
|
||||
}
|
||||
|
@ -370,6 +398,10 @@ static int DESFIRESendApdu(bool activate_field, sAPDU apdu, uint8_t *result, uin
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int DESFIRESendApdu(bool activate_field, sAPDU apdu, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint16_t *sw) {
|
||||
return DESFIRESendApduEx(activate_field, apdu, APDU_INCLUDE_LE_00, result, max_result_len, result_len, sw);
|
||||
}
|
||||
|
||||
static int DESFIRESendRaw(bool activate_field, uint8_t *data, size_t datalen, uint8_t *result, uint32_t max_result_len, uint32_t *result_len, uint8_t *respcode) {
|
||||
*result_len = 0;
|
||||
if (respcode) *respcode = 0xff;
|
||||
|
@ -516,7 +548,7 @@ static int DesfireExchangeNative(bool activate_field, DesfireContext *ctx, uint8
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *respcode, uint8_t *resp, size_t *resplen, bool enable_chaining, size_t splitbysize) {
|
||||
static int DesfireExchangeISONative(bool activate_field, DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t datalen, uint8_t *respcode, uint8_t *resp, size_t *resplen, bool enable_chaining, size_t splitbysize) {
|
||||
if (resplen)
|
||||
*resplen = 0;
|
||||
if (respcode)
|
||||
|
@ -622,6 +654,16 @@ static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, uint8_t
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int DesfireExchangeISO(bool activate_field, DesfireContext *ctx, sAPDU apdu, uint16_t le, uint8_t *resp, size_t *resplen, uint16_t *sw) {
|
||||
uint32_t rlen = 0;
|
||||
int res = DESFIRESendApduEx(activate_field, apdu, le, resp, 255, &rlen, sw);
|
||||
|
||||
if (res == PM3_SUCCESS)
|
||||
*resplen = rlen;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// move data from blockdata [format: <length, data><length, data>...] to single data block
|
||||
static void DesfireJoinBlockToBytes(uint8_t *blockdata, size_t blockdatacount, size_t blockdatasize, uint8_t *dstdata, size_t *dstdatalen) {
|
||||
*dstdatalen = 0;
|
||||
|
@ -665,7 +707,7 @@ int DesfireExchangeEx(bool activate_field, DesfireContext *ctx, uint8_t cmd, uin
|
|||
if (ctx->cmdSet == DCCNative)
|
||||
res = DesfireExchangeNative(activate_field, ctx, cmd, databuf, databuflen, respcode, databuf, &databuflen, enable_chaining, splitbysize);
|
||||
else
|
||||
res = DesfireExchangeISO(activate_field, ctx, cmd, databuf, databuflen, respcode, databuf, &databuflen, enable_chaining, splitbysize);
|
||||
res = DesfireExchangeISONative(activate_field, ctx, cmd, databuf, databuflen, respcode, databuf, &databuflen, enable_chaining, splitbysize);
|
||||
|
||||
if (splitbysize) {
|
||||
uint8_t sdata[250 * 5] = {0};
|
||||
|
@ -1201,7 +1243,53 @@ static int DesfireAuthenticateEV2(DesfireContext *dctx, DesfireSecureChannel sec
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int DesfireAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose) {
|
||||
uint8_t rndlen = DesfireGetRndLenForKey(dctx->keyType);
|
||||
|
||||
uint8_t hostrnd[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16};
|
||||
uint8_t hostrnd2[] = {0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01};
|
||||
|
||||
uint8_t piccrnd[64];
|
||||
size_t xlen = 0;
|
||||
int res = DesfireISOGetChallenge(dctx, dctx->keyType, piccrnd, &xlen);
|
||||
if (res != PM3_SUCCESS)
|
||||
return 301;
|
||||
|
||||
if (xlen != rndlen)
|
||||
return 302;
|
||||
|
||||
uint8_t both[32] = {0};
|
||||
memcpy(both, hostrnd, rndlen);
|
||||
memcpy(&both[rndlen], piccrnd, rndlen);
|
||||
|
||||
// encode
|
||||
|
||||
// external authenticate
|
||||
res = DesfireISOExternalAuth(dctx, dctx->keyNum, dctx->keyType);
|
||||
if (res != PM3_SUCCESS)
|
||||
return 302;
|
||||
|
||||
// internal authenticate
|
||||
uint8_t rnddata[64] = {0};
|
||||
xlen = 0;
|
||||
res = DesfireISOInternalAuth(dctx, dctx->keyNum, dctx->keyType, hostrnd2, rnddata, &xlen);
|
||||
if (res != PM3_SUCCESS)
|
||||
return 303;
|
||||
|
||||
if (xlen != rndlen)
|
||||
return 304;
|
||||
|
||||
// decode rnddata
|
||||
|
||||
// check
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int DesfireAuthenticate(DesfireContext *dctx, DesfireSecureChannel secureChannel, bool verbose) {
|
||||
if (dctx->cmdSet == DCCISO)
|
||||
return DesfireAuthenticateISO(dctx, secureChannel, verbose);
|
||||
|
||||
if (secureChannel == DACd40 || secureChannel == DACEV1)
|
||||
return DesfireAuthenticateEV1(dctx, secureChannel, verbose);
|
||||
|
||||
|
@ -1382,7 +1470,6 @@ int DesfireFillFileList(DesfireContext *dctx, FileListS FileList, size_t *filesc
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
int DesfireCreateFile(DesfireContext *dctx, uint8_t ftype, uint8_t *fdata, size_t fdatalen, bool checklen) {
|
||||
const DesfireCreateFileCommandsS *rcmd = GetDesfireFileCmdRec(ftype);
|
||||
if (rcmd == NULL)
|
||||
|
@ -2087,3 +2174,40 @@ int DesfireSetConfiguration(DesfireContext *dctx, uint8_t paramid, uint8_t *para
|
|||
|
||||
return res;
|
||||
}
|
||||
|
||||
int DesfireISOSelect(DesfireContext *dctx, bool sel_by_df_name, uint8_t *id, uint8_t idlen, uint8_t *resp, size_t *resplen) {
|
||||
sAPDU apdu = {0};
|
||||
apdu.CLA = 0x00;
|
||||
apdu.INS = ISO7816_SELECT_FILE;
|
||||
apdu.P1 = (sel_by_df_name) ? 0x04 : 0x00;
|
||||
apdu.P2 = 0x00;
|
||||
apdu.Lc = idlen;
|
||||
apdu.data = id;
|
||||
|
||||
uint16_t sw = 0;
|
||||
int res = DesfireExchangeISO(true, dctx, apdu, APDU_INCLUDE_LE_00, resp, resplen, &sw);
|
||||
|
||||
if (res == PM3_SUCCESS && sw != 0x9000)
|
||||
return PM3_ESOFT;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int DesfireISOGetChallenge(DesfireContext *dctx, DesfireCryptoAlgorythm keytype, uint8_t *resp, size_t *resplen) {
|
||||
DesfireGetRndLenForKey(keytype);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int DesfireISOExternalAuth(DesfireContext *dctx, uint8_t keynum, DesfireCryptoAlgorythm keytype) {
|
||||
|
||||
DesfireKeyToISOKey(keytype);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int DesfireISOInternalAuth(DesfireContext *dctx, uint8_t keynum, DesfireCryptoAlgorythm keytype, uint8_t *data, uint8_t *resp, size_t *resplen) {
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -167,4 +167,9 @@ int DesfireReadRecords(DesfireContext *dctx, uint8_t fnum, uint32_t recnum, uint
|
|||
int DesfireWriteRecord(DesfireContext *dctx, uint8_t fnum, uint32_t offset, uint32_t len, uint8_t *data);
|
||||
int DesfireUpdateRecord(DesfireContext *dctx, uint8_t fnum, uint32_t recnum, uint32_t offset, uint32_t len, uint8_t *data);
|
||||
|
||||
int DesfireISOSelect(DesfireContext *dctx, bool sel_by_df_name, uint8_t *id, uint8_t idlen, uint8_t *resp, size_t *resplen);
|
||||
int DesfireISOGetChallenge(DesfireContext *dctx, DesfireCryptoAlgorythm keytype, uint8_t *resp, size_t *resplen);
|
||||
int DesfireISOExternalAuth(DesfireContext *dctx, uint8_t keynum, DesfireCryptoAlgorythm keytype);
|
||||
int DesfireISOInternalAuth(DesfireContext *dctx, uint8_t keynum, DesfireCryptoAlgorythm keytype, uint8_t *data, uint8_t *resp, size_t *resplen);
|
||||
|
||||
#endif // __DESFIRECORE_H
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue