encoding works

This commit is contained in:
merlokk 2021-06-03 14:39:15 +03:00
commit 737ff2d465
3 changed files with 27 additions and 11 deletions

View file

@ -73,6 +73,7 @@ static int CIPURSEExchangeEx(bool ActivateField, bool LeaveFieldON, sAPDU apdu,
size_t rlen = 0; size_t rlen = 0;
if (*ResultLen == 2) { if (*ResultLen == 2) {
if (cipurseContext.RequestSecurity == CPSMACed || cipurseContext.RequestSecurity == CPSEncrypted)
CipurseCClearContext(&cipurseContext); CipurseCClearContext(&cipurseContext);
isw = Result[0] * 0x0100 + Result[1]; isw = Result[0] * 0x0100 + Result[1];
@ -178,9 +179,7 @@ bool CIPURSEChannelAuthenticate(uint8_t keyIndex, uint8_t *key, bool verbose) {
if (verbose) if (verbose)
PrintAndLogEx(INFO, "Authentication " _GREEN_("OK")); PrintAndLogEx(INFO, "Authentication " _GREEN_("OK"));
//CipurseCChannelSetSecurityLevels(&cpc, CPSEncrypted, CPSEncrypted);
CipurseCChannelSetSecurityLevels(&cpc, CPSMACed, CPSMACed); CipurseCChannelSetSecurityLevels(&cpc, CPSMACed, CPSMACed);
//CipurseCChannelSetSecurityLevels(&cpc, CPSPlain, CPSPlain);
memcpy(&cipurseContext, &cpc, sizeof(CipurseContext)); memcpy(&cipurseContext, &cpc, sizeof(CipurseContext));
return true; return true;
} else { } else {

View file

@ -292,7 +292,10 @@ bool CipurseCCheckMIC(uint8_t *data, size_t datalen, uint8_t *mic) {
*/ */
void CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt) { void CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt) {
uint8_t hx[CIPURSE_AES_KEY_LENGTH] = {0}; uint8_t hx[CIPURSE_AES_KEY_LENGTH] = {0};
PrintAndLogEx(INFO, "----data[%d]: %s", datalen, sprint_hex(data, datalen));
if (datalen == 0 || datalen % CIPURSE_AES_KEY_LENGTH != 0)
return;
memcpy(ctx->frameKeyNext, ctx->frameKey, CIPURSE_AES_KEY_LENGTH); memcpy(ctx->frameKeyNext, ctx->frameKey, CIPURSE_AES_KEY_LENGTH);
int i = 0; int i = 0;
while (datalen > i) { while (datalen > i) {
@ -367,7 +370,7 @@ bool CipurseCCheckMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen,
return (memcmp(mac, xmac, CIPURSE_MAC_LENGTH) == 0); return (memcmp(mac, xmac, CIPURSE_MAC_LENGTH) == 0);
} }
static void CipurseCAPDUMACEncode(CipurseContext *ctx, sAPDU *apdu, uint8_t *data, size_t *datalen) { static void CipurseCAPDUMACEncode(CipurseContext *ctx, sAPDU *apdu, uint8_t originalLc, uint8_t *data, size_t *datalen) {
data[0] = apdu->CLA; data[0] = apdu->CLA;
data[1] = apdu->INS; data[1] = apdu->INS;
data[2] = apdu->P1; data[2] = apdu->P1;
@ -375,8 +378,8 @@ static void CipurseCAPDUMACEncode(CipurseContext *ctx, sAPDU *apdu, uint8_t *dat
data[4] = apdu->Lc; data[4] = apdu->Lc;
*datalen = 5 + apdu->Lc; *datalen = 5 + apdu->Lc;
if (ctx->RequestSecurity == CPSMACed) if (ctx->RequestSecurity == CPSMACed || ctx->RequestSecurity == CPSEncrypted)
*datalen -= CIPURSE_MAC_LENGTH; *datalen = 5 + originalLc;
memcpy(&data[5], apdu->data, *datalen); memcpy(&data[5], apdu->data, *datalen);
} }
@ -399,24 +402,37 @@ void CipurseCAPDUReqEncode(CipurseContext *ctx, sAPDU *srcapdu, sAPDU *dstapdu,
dstapdu->data[dstapdu->Lc] = Le; dstapdu->data[dstapdu->Lc] = Le;
dstapdu->Lc++; dstapdu->Lc++;
} }
uint8_t originalLc = dstapdu->Lc;
switch (ctx->RequestSecurity) { switch (ctx->RequestSecurity) {
case CPSNone: case CPSNone:
break; break;
case CPSPlain: case CPSPlain:
CipurseCAPDUMACEncode(ctx, dstapdu, buf, &buflen); CipurseCAPDUMACEncode(ctx, dstapdu, originalLc, buf, &buflen);
CipurseCCalcMACPadded(ctx, buf, buflen, NULL); CipurseCCalcMACPadded(ctx, buf, buflen, NULL);
break; break;
case CPSMACed: case CPSMACed:
dstapdu->Lc += CIPURSE_MAC_LENGTH; dstapdu->Lc += CIPURSE_MAC_LENGTH;
CipurseCAPDUMACEncode(ctx, dstapdu, buf, &buflen); CipurseCAPDUMACEncode(ctx, dstapdu, originalLc, buf, &buflen);
CipurseCCalcMACPadded(ctx, buf, buflen, mac); CipurseCCalcMACPadded(ctx, buf, buflen, mac);
memcpy(&dstdatabuf[dstapdu->Lc - CIPURSE_MAC_LENGTH], mac, CIPURSE_MAC_LENGTH); memcpy(&dstdatabuf[dstapdu->Lc - CIPURSE_MAC_LENGTH], mac, CIPURSE_MAC_LENGTH);
break; break;
case CPSEncrypted: case CPSEncrypted:
CipurseCAPDUMACEncode(ctx, dstapdu, buf, &buflen); dstapdu->Lc = srcapdu->Lc + CIPURSE_MIC_LENGTH;
dstapdu->Lc += CIPURSE_AES_BLOCK_LENGTH - dstapdu->Lc % CIPURSE_AES_BLOCK_LENGTH + 1; // 1 - SMI
if (includeLe)
dstapdu->Lc++;
CipurseCAPDUMACEncode(ctx, dstapdu, originalLc, buf, &buflen);
CipurseCGenerateMIC(buf, buflen, mac); CipurseCGenerateMIC(buf, buflen, mac);
PrintAndLogEx(INFO, "mic: %s", sprint_hex(mac, 4)); buf[0] = dstapdu->CLA;
buf[1] = dstapdu->INS;
buf[2] = dstapdu->P1;
buf[3] = dstapdu->P2;
memcpy(&buf[4], srcapdu->data, srcapdu->Lc);
memcpy(&buf[4 + srcapdu->Lc], mac, CIPURSE_MIC_LENGTH);
//PrintAndLogEx(INFO, "data plain[%d]: %s", 4 + srcapdu->Lc + CIPURSE_MIC_LENGTH, sprint_hex(buf, 4 + srcapdu->Lc + CIPURSE_MIC_LENGTH));
CipurseCChannelEncrypt(ctx, buf, 4 + srcapdu->Lc + CIPURSE_MIC_LENGTH, &dstdatabuf[1], &buflen);
break; break;
default: default:
break; break;

View file

@ -16,6 +16,7 @@
#define CIPURSE_KVV_LENGTH 4 #define CIPURSE_KVV_LENGTH 4
#define CIPURSE_AES_KEY_LENGTH 16 #define CIPURSE_AES_KEY_LENGTH 16
#define CIPURSE_AES_BLOCK_LENGTH 16
#define CIPURSE_SECURITY_PARAM_N 6 #define CIPURSE_SECURITY_PARAM_N 6
#define CIPURSE_MAC_LENGTH 8 #define CIPURSE_MAC_LENGTH 8
#define CIPURSE_MIC_LENGTH 4 #define CIPURSE_MIC_LENGTH 4