1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2021 Merlok
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // CIPURSE crypto primitives
9 //-----------------------------------------------------------------------------
11 #ifndef __CIPURSECRYPTO_H__
12 #define __CIPURSECRYPTO_H__
15 #include "iso7816/apduinfo.h" // sAPDU
17 #define CIPURSE_KVV_LENGTH 4
18 #define CIPURSE_AES_KEY_LENGTH 16
19 #define CIPURSE_AES_BLOCK_LENGTH 16
20 #define CIPURSE_SECURITY_PARAM_N 6
21 #define CIPURSE_MAC_LENGTH 8
22 #define CIPURSE_MIC_LENGTH 4
23 #define CIPURSE_POLY 0x35b088cce172UL
24 #define ISO9797_M2_PAD_BYTE 0x80
26 #define member_size(type, member) sizeof(((type *)0)->member)
33 } CipurseChannelSecurityLevel
;
35 typedef struct CipurseContextS
{
37 uint8_t key
[CIPURSE_AES_KEY_LENGTH
];
39 uint8_t RP
[CIPURSE_AES_KEY_LENGTH
];
40 uint8_t rP
[CIPURSE_SECURITY_PARAM_N
];
41 uint8_t RT
[CIPURSE_AES_KEY_LENGTH
];
42 uint8_t rT
[CIPURSE_SECURITY_PARAM_N
];
44 uint8_t k0
[CIPURSE_AES_KEY_LENGTH
];
45 uint8_t cP
[CIPURSE_AES_KEY_LENGTH
];
46 uint8_t CT
[CIPURSE_AES_KEY_LENGTH
];
48 uint8_t frameKey
[CIPURSE_AES_KEY_LENGTH
];
49 uint8_t frameKeyNext
[CIPURSE_AES_KEY_LENGTH
];
51 CipurseChannelSecurityLevel RequestSecurity
;
52 CipurseChannelSecurityLevel ResponseSecurity
;
55 uint8_t CipurseCSecurityLevelEnc(CipurseChannelSecurityLevel lvl
);
57 void CipurseCClearContext(CipurseContext
*ctx
);
58 void CipurseCSetKey(CipurseContext
*ctx
, uint8_t keyId
, uint8_t *key
);
59 void CipurseCSetRandomFromPICC(CipurseContext
*ctx
, uint8_t *random
);
60 void CipurseCSetRandomHost(CipurseContext
*ctx
);
61 uint8_t CipurseCGetSMI(CipurseContext
*ctx
, bool LePresent
);
63 void CipurseCAuthenticateHost(CipurseContext
*ctx
, uint8_t *authdata
);
64 bool CipurseCCheckCT(CipurseContext
*ctx
, uint8_t *CT
);
66 void CipurseCChannelSetSecurityLevels(CipurseContext
*ctx
, CipurseChannelSecurityLevel req
, CipurseChannelSecurityLevel resp
);
67 bool isCipurseCChannelSecuritySet(CipurseContext
*ctx
);
69 void AddISO9797M2Padding(uint8_t *ddata
, size_t *ddatalen
, uint8_t *sdata
, size_t sdatalen
, size_t blocklen
);
70 size_t FindISO9797M2PaddingDataLen(uint8_t *data
, size_t datalen
);
72 void CipurseCGenerateMAC(CipurseContext
*ctx
, uint8_t *data
, size_t datalen
, uint8_t *mac
);
73 void CipurseCCalcMACPadded(CipurseContext
*ctx
, uint8_t *data
, size_t datalen
, uint8_t *mac
);
74 bool CipurseCCheckMACPadded(CipurseContext
*ctx
, uint8_t *data
, size_t datalen
, uint8_t *mac
);
75 void CipurseCGenerateMIC(uint8_t *data
, size_t datalen
, uint8_t *mic
);
76 bool CipurseCCheckMIC(uint8_t *data
, size_t datalen
, uint8_t *mic
);
77 void CipurseCEncryptDecrypt(CipurseContext
*ctx
, uint8_t *data
, size_t datalen
, uint8_t *dstdata
, bool isEncrypt
);
78 void CipurseCChannelEncrypt(CipurseContext
*ctx
, uint8_t *data
, size_t datalen
, uint8_t *encdata
, size_t *encdatalen
);
79 void CipurseCChannelDecrypt(CipurseContext
*ctx
, uint8_t *data
, size_t datalen
, uint8_t *plaindata
, size_t *plaindatalen
);
80 void CipurseCGetKVV(uint8_t *key
, uint8_t *kvv
);
82 void CipurseCAPDUReqEncode(CipurseContext
*ctx
, sAPDU
*srcapdu
, sAPDU
*dstapdu
, uint8_t *dstdatabuf
, bool includeLe
, uint8_t Le
);
83 void CipurseCAPDURespDecode(CipurseContext
*ctx
, uint8_t *srcdata
, size_t srcdatalen
, uint8_t *dstdata
, size_t *dstdatalen
, uint16_t *sw
);
86 #endif /* __CIPURSECRYPTO_H__ */