Skip to content

Commit 306865e

Browse files
committed
New DF_ENCMODE command to set ECB/CBC crypto modes ; Incremental changes to LibNFC test code ; Incomplete docs to edit elsewhere
1 parent 3a89c4b commit 306865e

File tree

11 files changed

+132
-23
lines changed

11 files changed

+132
-23
lines changed

Doc/DESFireSupportReadme.md

+51-2
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,23 @@ DESFire emulation if things suddenly fail after a call to this terminal command.
221221
Putting the Chameleon through a full power recycle (battery off) should reset the setting
222222
to the defaults.
223223

224+
#### DF_COMM_MODE -- Manually sets the communication mode of the current session
225+
226+
This commanf sets the encryption mode for cryptographic operations.
227+
The two supported modes are ECB and CBC.
228+
The default mode for AES and DES (all types) of encryption is ECB mode.
229+
This is the supported mode for DESFire tags using the latest Proxmark3 software.
230+
231+
The syntax is demonstrated by the following examples:
232+
```bash
233+
DF_ENCMODE=ECB
234+
DF_ENCMODE=DES:ECB
235+
DF_ENCMODE=AES:ECB
236+
DF_ENCMODE=CBC
237+
DF_ENCMODE=DES:CBC
238+
DF_ENCMODE=AES:CBC
239+
```
240+
224241
## Supported functionality
225242

226243
### Tables of tested support for active commands
@@ -283,6 +300,33 @@ to the defaults.
283300
| CMD_ISO7816_READ_RECORDS | 0xb2 | | :wavy_dash: :question: | Needs testing. |
284301
| CMD_ISO7816_APPEND_RECORD | 0xe2 | | :wavy_dash: :question: | Especially needs testing for corner case checks. |
285302

303+
### Proxmark3 (PM3) compatibility and support
304+
305+
The next PM3 commands are known to work with the Chameleon DESFire tag emulation (using both the RDV4 and Easy device types).
306+
The sample outputs obtained running the ``pm3`` command line utility below may vary by usage and proximity to the PM3 hardware.
307+
308+
#### Getting a summary of tag information
309+
310+
```bash
311+
TODO
312+
```
313+
314+
#### ISODES authentication with the PICC and PICC master key
315+
316+
```bash
317+
TODO
318+
```
319+
320+
### Compatibility with external USB readers and LibNFC
321+
322+
The DESFire configurations are known to work with the anticollision and RATS handshaking utility ``nfc-anticol`` from LibNFC.
323+
The Mifare DESFire commands installed by LibFreeFare have not been tested nor confirmed to work with the Chameleon Mini.
324+
The developers are actively working to ensure compatibility of the Chameleon DESFire emulation with external USB readers used
325+
running ``pcscd`` and ``pcsc_spy``. This support is not yet functional with tests using ACR-122 and HID Omnikey 5022CL readers.
326+
The DESFire support for the Chameleon Mini is tested with the LibNFC-based source code
327+
[developed in this directory]() with
328+
[sample dumps and output here]().
329+
286330
### Links to public datasheets and online specs
287331

288332
The following links are the original online resource links are
@@ -342,12 +386,17 @@ repositories and code bases:
342386

343387
## New development sources of DESFire support for the Chameleon Mini
344388

