mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-20 03:48:33 +08:00
add mac/encrypt primitives
This commit is contained in:
parent
413c5ec340
commit
283f065bc8
2 changed files with 58 additions and 1 deletions
|
@ -23,6 +23,7 @@
|
|||
#include "util.h"
|
||||
|
||||
uint8_t AESData0[CIPURSE_AES_KEY_LENGTH] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
uint8_t QConstant[CIPURSE_AES_KEY_LENGTH] = {0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73};
|
||||
|
||||
static void bin_xor(uint8_t *d1, uint8_t *d2, size_t len) {
|
||||
for(size_t i = 0; i < len; i++)
|
||||
|
@ -194,6 +195,59 @@ void AddISO9797M2Padding(uint8_t *ddata, size_t *ddatalen, uint8_t *sdata, size_
|
|||
ddata[sdatalen] = ISO9797_M2_PAD_BYTE;
|
||||
}
|
||||
|
||||
size_t FindISO9797M2PaddingDataLen(uint8_t *data, size_t datalen) {
|
||||
for (int i = datalen; i > 0; i--) {
|
||||
if (data[i - 1] == 0x80)
|
||||
return i;
|
||||
if (data[i - 1] != 0x00)
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* from: https://github.com/duychuongvn/cipurse-card-core/blob/master/src/main/java/com/github/duychuongvn/cirpusecard/core/security/crypto/CipurseCrypto.java#L521
|
||||
*
|
||||
* Encrypt/Decrypt the given data using ciphering mechanism explained the OPST.
|
||||
* Data should be already padded.
|
||||
*
|
||||
* hx-1 := ki , hx := AES( key = hx-1 ; q) XOR q, Cx := AES( key = hx ;
|
||||
* Dx ), hx+1 := AES( key = hx ; q ) XOR q, Cx+1 := AES( key = hx+1 ;
|
||||
* Dx+1 ), ... hy := AES( key = hy-1 ; q ) XOR q, Cy := AES( key = hy ;
|
||||
* Dy ), ki+1 := hy
|
||||
*/
|
||||
void CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt) {
|
||||
uint8_t hx[CIPURSE_AES_KEY_LENGTH] = {0};
|
||||
|
||||
memcpy(ctx->frameKeyNext, ctx->frameKey, CIPURSE_AES_KEY_LENGTH);
|
||||
int i = 0;
|
||||
while (datalen > i) {
|
||||
aes_encode(NULL, QConstant, ctx->frameKeyNext, hx, CIPURSE_AES_KEY_LENGTH);
|
||||
bin_xor(hx, ctx->frameKeyNext, CIPURSE_AES_KEY_LENGTH);
|
||||
|
||||
if (isEncrypt)
|
||||
aes_encode(NULL, hx, &data[i], &dstdata[i], CIPURSE_AES_KEY_LENGTH);
|
||||
else
|
||||
aes_decode(NULL, hx, &data[i], &dstdata[i], CIPURSE_AES_KEY_LENGTH);
|
||||
|
||||
memcpy(ctx->frameKeyNext, hx, CIPURSE_AES_KEY_LENGTH);
|
||||
i += CIPURSE_AES_KEY_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
void CipurseCChannelEncrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen) {
|
||||
uint8_t pdata[datalen + CIPURSE_AES_KEY_LENGTH];
|
||||
size_t pdatalen = 0;
|
||||
AddISO9797M2Padding(pdata, &pdatalen, data, datalen, CIPURSE_AES_KEY_LENGTH);
|
||||
|
||||
CipurseCEncryptDecrypt(ctx, pdata, pdatalen, encdata, true);
|
||||
*encdatalen = pdatalen;
|
||||
}
|
||||
|
||||
void CipurseCChannelDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *plaindata, size_t *plaindatalen) {
|
||||
CipurseCEncryptDecrypt(ctx, data, datalen, plaindata, false);
|
||||
*plaindatalen = FindISO9797M2PaddingDataLen(plaindata, datalen);
|
||||
}
|
||||
|
||||
/* from: https://github.com/duychuongvn/cipurse-card-core/blob/master/src/main/java/com/github/duychuongvn/cirpusecard/core/security/crypto/CipurseCrypto.java#L473
|
||||
*
|
||||
* Generate OSPT MAC on the given input data.
|
||||
|
|
|
@ -55,11 +55,14 @@ 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);
|
||||
size_t FindISO9797M2PaddingDataLen(uint8_t *data, size_t datalen);
|
||||
|
||||
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 CipurseCEncryptDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *dstdata, bool isEncrypt);
|
||||
void CipurseCChannelEncrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *encdata, size_t *encdatalen);
|
||||
void CipurseCChannelDecrypt(CipurseContext *ctx, uint8_t *data, size_t datalen, uint8_t *plaindata, size_t *plaindatalen);
|
||||
void CipurseCGetKVV(uint8_t *key, uint8_t *kvv);
|
||||
|
||||
#endif /* __CIPURSECRYPTO_H__ */
|
||||
|
|
Loading…
Add table
Reference in a new issue