diff --git a/client/src/cipurse/cipursecore.c b/client/src/cipurse/cipursecore.c index 45c276f2c..553e5ba68 100644 --- a/client/src/cipurse/cipursecore.c +++ b/client/src/cipurse/cipursecore.c @@ -21,6 +21,9 @@ #include "util.h" #include "cipurse/cipursecrypto.h" +// context for secure channel +CipurseContext cipurseContext; + static int CIPURSEExchangeEx(bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool IncludeLe, uint16_t Le, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { uint8_t data[APDU_RES_LEN] = {0}; @@ -84,6 +87,7 @@ static int CIPURSEExchangeEx(bool ActivateField, bool LeaveFieldON, sAPDU apdu, int CIPURSESelect(bool ActivateField, bool LeaveFieldON, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) { uint8_t data[] = {0x41, 0x44, 0x20, 0x46, 0x31}; + CipurseCClearContext(&cipurseContext); return EMVSelect(ECC_CONTACTLESS, ActivateField, LeaveFieldON, data, sizeof(data), Result, MaxResultLen, ResultLen, sw, NULL); } diff --git a/client/src/cipurse/cipursecrypto.c b/client/src/cipurse/cipursecrypto.c index 14dd8c3a5..29cdc994c 100644 --- a/client/src/cipurse/cipursecrypto.c +++ b/client/src/cipurse/cipursecrypto.c @@ -184,3 +184,28 @@ void CipurseCAuthenticateHost(CipurseContext *ctx, uint8_t *authdata) { bool CipurseCCheckCT(CipurseContext *ctx, uint8_t *CT) { return (memcmp(CT, ctx->CT, CIPURSE_AES_KEY_LENGTH) == 0); } + +void AddISO9797M2Padding(uint8_t *ddata, size_t *ddatalen, uint8_t *sdata, size_t sdatalen, size_t blocklen) { + *ddatalen = sdatalen + 1; + *ddatalen += *ddatalen % blocklen; + memset(ddata, 0, *ddatalen); + memcpy(ddata, sdata, sdatalen); + ddata[sdatalen] = ISO9797_M2_PAD_BYTE; +} + +void CipurseCGenerateMAC(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac) { + +} + +void CipurseCCalcMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac) { + uint8_t pdata[datalen + CIPURSE_AES_KEY_LENGTH]; + size_t pdatalen = 0; + AddISO9797M2Padding(pdata, &pdatalen, data, datalen, CIPURSE_AES_KEY_LENGTH); + CipurseCGenerateMAC(ctx, pdata, pdatalen, mac); +} + +bool CipurseCCheckMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac) { + uint8_t xmac[CIPURSE_MAC_LENGTH] = {0}; + CipurseCCalcMACPadded(ctx, data, datalen, xmac); + return (memcmp(mac, xmac, CIPURSE_MAC_LENGTH) == 0); +} diff --git a/client/src/cipurse/cipursecrypto.h b/client/src/cipurse/cipursecrypto.h index ca1ed29f3..c7fdc57e4 100644 --- a/client/src/cipurse/cipursecrypto.h +++ b/client/src/cipurse/cipursecrypto.h @@ -16,8 +16,9 @@ #define CIPURSE_KVV_LENGTH 4 #define CIPURSE_AES_KEY_LENGTH 16 #define CIPURSE_SECURITY_PARAM_N 6 -#define OSPT_MAC_LENGTH 8 +#define CIPURSE_MAC_LENGTH 8 #define CIPURSE_POLY 0x35b088cce172UL +#define ISO9797_M2_PAD_BYTE 0x80 #define member_size(type, member) sizeof(((type *)0)->member) @@ -53,6 +54,11 @@ void CipurseCSetRandomHost(CipurseContext *ctx); void CipurseCAuthenticateHost(CipurseContext *ctx, uint8_t *authdata); bool CipurseCCheckCT(CipurseContext *ctx, uint8_t *CT); +void AddISO9797M2Padding(uint8_t *ddata, size_t *ddatalen, uint8_t *sdata, size_t sdatalen, size_t blocklen); + +void CipurseCGenerateMAC(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac); +void CipurseCCalcMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac); +bool CipurseCCheckMACPadded(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *mac); void CipurseCGetKVV(uint8_t *key, uint8_t *kvv);