345-
David Oswald has added a [DESFire emulation project](https://github.com/orgs/emsec/projects?type=classic) to organize tasks in progress for DESFire emulation support on the Chameleon Mini. The [original development sources](https://github.com/maxieds/ChameleonMiniDESFireStack/releases) are now archived and not kept up to date. Development sources for pull request projects in progress by **@maxieds** are [located here](https://github.com/maxieds/ChameleonMini). For example, a newer branch can be built by running
389+
David Oswald has added a [DESFire emulation project](https://github.com/orgs/emsec/projects?type=classic) to organize tasks in
390+
progress for DESFire emulation support on the Chameleon Mini. The
391+
[original development sources](https://github.com/maxieds/ChameleonMiniDESFireStack/releases) are now archived and
392+
not kept up to date with the latest firmware pull requests and development sources. There are development sources for pull request projects in
393+
progress written by **@maxieds** are [located here](https://github.com/maxieds/ChameleonMini).
394+
For example, a newer branch can be built by running
346395
```bash
347396
$ git clone https://github.com/maxieds/ChameleonMini.git
348397
$ cd ChameleonMini
349398
$ git checkout DESFireNFCExternalUSBReaderPatches-LibNFCTestCode
350399
$ cd Firmware/ChameleonMini
351400
$ make desfire-dev
352401
```
353-
Other GitHub users are developing mods of the emsec firmware sources for projects such as Mifare DESFire Plus support elsewhere.
402+
Other GitHub users are developing modifications of the main firmware sources for projects that include Mifare DESFire Plus support elsewhere.

Firmware/Chameleon-Mini/Application/CryptoAES128.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ static aes_callback_t __CryptoAESCallbackFunc = NULL;
4545
static CryptoAESBlock_t __CryptoAES_IVData = { 0 };
4646

4747
/* Set the last operation mode (ECB or CBC) init for the context */
48-
static uint8_t __CryptoAESOpMode = CRYPTO_AES_ECB_MODE;
48+
uint8_t __CryptoAESOpMode = CRYPTO_AES_ECB_MODE;
4949

5050
void aes_start(void) {
5151
AES.CTRL |= AES_START_bm;

Firmware/Chameleon-Mini/Application/CryptoAES128.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@
4646
#define CRYPTO_AES_KEY_SIZE_192 1 // 192-bit
4747
#define CRYPTO_AES_KEY_SIZE_256 2 // 256-bit
4848

49-
/* AES Operation cipher mode */
49+
/* AES Operation cipher modes */
5050
#define CRYPTO_AES_ECB_MODE 0 // Electronic Code Book mode
5151
#define CRYPTO_AES_CBC_MODE 1 // Cipher Block Chaining mode
52-
#define CRYPTO_AES_OFB_MODE 2 // Output FeedBack mode
53-
#define CRYPTO_AES_CFB_MODE 3 // Cipher FeedBack mode
54-
#define CRYPTO_AES_CTR_MODE 4 // Counter mode
52+
#define CRYPTO_AES_OFB_MODE 2 // Output FeedBack mode (NOT SUPPORTED)
53+
#define CRYPTO_AES_CFB_MODE 3 // Cipher FeedBack mode (NOT SUPPORTED)
54+
#define CRYPTO_AES_CTR_MODE 4 // Counter mode (NOT SUPPORTED)
55+
56+
extern uint8_t __CryptoAESOpMode;
5557

5658
/* AES URAD Type */
5759
#define CRYPTO_AES_URAT_INPUTWRITE_DMA 0 // Input Data Register written during the data processing in DMA mode

Firmware/Chameleon-Mini/Application/CryptoTDEA.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "CryptoAES128.h"
1010

1111
/* Set the last operation mode (ECB or CBC) init for the context */
12-
static uint8_t __CryptoDESOpMode = CRYPTO_DES_ECB_MODE;
12+
uint8_t __CryptoDESOpMode = CRYPTO_DES_ECB_MODE;
1313

1414
static void CryptoEncryptCBCBuffer(CryptoTDEA_CBCSpec *CryptoSpec, uint16_t Count, const void *Plaintext, void *Ciphertext, const uint8_t *IVIn, const uint8_t *Keys);
1515
static void CryptoEncryptCBCBuffer(CryptoTDEA_CBCSpec *CryptoSpec, uint16_t Count, const void *Plaintext, void *Ciphertext, const uint8_t *IVIn, const uint8_t *Keys) {

Firmware/Chameleon-Mini/Application/CryptoTDEA.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,12 @@ PCD's side.
2727
2828
*/
2929

30-
/* DES Operation cipher mode */
30+
/* DES Operation cipher modes */
3131
#define CRYPTO_DES_ECB_MODE 0 // Electronic Code Book mode
3232
#define CRYPTO_DES_CBC_MODE 1 // Cipher Block Chaining mode
3333

34+
extern uint8_t __CryptoDESOpMode;
35+
3436
/* Key sizes, in bytes */
3537
#define CRYPTO_DES_KEY_SIZE 8 /* Bytes */
3638
#define CRYPTO_2KTDEA_KEY_SIZE (CRYPTO_DES_KEY_SIZE * 2)

Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.c

+42
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,46 @@ CommandStatusIdType CommandDESFireSetCommMode(char *OutParam, const char *InPara
145145
return COMMAND_ERR_INVALID_USAGE_ID;
146146
}
147147

148+
CommandStatusIdType CommandDESFireSetEncryptionMode(char *OutParam, const char *InParams) {
149+
if (!IsDESFireConfiguration()) {
150+
return COMMAND_ERR_INVALID_USAGE_ID;
151+
}
152+
char valueStr[16];
153+
if (!sscanf_P(InParams, PSTR("%15s"), valueStr)) {
154+
return COMMAND_ERR_INVALID_PARAM_ID;
155+
}
156+
valueStr[15] = '\0';
157+
char *modeStartPos = strchr(valueStr, ':');
158+
bool setAESCryptoMode = true, setDESCryptoMode = true;
159+
bool ecbModeEnabled = true;
160+
if (modeStartPos == NULL) {
161+
modeStartPos = &valueStr;
162+
} else {
163+
uint8_t prefixLength = (uint8_t)(modeStartPos - valueStr);
164+
if (prefixLength == 0) {
165+
return COMMAND_ERR_INVALID_USAGE_ID;
166+
} else if (!strncasecmp_P(valueStr, PSTR("DES"), prefixLength)) {
167+
setAESCryptoMode = false;
168+
} else if (!strncasecmp_P(valueStr, PSTR("AES"), prefixLength)) {
169+
setDESCryptoMode = false;
170+
} else {
171+
return COMMAND_ERR_INVALID_USAGE_ID;
172+
}
173+
}
174+
if (!strcasecmp_P(modeStartPos, PSTR("ECB"))) {
175+
ecbModeEnabled = true;
176+
} else if (!strcasecmp_P(modeStartPos, PSTR("CBC"))) {
177+
ecbModeEnabled = false;
178+
} else {
179+
return COMMAND_ERR_INVALID_USAGE_ID;
180+
}
181+
if (setDESCryptoMode) {
182+
__CryptoDESOpMode = ecbModeEnabled ? CRYPTO_DES_ECB_MODE : CRYPTO_DES_CBC_MODE;
183+
}
184+
if (setAESCryptoMode) {
185+
__CryptoAESOpMode = ecbModeEnabled ? CRYPTO_AES_ECB_MODE : CRYPTO_AES_CBC_MODE;
186+
}
187+
return COMMAND_INFO_OK;
188+
}
189+
148190
#endif /* CONFIG_MF_DESFIRE_SUPPORT */

Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.h

+3
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ CommandStatusIdType CommandDESFireSetHeaderProperty(char *OutMessage, const char
4444
#define DFCOMMAND_COMM_MODE "DF_COMM_MODE"
4545
CommandStatusIdType CommandDESFireSetCommMode(char *OutMessage, const char *InParams);
4646

47+
#define DFCOMMAND_SET_ENCMODE "DF_ENCMODE"
48+
CommandStatusIdType CommandDESFireSetEncryptionMode(char *OutMessage, const char *InParams);
49+
4750
#endif /* DESFire Support */
4851

4952
#endif /* __DESFIRE_CHAMELEON_TERMINAL_H__ */

Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminalInclude.c

+6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ This notice must be retained at the top of all source files where indicated.
4040
.ExecParamFunc = NO_FUNCTION,
4141
.SetFunc = CommandDESFireSetCommMode,
4242
.GetFunc = NO_FUNCTION
43+
}, {
44+
.Command = DFCOMMAND_SET_ENCMODE,
45+
.ExecFunc = NO_FUNCTION,
46+
.ExecParamFunc = NO_FUNCTION,
47+
.SetFunc = CommandDESFireSetEncryptionMode,
48+
.GetFunc = NO_FUNCTION
4349
},
4450

4551
#endif

Firmware/Chameleon-Mini/BuildScripts/custom_build_targets.mk

+6-4
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ desfire: FLASH_DATA_SIZE:=0x$(FLASH_DATA_SIZE_CONST)
5656
desfire: FLASH_DATA_SIZE_UPPER_CONST:=20000
5757
desfire: FLASH_DATA_ADDR:=0x$(shell echo $$(( 0x$(FLASH_DATA_SIZE_UPPER_CONST) - 0x$(FLASH_DATA_SIZE_CONST) )) | xargs -0 printf %X)
5858
desfire: SUPPORTED_TAGS_BUILD:=-DCONFIG_MF_DESFIRE_SUPPORT
59-
desfire: EXTRA_CONFIG_SETTINGS:=-DDESFIRE_CRYPTO1_SAVE_SPACE \
59+
desfire: EXTRA_CONFIG_SETTINGS:=-DMEMORY_LIMITED_TESTING=1 \
60+
-DDESFIRE_CRYPTO1_SAVE_SPACE \
6061
-finline-small-functions
6162
desfire: TARGET_CUSTOM_BUILD_NAME:=DESFire
6263
desfire: CONFIG_SETTINGS:=$(SUPPORTED_TAGS_BUILD) -DDEFAULT_CONFIGURATION=CONFIG_NONE $(EXTRA_CONFIG_SETTINGS)
@@ -67,11 +68,12 @@ desfire-dev: FLASH_DATA_SIZE:=0x$(FLASH_DATA_SIZE_CONST)
6768
desfire-dev: FLASH_DATA_SIZE_UPPER_CONST:=20000
6869
desfire-dev: FLASH_DATA_ADDR:=0x$(shell echo $$(( 0x$(FLASH_DATA_SIZE_UPPER_CONST) - 0x$(FLASH_DATA_SIZE_CONST) )) | xargs -0 printf %X)
6970
desfire-dev: SUPPORTED_TAGS_BUILD:=-DCONFIG_MF_DESFIRE_SUPPORT
70-
desfire-dev: EXTRA_CONFIG_SETTINGS:=-DDESFIRE_CRYPTO1_SAVE_SPACE \
71-
-finline-small-functions \
71+
desfire-dev: EXTRA_CONFIG_SETTINGS:=-DMEMORY_LIMITED_TESTING=1 \
72+
-DDESFIRE_CRYPTO1_SAVE_SPACE \
7273
-DDESFIRE_MIN_OUTGOING_LOGSIZE=0 \
7374
-DDESFIRE_MIN_INCOMING_LOGSIZE=0 \
74-
-DDESFIRE_DEBUGGING=1
75+
-DDESFIRE_DEBUGGING=1 \
76+
-finline-small-functions
7577
desfire-dev: TARGET_CUSTOM_BUILD_NAME:=DESFire_DEV
7678
desfire-dev: CONFIG_SETTINGS:=$(SUPPORTED_TAGS_BUILD) -DDEFAULT_CONFIGURATION=CONFIG_NONE $(EXTRA_CONFIG_SETTINGS)
7779
desfire-dev: custom-build

Firmware/Chameleon-Mini/Log.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "Common.h"
55

66
#ifdef MEMORY_LIMITED_TESTING
7-
#define LOG_SIZE 1664 // 1024
7+
#define LOG_SIZE 1536
88
#else
99
#define LOG_SIZE 2048
1010
#endif

Software/DESFireLibNFCTesting/LocalInclude/DesfireUtils.h

+12-9
Original file line numberDiff line numberDiff line change
@@ -177,25 +177,22 @@ static inline int AuthenticateISO(nfc_device *nfcConnDev, uint8_t keyIndex, cons
177177
uint8_t *IVBuf = ActiveCryptoIVBuffer;
178178
memcpy(encryptedRndB, rxDataStorage->rxDataBuf, CRYPTO_CHALLENGE_RESPONSE_SIZE);
179179
memset(IVBuf, 0x00, CRYPTO_CHALLENGE_RESPONSE_SIZE);
180-
//memcpy(IVBuf, &encryptedRndB[CRYPTO_CHALLENGE_RESPONSE_SIZE - CRYPTO_3KTDEA_BLOCK_SIZE], CRYPTO_3KTDEA_BLOCK_SIZE);
181180
CryptoData_t desCryptoData = { 0 };
182181
desCryptoData.keySize = 3 * 8;
183182
desCryptoData.keyData = keyData;
184183
desCryptoData.ivSize = CRYPTO_CHALLENGE_RESPONSE_SIZE;
185184
Decrypt3DES(encryptedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE, plainTextRndB, IVBuf, desCryptoData);
186185
if (PRINT_STATUS_EXCHANGE_MESSAGES) {
187-
fprintf(stdout, " -- IV = ");
186+
fprintf(stdout, " -- IV = ");
188187
print_hex(IVBuf, CRYPTO_3KTDEA_BLOCK_SIZE);
189188
}
190189
RotateArrayRight(plainTextRndB, rotatedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE);
191-
//memset(IVBuf, 0x00, CRYPTO_CHALLENGE_RESPONSE_SIZE);
192-
memcpy(IVBuf, &encryptedRndB[CRYPTO_CHALLENGE_RESPONSE_SIZE - CRYPTO_3KTDEA_BLOCK_SIZE], CRYPTO_3KTDEA_BLOCK_SIZE);
193190
desCryptoData.ivData = IVBuf;
194191
GenerateRandomBytes(rndA, CRYPTO_CHALLENGE_RESPONSE_SIZE);
195192
ConcatByteArrays(rndA, CRYPTO_CHALLENGE_RESPONSE_SIZE, rotatedRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE, challengeResponse);
196193
Encrypt3DES(challengeResponse, 2 * CRYPTO_CHALLENGE_RESPONSE_SIZE, challengeResponseCipherText, IVBuf, desCryptoData);
197194
if (PRINT_STATUS_EXCHANGE_MESSAGES) {
198-
fprintf(stdout, " -- IV = ");
195+
fprintf(stdout, " -- IV = ");
199196
print_hex(IVBuf, CRYPTO_3KTDEA_BLOCK_SIZE);
200197
}
201198

@@ -208,12 +205,14 @@ static inline int AuthenticateISO(nfc_device *nfcConnDev, uint8_t keyIndex, cons
208205
memcpy(&sendBytesBuf[5], challengeResponseCipherText, 2 * CRYPTO_CHALLENGE_RESPONSE_SIZE);
209206

210207
if (PRINT_STATUS_EXCHANGE_MESSAGES) {
211-
fprintf(stdout, " -- RNDA = ");
208+
fprintf(stdout, " -- RNDA = ");
212209
print_hex(rndA, CRYPTO_CHALLENGE_RESPONSE_SIZE);
213-
fprintf(stdout, " -- RNDB = ");
210+
fprintf(stdout, " -- RNDB = ");
214211
print_hex(plainTextRndB, CRYPTO_CHALLENGE_RESPONSE_SIZE);
215-
fprintf(stdout, " -- CHAL = ");
212+
fprintf(stdout, " -- CHAL = ");
216213
print_hex(challengeResponse, 2 * CRYPTO_CHALLENGE_RESPONSE_SIZE);
214+
fprintf(stdout, " -- ENC-CHAL = ");
215+
print_hex(challengeResponseCipherText, 2 * CRYPTO_CHALLENGE_RESPONSE_SIZE);
217216
fprintf(stdout, " -> ");
218217
print_hex(sendBytesBuf, sizeof(sendBytesBuf));
219218
}
@@ -236,9 +235,13 @@ static inline int AuthenticateISO(nfc_device *nfcConnDev, uint8_t keyIndex, cons
236235
uint8_t decryptedRndAFromPICCRotated[CRYPTO_CHALLENGE_RESPONSE_SIZE], decryptedRndA[CRYPTO_CHALLENGE_RESPONSE_SIZE];
237236
//memcpy(IVBuf, &rxDataStorage->rxDataBuf[rxDataStorage->recvSzRx - CRYPTO_3KTDEA_BLOCK_SIZE - 1], CRYPTO_3KTDEA_BLOCK_SIZE);
238237
//memset(IVBuf, 0x00, CRYPTO_CHALLENGE_RESPONSE_SIZE);
238+
//memcpy(IVBuf, &rxDataStorage->rxDataBuf[CRYPTO_3KTDEA_BLOCK_SIZE], CRYPTO_3KTDEA_BLOCK_SIZE);
239+
//memcpy(IVBuf, &rxDataStorage->rxDataBuf[CRYPTO_CHALLENGE_RESPONSE_SIZE - CRYPTO_3KTDEA_BLOCK_SIZE], CRYPTO_3KTDEA_BLOCK_SIZE);
240+
//memcpy(IVBuf, &challengeResponseCipherText[2 * CRYPTO_CHALLENGE_RESPONSE_SIZE - CRYPTO_3KTDEA_BLOCK_SIZE], CRYPTO_3KTDEA_BLOCK_SIZE);
241+
memcpy(IVBuf, &encryptedRndB[CRYPTO_3KTDEA_BLOCK_SIZE], CRYPTO_3KTDEA_BLOCK_SIZE);
239242
Decrypt3DES(rxDataStorage->rxDataBuf, CRYPTO_CHALLENGE_RESPONSE_SIZE, decryptedRndAFromPICCRotated, IVBuf, desCryptoData);
240243
if (PRINT_STATUS_EXCHANGE_MESSAGES) {
241-
fprintf(stdout, " -- IV = ");
244+
fprintf(stdout, " -- IV = ");
242245
print_hex(IVBuf, CRYPTO_3KTDEA_BLOCK_SIZE);
243246
}
244247
RotateArrayLeft(decryptedRndAFromPICCRotated, decryptedRndA, CRYPTO_CHALLENGE_RESPONSE_SIZE);

0 commit comments

Comments
 (0)