diff --git a/client/src/cipurse/cipursecore.c b/client/src/cipurse/cipursecore.c index 9b6176d97..a848fc30c 100644 --- a/client/src/cipurse/cipursecore.c +++ b/client/src/cipurse/cipursecore.c @@ -20,7 +20,6 @@ #include "emv/emvjson.h" #include "ui.h" #include "util.h" -#include "cipurse/cipursecrypto.h" // context for secure channel CipurseContext cipurseContext; @@ -49,7 +48,7 @@ static int CIPURSEExchangeEx(bool ActivateField, bool LeaveFieldON, sAPDU apdu, uint16_t xle = IncludeLe ? 0x100 : 0x00; if (xle == 0x100 && Le != 0) xle = Le; - + CipurseCAPDUReqEncode(&cipurseContext, &apdu, &secapdu, securedata, IncludeLe, Le); if (APDUEncodeS(&secapdu, false, xle, data, &datalen)) { @@ -172,8 +171,8 @@ bool CIPURSEChannelAuthenticate(uint8_t keyIndex, uint8_t *key, bool verbose) { if (verbose) PrintAndLogEx(INFO, "Authentication " _GREEN_("OK")); - //CipurseCChannelSetSecurityLevels(&cpc, CPSMACed, CPSMACed); - CipurseCChannelSetSecurityLevels(&cpc, CPSPlain, CPSPlain); + CipurseCChannelSetSecurityLevels(&cpc, CPSMACed, CPSMACed); + //CipurseCChannelSetSecurityLevels(&cpc, CPSPlain, CPSPlain); memcpy(&cipurseContext, &cpc, sizeof(CipurseContext)); return true; } else { @@ -185,6 +184,10 @@ bool CIPURSEChannelAuthenticate(uint8_t keyIndex, uint8_t *key, bool verbose) { } } +void CIPURSECSetActChannelSecurityLevels(CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp) { + CipurseCChannelSetSecurityLevels(&cipurseContext, req, resp); +} + void CIPURSEPrintInfoFile(uint8_t *data, size_t len) { if (len < 2) { PrintAndLogEx(ERR, "Info file length " _RED_("ERROR")); diff --git a/client/src/cipurse/cipursecore.h b/client/src/cipurse/cipursecore.h index e0f638553..ad044087e 100644 --- a/client/src/cipurse/cipursecore.h +++ b/client/src/cipurse/cipursecore.h @@ -16,6 +16,8 @@ #include #include "emv/apduinfo.h" // sAPDU +#include "cipurse/cipursecrypto.h" + #define CIPURSE_DEFAULT_KEY {0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73} @@ -35,5 +37,6 @@ int CIPURSEReadBinary(uint16_t offset, uint8_t *Result, size_t MaxResultLen, siz int CIPURSEUpdateBinary(uint16_t offset, uint8_t *data, uint16_t datalen); bool CIPURSEChannelAuthenticate(uint8_t keyIndex, uint8_t *key, bool verbose); +void CIPURSECSetActChannelSecurityLevels(CipurseChannelSecurityLevel req, CipurseChannelSecurityLevel resp); #endif /* __CIPURSECORE_H__ */ diff --git a/client/src/cipurse/cipursecrypto.c b/client/src/cipurse/cipursecrypto.c index e054bff27..45081d75d 100644 --- a/client/src/cipurse/cipursecrypto.c +++ b/client/src/cipurse/cipursecrypto.c @@ -287,7 +287,7 @@ void CipurseCChannelDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, */ void CipurseCGenerateMAC(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac) { uint8_t temp[CIPURSE_AES_KEY_LENGTH] = {0}; -PrintAndLogEx(INFO, "------[%d]: %s", datalen, sprint_hex(data, datalen)); + memcpy(ctx->frameKeyNext, ctx->frameKey, CIPURSE_AES_KEY_LENGTH); int i = 0; while (datalen > i) { @@ -299,6 +299,7 @@ PrintAndLogEx(INFO, "------[%d]: %s", datalen, sprint_hex(data, datalen)); aes_encode(NULL, ctx->frameKey, ctx->frameKeyNext, temp, CIPURSE_AES_KEY_LENGTH); bin_xor(temp, ctx->frameKeyNext, CIPURSE_AES_KEY_LENGTH); + memcpy(ctx->frameKey, ctx->frameKeyNext, CIPURSE_AES_KEY_LENGTH); if (mac != NULL) memcpy(mac, temp, CIPURSE_MAC_LENGTH); } @@ -354,7 +355,7 @@ void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu, break; case CPSPlain: CipurseCAPDUMACEncode(ctx, dstapdu, buf, &buflen); - CipurseCCalcMACPadded(ctx, buf, buflen, mac); + CipurseCCalcMACPadded(ctx, buf, buflen, NULL); break; case CPSMACed: dstapdu->Lc += CIPURSE_MAC_LENGTH; @@ -371,6 +372,9 @@ void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu, } void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdatalen, uint8_t *dstdata, size_t *dstdatalen, uint16_t *sw) { + uint8_t buf[260] = {0}; + size_t buflen = 0; + if (dstdatalen != NULL) *dstdatalen = 0; if (sw != NULL) @@ -395,6 +399,12 @@ void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdat case CPSNone: break; case CPSPlain: + memcpy(buf, srcdata, srcdatalen); + buflen = srcdatalen; + memcpy(&buf[buflen], &srcdata[srcdatalen], 2); + buflen += 2; + CipurseCCalcMACPadded(ctx, buf, buflen, NULL); + memcpy(dstdata, srcdata, srcdatalen); if (dstdatalen != NULL) *dstdatalen = srcdatalen; @@ -402,8 +412,14 @@ void CipurseCAPDURespDecode(CipurseContext *ctx, uint8_t *srcdata, size_t srcdat case CPSMACed: if (srcdatalen < CIPURSE_MAC_LENGTH) return; + + buflen = srcdatalen - CIPURSE_MAC_LENGTH; + memcpy(buf, srcdata, buflen); + memcpy(&buf[buflen], &srcdata[srcdatalen], 2); + buflen += 2; + srcdatalen -= CIPURSE_MAC_LENGTH; - if (CipurseCCheckMACPadded(ctx, srcdata, srcdatalen, &srcdata[srcdatalen]) == false) { + if (CipurseCCheckMACPadded(ctx, buf, buflen, &srcdata[srcdatalen]) == false) { PrintAndLogEx(WARNING, "APDU MAC is not valid!"); } memcpy(dstdata, srcdata, srcdatalen); diff --git a/client/src/cmdhfcipurse.c b/client/src/cmdhfcipurse.c index a8942df5e..b5be78a3a 100644 --- a/client/src/cmdhfcipurse.c +++ b/client/src/cmdhfcipurse.c @@ -246,6 +246,7 @@ static int CmdHFCipurseReadFile(const char *Cmd) { DropField(); return PM3_ESOFT; } +//CIPURSECSetActChannelSecurityLevels(CPSMACed, CPSMACed); if (verbose) PrintAndLogEx(INFO, "Select file 0x%x " _GREEN_("OK"), fileId);