-
Notifications
You must be signed in to change notification settings - Fork 399
Expand file tree
/
Copy pathCryptoTDEA.h
More file actions
143 lines (116 loc) · 6.42 KB
/
Copy pathCryptoTDEA.h
File metadata and controls
143 lines (116 loc) · 6.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
* CryptoDES.h
*
* Created on: 18.10.2016
* Author: dev_zzo
*/
#ifndef CRYPTODES_H_
#define CRYPTODES_H_
#include <stdint.h>
#include "../Common.h"
/* Notes on cryptography in DESFire cards
The EV0 was the first chip in the DESFire series. It makes use of the TDEA
encryption to secure the comms. It also employs CBC to make things more secure.
CBC is used in two "modes": "send mode" and "receive mode".
- Sending data uses the same structure as conventional encryption with CBC
(XOR with the IV then apply block cipher)
- Receiving data uses the same structure as conventional decryption with CBC
(apply block cipher then XOR with the IV)
Both operations employ TDEA encryption on the PICC's side and decryption on
PCD's side.
*/
/* DES Operation cipher modes */
#define CRYPTO_DES_ECB_MODE 0 // Electronic Code Book mode (ECB mode)
#define CRYPTO_DES_CBC_MODE 1 // Cipher Block Chaining mode (CBC mode)
extern uint8_t __CryptoDESOpMode;
/* Key sizes, in bytes */
#define CRYPTO_DES_KEY_SIZE (8)
#define CRYPTO_2KTDEA_KEY_SIZE (2 * CRYPTO_DES_KEY_SIZE)
#define CRYPTO_3KTDEA_KEY_SIZE (3 * CRYPTO_DES_KEY_SIZE)
typedef uint8_t Crypto2KTDEAKeyType[CRYPTO_2KTDEA_KEY_SIZE];
typedef uint8_t Crypto3KTDEAKeyType[CRYPTO_3KTDEA_KEY_SIZE];
#define CRYPTO_DES_BLOCK_SIZE (8)
#define CRYPTO_2KTDEA_BLOCK_SIZE (CRYPTO_DES_BLOCK_SIZE)
#define CRYPTO_3KTDEA_BLOCK_SIZE (CRYPTO_DES_BLOCK_SIZE)
/* Error and status codes */
#define CRYPTO_TDEA_EXIT_SUCCESS 0
#define CRYPTO_TDEA_EXIT_UNEVEN_BLOCKS 1
/* Prototype the CBC function pointer in case anyone needs it */
typedef void (*CryptoTDEACBCFuncType)(uint16_t Count, const void *Plaintext, void *Ciphertext, void *IV, const uint8_t *Keys);
typedef void (*CryptoTDEAFuncType)(void *PlainText, void *Ciphertext, const uint8_t *Keys);
void CryptoEncryptDES(void *Plaintext, void *Ciphertext, const uint8_t *Keys);
void CryptoDecryptDES(void *Plaintext, void *Ciphertext, const uint8_t *Keys);
int EncryptDESBuffer(uint16_t Count, const void *Plaintext, void *Ciphertext, const uint8_t *IV, const uint8_t *Keys);
int DecryptDESBuffer(uint16_t Count, void *Plaintext, const void *Ciphertext, const uint8_t *IV, const uint8_t *Keys);
/** Performs the Triple DEA enciphering in ECB mode (single block)
*
* \param Plaintext Source buffer with plaintext
* \param Ciphertext Destination buffer to contain ciphertext
* \param Keys Key block pointer (CRYPTO_2KTDEA_KEY_SIZE)
*/
void CryptoEncrypt2KTDEA(void *Plaintext, void *Ciphertext, const uint8_t *Keys);
void CryptoDecrypt2KTDEA(void *Plaintext, void *Ciphertext, const uint8_t *Keys);
int Encrypt2K3DESBuffer(uint16_t Count, const void *Plaintext, void *Ciphertext, const uint8_t *IV, const uint8_t *Keys);
int Decrypt2K3DESBuffer(uint16_t Count, void *Plaintext, const void *Ciphertext, const uint8_t *IV, const uint8_t *Keys);
void CryptoEncrypt3KTDEA(void *Plaintext, void *Ciphertext, const uint8_t *Keys);
void CryptoDecrypt3KTDEA(void *Plaintext, void *Ciphertext, const uint8_t *Keys);
int Encrypt3DESBuffer(uint16_t Count, const void *Plaintext, void *Ciphertext, const uint8_t *IV, const uint8_t *Keys);
int Decrypt3DESBuffer(uint16_t Count, void *Plaintext, const void *Ciphertext, const uint8_t *IV, const uint8_t *Keys);
/** Performs the 2-key Triple DES en/deciphering in the CBC "send" mode (xor-then-crypt)
*
* \param Count Block count, expected to be >= 1
* \param Plaintext Source buffer with plaintext
* \param Ciphertext Destination buffer to contain ciphertext
* \param IV Initialization vector buffer, will be updated
* \param Keys Key block pointer (CRYPTO_2KTDEA_KEY_SIZE)
*/
void CryptoEncrypt2KTDEA_CBCSend(uint16_t Count, const void *Input, void *Output, void *IV, const uint8_t *Keys);
void CryptoDecrypt2KTDEA_CBCSend(uint16_t Count, const void *Input, void *Output, void *IV, const uint8_t *Keys);
/** Performs the 2-key Triple DES en/deciphering in the CBC "receive" mode (crypt-then-xor)
*
* \param Count Block count, expected to be >= 1
* \param Plaintext Source buffer with plaintext
* \param Ciphertext Destination buffer to contain ciphertext
* \param IV Initialization vector buffer, will be updated
* \param Keys Key block pointer (CRYPTO_2KTDEA_KEY_SIZE)
*/
void CryptoEncrypt2KTDEA_CBCReceive(uint16_t Count, const void *Input, void *Output, void *IV, const uint8_t *Keys);
void CryptoDecrypt2KTDEA_CBCReceive(uint16_t Count, const void *Input, void *Output, void *IV, const uint8_t *Keys);
#ifdef ENABLE_CRYPTO_TESTS
/** Performs the 3-key Triple DES en/deciphering in the CBC "send" or "receive" mode
*
* \param Count Block count, expected to be >= 1
* \param Plaintext Source buffer with plaintext
* \param Ciphertext Destination buffer to contain ciphertext
* \param IV Initialization vector buffer, will be updated
* \param Keys Key block pointer (CRYPTO_3KTDEA_KEY_SIZE)
*/
void CryptoEncrypt3KTDEA_CBCSend(uint16_t Count, const void *Plaintext, void *Ciphertext, void *IV, const uint8_t *Keys);
void CryptoDecrypt3KTDEA_CBCReceive(uint16_t Count, const void *Plaintext, void *Ciphertext, void *IV, const uint8_t *Keys);
#endif
/* Spec for more generic send/recv encrypt/decrypt schemes: */
typedef struct {
CryptoTDEAFuncType cryptFunc;
uint16_t blockSize;
} CryptoTDEA_CBCSpec;
void CryptoTDEA_CBCSend(uint16_t Count, void *Plaintext, void *Ciphertext,
void *IV, const uint8_t *Keys, CryptoTDEA_CBCSpec CryptoSpec);
void CryptoTDEA_CBCRecv(uint16_t Count, void *Plaintext, void *Ciphertext,
void *IV, const uint8_t *Keys, CryptoTDEA_CBCSpec CryptoSpec);
uint8_t TransferEncryptTDEASend(uint8_t *Buffer, uint8_t Count);
uint8_t TransferEncryptTDEAReceive(uint8_t *Buffer, uint8_t Count);
/** Applies padding to the data within the buffer
*
* \param Buffer Data buffer to pad
* \param BytesInBuffer How much data there is in the buffer already
* \param FirstPaddingBitSet Whether the very first bit (MSB) will be set or not
*/
INLINE void CryptoPaddingTDEA(uint8_t *Buffer, uint8_t BytesInBuffer, bool FirstPaddingBitSet) {
uint8_t PaddingByte = FirstPaddingBitSet << 7;
uint8_t i;
for (i = BytesInBuffer; i < CRYPTO_DES_BLOCK_SIZE; ++i) {
Buffer[i] = PaddingByte;
PaddingByte = 0x00;
}
}
#endif /* CRYPTODES_H_ */