mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-02-25 00:25:48 +08:00
ev2 encrypted channel tx works
This commit is contained in:
parent
fc8e3e8851
commit
51b197c3a6
4 changed files with 33 additions and 24 deletions
|
@ -1295,7 +1295,7 @@ static int DesfireAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel sec
|
||||||
|
|
||||||
// encode
|
// encode
|
||||||
DesfireClearIV(dctx);
|
DesfireClearIV(dctx);
|
||||||
DesfireCryptoEncDec(dctx, false, both, rndlen * 2, both, true); // error 303
|
DesfireCryptoEncDec(dctx, DCOMainKey, both, rndlen * 2, both, true); // error 303
|
||||||
|
|
||||||
// external authenticate
|
// external authenticate
|
||||||
res = DesfireISOExternalAuth(dctx, dctx->appSelected, dctx->keyNum, dctx->keyType, both);
|
res = DesfireISOExternalAuth(dctx, dctx->appSelected, dctx->keyNum, dctx->keyType, both);
|
||||||
|
@ -1314,7 +1314,7 @@ static int DesfireAuthenticateISO(DesfireContext *dctx, DesfireSecureChannel sec
|
||||||
|
|
||||||
// decode rnddata
|
// decode rnddata
|
||||||
uint8_t piccrnd2[64] = {0};
|
uint8_t piccrnd2[64] = {0};
|
||||||
DesfireCryptoEncDec(dctx, false, rnddata, rndlen * 2, piccrnd2, false); // error 307
|
DesfireCryptoEncDec(dctx, DCOMainKey, rnddata, rndlen * 2, piccrnd2, false); // error 307
|
||||||
|
|
||||||
// check
|
// check
|
||||||
if (memcmp(hostrnd2, &piccrnd2[rndlen], rndlen) != 0)
|
if (memcmp(hostrnd2, &piccrnd2[rndlen], rndlen) != 0)
|
||||||
|
|
|
@ -217,7 +217,7 @@ static void DesfireCryptoEncDecSingleBlock(uint8_t *key, DesfireCryptoAlgorythm
|
||||||
memcpy(dstdata, edata, block_size);
|
memcpy(dstdata, edata, block_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv) {
|
void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv) {
|
||||||
uint8_t data[1024] = {0};
|
uint8_t data[1024] = {0};
|
||||||
uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
uint8_t xiv[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
||||||
|
|
||||||
|
@ -234,10 +234,13 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s
|
||||||
|
|
||||||
size_t offset = 0;
|
size_t offset = 0;
|
||||||
while (offset < srcdatalen) {
|
while (offset < srcdatalen) {
|
||||||
if (use_session_key)
|
if (key_type == DCOSessionKeyMac) {
|
||||||
DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
|
DesfireCryptoEncDecSingleBlock(ctx->sessionKeyMAC, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
|
||||||
else
|
} else if (key_type == DCOSessionKeyEnc) {
|
||||||
|
DesfireCryptoEncDecSingleBlock(ctx->sessionKeyEnc, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
|
||||||
|
} else {
|
||||||
DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
|
DesfireCryptoEncDecSingleBlock(ctx->key, ctx->keyType, srcdata + offset, data + offset, xiv, dir_to_send, encode);
|
||||||
|
}
|
||||||
offset += block_size;
|
offset += block_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,13 +253,13 @@ void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *s
|
||||||
memcpy(dstdata, data, srcdatalen);
|
memcpy(dstdata, data, srcdatalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesfireCryptoEncDec(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) {
|
void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode) {
|
||||||
bool dir_to_send = encode;
|
bool dir_to_send = encode;
|
||||||
bool xencode = encode;
|
bool xencode = encode;
|
||||||
if (ctx->secureChannel == DACd40)
|
if (ctx->secureChannel == DACd40)
|
||||||
xencode = false;
|
xencode = false;
|
||||||
|
|
||||||
DesfireCryptoEncDecEx(ctx, use_session_key, srcdata, srcdatalen, dstdata, dir_to_send, xencode, NULL);
|
DesfireCryptoEncDecEx(ctx, key_type, srcdata, srcdatalen, dstdata, dir_to_send, xencode, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2) {
|
static void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_t *sk2) {
|
||||||
|
@ -269,7 +272,7 @@ static void DesfireCMACGenerateSubkeys(DesfireContext *ctx, uint8_t *sk1, uint8_
|
||||||
uint8_t ivect[kbs];
|
uint8_t ivect[kbs];
|
||||||
memset(ivect, 0, kbs);
|
memset(ivect, 0, kbs);
|
||||||
|
|
||||||
DesfireCryptoEncDecEx(ctx, true, l, kbs, l, true, true, ivect);
|
DesfireCryptoEncDecEx(ctx, DCOSessionKeyMac, l, kbs, l, true, true, ivect);
|
||||||
|
|
||||||
bool txor = false;
|
bool txor = false;
|
||||||
|
|
||||||
|
@ -314,7 +317,7 @@ void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *data, size_t len, uint8_t *
|
||||||
bin_xor(buffer + len - kbs, sk1, kbs);
|
bin_xor(buffer + len - kbs, sk1, kbs);
|
||||||
}
|
}
|
||||||
|
|
||||||
DesfireCryptoEncDec(ctx, true, buffer, len, NULL, true);
|
DesfireCryptoEncDec(ctx, DCOSessionKeyMac, buffer, len, NULL, true);
|
||||||
|
|
||||||
if (cmac != NULL)
|
if (cmac != NULL)
|
||||||
memcpy(cmac, ctx->IV, kbs);
|
memcpy(cmac, ctx->IV, kbs);
|
||||||
|
@ -484,7 +487,7 @@ int DesfireEV2CalcCMAC(DesfireContext *ctx, uint8_t cmd, uint8_t *data, size_t d
|
||||||
if (data != NULL && datalen > 0)
|
if (data != NULL && datalen > 0)
|
||||||
memcpy(&mdata[7], data, datalen);
|
memcpy(&mdata[7], data, datalen);
|
||||||
mdatalen = 1 + 2 + 4 + datalen;
|
mdatalen = 1 + 2 + 4 + datalen;
|
||||||
|
|
||||||
return aes_cmac8(NULL, ctx->sessionKeyMAC, mdata, mac, mdatalen);
|
return aes_cmac8(NULL, ctx->sessionKeyMAC, mdata, mac, mdatalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,11 @@ typedef enum {
|
||||||
DCMEncryptedPlain
|
DCMEncryptedPlain
|
||||||
} DesfireCommunicationMode;
|
} DesfireCommunicationMode;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DCOMainKey,
|
||||||
|
DCOSessionKeyMac,
|
||||||
|
DCOSessionKeyEnc
|
||||||
|
} DesfireCryptoOpKeyType;
|
||||||
|
|
||||||
typedef struct DesfireContextS {
|
typedef struct DesfireContextS {
|
||||||
uint8_t keyNum;
|
uint8_t keyNum;
|
||||||
|
@ -100,8 +105,8 @@ size_t DesfireGetMACLength(DesfireContext *ctx);
|
||||||
|
|
||||||
size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint8_t crclen);
|
size_t DesfireSearchCRCPos(uint8_t *data, size_t datalen, uint8_t respcode, uint8_t crclen);
|
||||||
|
|
||||||
void DesfireCryptoEncDec(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode);
|
void DesfireCryptoEncDec(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool encode);
|
||||||
void DesfireCryptoEncDecEx(DesfireContext *ctx, bool use_session_key, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv);
|
void DesfireCryptoEncDecEx(DesfireContext *ctx, DesfireCryptoOpKeyType key_type, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, bool dir_to_send, bool encode, uint8_t *iv);
|
||||||
void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *cmac);
|
void DesfireCryptoCMAC(DesfireContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *cmac);
|
||||||
|
|
||||||
void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version);
|
void DesfireDESKeySetVersion(uint8_t *key, DesfireCryptoAlgorythm keytype, uint8_t version);
|
||||||
|
|
|
@ -166,7 +166,7 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint
|
||||||
size_t srcmaclen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType));
|
size_t srcmaclen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType));
|
||||||
|
|
||||||
uint8_t mac[32] = {0};
|
uint8_t mac[32] = {0};
|
||||||
DesfireCryptoEncDecEx(ctx, true, data, srcmaclen, NULL, true, true, mac);
|
DesfireCryptoEncDecEx(ctx, DCOSessionKeyMac, data, srcmaclen, NULL, true, true, mac);
|
||||||
|
|
||||||
memcpy(dstdata, srcdata, srcdatalen);
|
memcpy(dstdata, srcdata, srcdatalen);
|
||||||
memcpy(&dstdata[srcdatalen], mac, DesfireGetMACLength(ctx));
|
memcpy(&dstdata[srcdatalen], mac, DesfireGetMACLength(ctx));
|
||||||
|
@ -181,7 +181,7 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint
|
||||||
|
|
||||||
memcpy(dstdata, srcdata, hdrlen);
|
memcpy(dstdata, srcdata, hdrlen);
|
||||||
//PrintAndLogEx(INFO, "src[%d]: %s", srcdatalen - hdrlen + 2, sprint_hex(data, srcdatalen - hdrlen + 2));
|
//PrintAndLogEx(INFO, "src[%d]: %s", srcdatalen - hdrlen + 2, sprint_hex(data, srcdatalen - hdrlen + 2));
|
||||||
DesfireCryptoEncDec(ctx, true, data, rlen - hdrlen, &dstdata[hdrlen], true);
|
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, data, rlen - hdrlen, &dstdata[hdrlen], true);
|
||||||
|
|
||||||
*dstdatalen = rlen;
|
*dstdatalen = rlen;
|
||||||
} else if (ctx->commMode == DCMEncryptedPlain) {
|
} else if (ctx->commMode == DCMEncryptedPlain) {
|
||||||
|
@ -191,7 +191,7 @@ static void DesfireSecureChannelEncodeD40(DesfireContext *ctx, uint8_t cmd, uint
|
||||||
rlen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType)) + hdrlen;
|
rlen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType)) + hdrlen;
|
||||||
memcpy(data, srcdata, srcdatalen);
|
memcpy(data, srcdata, srcdatalen);
|
||||||
memcpy(dstdata, srcdata, hdrlen);
|
memcpy(dstdata, srcdata, hdrlen);
|
||||||
DesfireCryptoEncDec(ctx, true, &data[hdrlen], rlen - hdrlen, &dstdata[hdrlen], true);
|
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, &data[hdrlen], rlen - hdrlen, &dstdata[hdrlen], true);
|
||||||
*dstdatalen = rlen;
|
*dstdatalen = rlen;
|
||||||
ctx->commMode = DCMEncrypted;
|
ctx->commMode = DCMEncrypted;
|
||||||
}
|
}
|
||||||
|
@ -227,7 +227,7 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint
|
||||||
desfire_crc32_append(data, srcdatalen + 1);
|
desfire_crc32_append(data, srcdatalen + 1);
|
||||||
|
|
||||||
memcpy(dstdata, srcdata, hdrlen);
|
memcpy(dstdata, srcdata, hdrlen);
|
||||||
DesfireCryptoEncDec(ctx, true, &data[1 + hdrlen], rlen, &dstdata[hdrlen], true);
|
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, &data[1 + hdrlen], rlen, &dstdata[hdrlen], true);
|
||||||
|
|
||||||
*dstdatalen = hdrlen + rlen;
|
*dstdatalen = hdrlen + rlen;
|
||||||
} else if (ctx->commMode == DCMEncryptedPlain) {
|
} else if (ctx->commMode == DCMEncryptedPlain) {
|
||||||
|
@ -237,7 +237,7 @@ static void DesfireSecureChannelEncodeEV1(DesfireContext *ctx, uint8_t cmd, uint
|
||||||
memcpy(dstdata, srcdata, hdrlen);
|
memcpy(dstdata, srcdata, hdrlen);
|
||||||
memcpy(data, &srcdata[hdrlen], srcdatalen);
|
memcpy(data, &srcdata[hdrlen], srcdatalen);
|
||||||
rlen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType));
|
rlen = padded_data_length(srcdatalen - hdrlen, desfire_get_key_block_length(ctx->keyType));
|
||||||
DesfireCryptoEncDec(ctx, true, data, rlen, &dstdata[hdrlen], true);
|
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, data, rlen, &dstdata[hdrlen], true);
|
||||||
*dstdatalen = hdrlen + rlen;
|
*dstdatalen = hdrlen + rlen;
|
||||||
ctx->commMode = DCMEncrypted;
|
ctx->commMode = DCMEncrypted;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,7 @@ static void DesfireSecureChannelEncodeEV2(DesfireContext *ctx, uint8_t cmd, uint
|
||||||
|
|
||||||
dstdata[0] = cmd;
|
dstdata[0] = cmd;
|
||||||
memcpy(&dstdata[1], srcdata, hdrlen);
|
memcpy(&dstdata[1], srcdata, hdrlen);
|
||||||
DesfireCryptoEncDec(ctx, true, data, rlen, &dstdata[1 + hdrlen], true);
|
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, data, rlen, &dstdata[1 + hdrlen], true);
|
||||||
|
|
||||||
uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
uint8_t cmac[DESFIRE_MAX_CRYPTO_BLOCK_SIZE] = {0};
|
||||||
DesfireEV2CalcCMAC(ctx, cmd, &dstdata[1], hdrlen + rlen, cmac);
|
DesfireEV2CalcCMAC(ctx, cmd, &dstdata[1], hdrlen + rlen, cmac);
|
||||||
|
@ -321,7 +321,7 @@ static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata,
|
||||||
uint8_t mac[16] = {0};
|
uint8_t mac[16] = {0};
|
||||||
rlen = padded_data_length(srcdatalen - maclen, desfire_get_key_block_length(ctx->keyType));
|
rlen = padded_data_length(srcdatalen - maclen, desfire_get_key_block_length(ctx->keyType));
|
||||||
memcpy(data, srcdata, srcdatalen - maclen);
|
memcpy(data, srcdata, srcdatalen - maclen);
|
||||||
DesfireCryptoEncDecEx(ctx, true, data, rlen, NULL, true, true, mac);
|
DesfireCryptoEncDecEx(ctx, DCOSessionKeyMac, data, rlen, NULL, true, true, mac);
|
||||||
|
|
||||||
if (memcmp(mac, &srcdata[srcdatalen - maclen], maclen) == 0) {
|
if (memcmp(mac, &srcdata[srcdatalen - maclen], maclen) == 0) {
|
||||||
*dstdatalen = srcdatalen - maclen;
|
*dstdatalen = srcdatalen - maclen;
|
||||||
|
@ -340,7 +340,7 @@ static void DesfireSecureChannelDecodeD40(DesfireContext *ctx, uint8_t *srcdata,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DesfireCryptoEncDec(ctx, true, srcdata, srcdatalen, dstdata, false);
|
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, srcdatalen, dstdata, false);
|
||||||
//PrintAndLogEx(INFO, "decoded[%d]: %s", srcdatalen, sprint_hex(dstdata, srcdatalen));
|
//PrintAndLogEx(INFO, "decoded[%d]: %s", srcdatalen, sprint_hex(dstdata, srcdatalen));
|
||||||
|
|
||||||
size_t puredatalen = DesfireSearchCRCPos(dstdata, srcdatalen, respcode, 2);
|
size_t puredatalen = DesfireSearchCRCPos(dstdata, srcdatalen, respcode, 2);
|
||||||
|
@ -392,7 +392,7 @@ static void DesfireSecureChannelDecodeEV1(DesfireContext *ctx, uint8_t *srcdata,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DesfireCryptoEncDec(ctx, true, srcdata, srcdatalen, dstdata, false);
|
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, srcdatalen, dstdata, false);
|
||||||
//PrintAndLogEx(INFO, "decoded[%d]: %s", srcdatalen, sprint_hex(dstdata, srcdatalen));
|
//PrintAndLogEx(INFO, "decoded[%d]: %s", srcdatalen, sprint_hex(dstdata, srcdatalen));
|
||||||
|
|
||||||
size_t puredatalen = DesfireSearchCRCPos(dstdata, srcdatalen, respcode, 4);
|
size_t puredatalen = DesfireSearchCRCPos(dstdata, srcdatalen, respcode, 4);
|
||||||
|
@ -447,12 +447,13 @@ static void DesfireSecureChannelDecodeEV2(DesfireContext *ctx, uint8_t *srcdata,
|
||||||
PrintAndLogEx(WARNING, "Received MAC is not match with calculated");
|
PrintAndLogEx(WARNING, "Received MAC is not match with calculated");
|
||||||
PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], desfire_get_key_block_length(ctx->keyType)));
|
PrintAndLogEx(INFO, " received MAC: %s", sprint_hex(&srcdata[*dstdatalen], desfire_get_key_block_length(ctx->keyType)));
|
||||||
PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, desfire_get_key_block_length(ctx->keyType)));
|
PrintAndLogEx(INFO, " calculated MAC: %s", sprint_hex(cmac, desfire_get_key_block_length(ctx->keyType)));
|
||||||
|
} else {
|
||||||
|
//PrintAndLogEx(INFO, "Received MAC OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
DesfireEV2FillIV(ctx, true, NULL); // fill IV to ctx
|
DesfireEV2FillIV(ctx, false, NULL); // fill response IV to ctx
|
||||||
|
|
||||||
DesfireCryptoEncDec(ctx, true, srcdata, *dstdatalen, dstdata, false);
|
DesfireCryptoEncDec(ctx, DCOSessionKeyEnc, srcdata, *dstdatalen, dstdata, false);
|
||||||
PrintAndLogEx(INFO, "decoded[%d]: %s", *dstdatalen, sprint_hex(dstdata, *dstdatalen));
|
|
||||||
|
|
||||||
size_t puredatalen = FindISO9797M2PaddingDataLen(dstdata, *dstdatalen);
|
size_t puredatalen = FindISO9797M2PaddingDataLen(dstdata, *dstdatalen);
|
||||||
if (puredatalen != 0) {
|
if (puredatalen != 0) {
|
||||||
|
|
Loading…
Reference in a new issue