Skip to content

Commit

Permalink
Merge pull request #287 from maxieds/desfire-emulation-support
Browse files Browse the repository at this point in the history
Mifare DESFire tag emulation support
  • Loading branch information
fptrs committed Oct 19, 2020
2 parents 0169b36 + 2189f91 commit c28597a
Show file tree
Hide file tree
Showing 105 changed files with 13,444 additions and 116 deletions.
478 changes: 478 additions & 0 deletions Doc/DESFireSupportReadme.md

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions Dumps/DESFire_example.contents
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
>>> Select Application By AID:
-> 90 5a 00 00 03 00 00 00 | 00
<- 91 00

>>> Start AES Authenticate:
-> 90 aa 00 00 01 00 00
<- 35 a1 bf c7 9b e3 3b 29 | 35 9b 37 57 ed 35 88 b9 | 91 af
-- RNDA = f4 2d 68 bf bb 3e 87 12
-- RNDB = 0d 3e 90 75 5c 6d d5 22
-- CHAL = f4 2d 68 bf bb 3e 87 12 | 22 0d 3e 90 75 5c 6d d5
-> 90 af 00 00 10 72 15 a8 | 83 46 4c 69 f9 50 c4 7b | a8 e7 30 a7 68 00
<- 0d b4 4f 21 52 89 bc 84 | 25 3b ef bc 54 15 90 11 | 91 00
... AUTH OK! :)

>>> CreateApplication command:
-> 90 ca 00 00 05 01 00 34 | 0f 03 00
<- 91 00
>>> Select Application By AID:
-> 90 5a 00 00 03 01 00 34 | 00
<- 91 00

>>> Start AES Authenticate:
-> 90 aa 00 00 01 00 00
<- b0 82 2a 30 c2 b6 1f d0 | f9 68 33 c9 4b 26 24 20 | 91 af
-- RNDA = c3 70 32 58 4c 06 ef f2
-- RNDB = 2e 7d 6c 67 ae 32 cc f7
-- CHAL = c3 70 32 58 4c 06 ef f2 | f7 2e 7d 6c 67 ae 32 cc
-> 90 af 00 00 10 68 49 4a | c5 1d 75 02 f2 79 23 18 | b8 15 18 21 32 00
<- 6a 61 d5 7e 97 09 35 89 | 7d 10 87 d3 04 8e 20 47 | 91 00
... AUTH OK! :)

>>> CreateStdDataFile command:
-> 90 cd 00 00 07 00 00 0f | 00 04 00 00 00
<- 91 00

>>> CreateBackupDataFile command:
-> 90 cb 00 00 07 01 00 0f | 00 08 00 00 00
<- 91 00

>>> CreateValueFile command:
-> 90 cc 00 00 11 02 00 0f | 00 00 00 00 00 00 01 00 | 00 80 00 00 00 01 00
<- 91 00

>>> CreateLinearRecordFile command:
-> 90 c1 00 00 0a 03 00 0f | 00 04 00 00 0c 00 00 00
<- 91 00

>>> CreateCyclicRecordFile command:
-> 90 c0 00 00 0a 04 00 0f | 00 01 00 00 05 00 00 00
<- 91 00

>>> GetFileIds command:
-> 90 6f 00 00 00 00
<- 00 01 02 03 04 91 00
>>> DeleteFile command:
-> 90 df 00 00 01 01 00
<- 91 00
>>> GetFileIds command:
-> 90 6f 00 00 00 00
<- 00 02 03 04 91 00
>>> GetFileSettings command:
-> 90 f5 00 00 01 00 00
<- 00 00 0f 00 04 00 00 91 | 00
>>> GetFileSettings command:
-> 90 f5 00 00 01 02 00
<- 02 00 0f 00 00 00 00 00 | 00 01 00 00 80 00 00 00 | 01 91 00
>>> GetFileSettings command:
-> 90 f5 00 00 01 03 00
<- 03 00 0f 00 04 00 00 0c | 00 00 00 00 00 91 00
>>> GetFileSettings command:
-> 90 f5 00 00 01 04 00
<- 04 00 0f 00 01 00 00 05 | 00 00 00 00 00 91 00
Binary file added Dumps/DESFire_example.dmp
Binary file not shown.
10 changes: 9 additions & 1 deletion Firmware/Chameleon-Mini/AntennaLevel.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include "AntennaLevel.h"
#include "LEDHook.h"
#include "Log.h"
#include "Application/Application.h"

#define FIELD_MIN_RSSI 500
uint8_t AntennaLevelLogReaderDetectCount = 0;

void AntennaLevelTick(void) {
uint16_t rssi = AntennaLevelGet();
Expand All @@ -13,5 +14,12 @@ void AntennaLevelTick(void) {
ApplicationReset(); // reset the application just like a real card gets reset when there is no field
} else {
LEDHook(LED_FIELD_DETECTED, LED_ON);
AntennaLevelLogReaderDetectCount = (++AntennaLevelLogReaderDetectCount) % ANTENNA_LEVEL_LOG_RDRDETECT_INTERVAL;
if(AntennaLevelLogReaderDetectCount == 0) {
uint8_t antLevel[2];
antLevel[0] = (uint8_t) ((rssi >> 8) & 0x00ff);
antLevel[1] = (uint8_t) (rssi & 0x00ff);
LogEntry(LOG_INFO_CODEC_READER_FIELD_DETECTED, antLevel, 2);
}
}
}
5 changes: 5 additions & 0 deletions Firmware/Chameleon-Mini/AntennaLevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
#define ANTENNA_LEVEL_NUMERATOR ((uint32_t) (ANTENNA_LEVEL_MILLIVOLT * ANTENNA_LEVEL_FACTOR * ANTENNA_LEVEL_SCALE + .5))
#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE)

#define ANTENNA_LEVEL_LOG_RDRDETECT_INTERVAL (15)
extern uint8_t AntennaLevelLogReaderDetectCount;

#define FIELD_MIN_RSSI 500

static inline
void AntennaLevelInit(void) {
ADCA.CTRLA = ADC_ENABLE_bm;
Expand Down
62 changes: 44 additions & 18 deletions Firmware/Chameleon-Mini/Application/Crypto1.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,20 @@
}))
#endif

#ifdef DESFIRE_CRYPTO1_SAVE_SPACE
#define C1MEM PROGMEM
#else
#define C1MEM
#endif

/* Space/speed tradoff. */
/* We want speed, so we have to pay with size. */
/* If we combine the A und B Filtertables and precalculate the values */
/* for each state byte, we get the following tables which gives a */
/* faster calculation of the filter output */
/* Table of the filter A/B output per byte */
static const uint8_t abFilterTable[3][256] = {
#define AB_FILTER_TABLE_ENTRY_SIZE (256)
static const uint8_t C1MEM abFilterTable[3][AB_FILTER_TABLE_ENTRY_SIZE] = {
/* for Odd[0] */
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Expand Down Expand Up @@ -277,7 +284,7 @@ static const uint8_t abFilterTable[3][256] = {
};

/* Standard FC table, feedback at bit 0 */
static const uint8_t TableC0[32] = {
static const uint8_t C1MEM TableC0[32] = {
/* fc with Input {4,3,2,1,0} = (0,0,0,0,0) to (1,1,1,1,1) */
FC(0, 0, 0, 0, 0), FC(0, 0, 0, 0, 1), FC(0, 0, 0, 1, 0), FC(0, 0, 0, 1, 1),
FC(0, 0, 1, 0, 0), FC(0, 0, 1, 0, 1), FC(0, 0, 1, 1, 0), FC(0, 0, 1, 1, 1),
Expand All @@ -290,7 +297,7 @@ static const uint8_t TableC0[32] = {
};

/* Special table for byte processing, feedback at bit 7 */
static const uint8_t TableC7[32] = {
static const uint8_t C1MEM TableC7[32] = {
/* fc with Input {4,3,2,1,0} = (0,0,0,0,0) to (1,1,1,1,1) */
FC(0, 0, 0, 0, 0) << 7, FC(0, 0, 0, 0, 1) << 7, FC(0, 0, 0, 1, 0) << 7, FC(0, 0, 0, 1, 1) << 7,
FC(0, 0, 1, 0, 0) << 7, FC(0, 0, 1, 0, 1) << 7, FC(0, 0, 1, 1, 0) << 7, FC(0, 0, 1, 1, 1) << 7,
Expand All @@ -303,7 +310,7 @@ static const uint8_t TableC7[32] = {
};

/* Special table for nibble processing (e.g. ack), feedback at bit 3 */
static const uint8_t TableC3[32] = {
static const uint8_t C1MEM TableC3[32] = {
/* fc with Input {4,3,2,1,0} = (0,0,0,0,0) to (1,1,1,1,1) */
FC(0, 0, 0, 0, 0) << 3, FC(0, 0, 0, 0, 1) << 3, FC(0, 0, 0, 1, 0) << 3, FC(0, 0, 0, 1, 1) << 3,
FC(0, 0, 1, 0, 0) << 3, FC(0, 0, 1, 0, 1) << 3, FC(0, 0, 1, 1, 0) << 3, FC(0, 0, 1, 1, 1) << 3,
Expand All @@ -316,20 +323,39 @@ static const uint8_t TableC3[32] = {
};

/* Filter Output Macros */
/* Output at bit 7 for optimized byte processing */
#define CRYPTO1_FILTER_OUTPUT_B7_24(__O0, __O1, __O2) TableC7[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]

/* Output at bit 3 for optimized nibble processing */
#define CRYPTO1_FILTER_OUTPUT_B3_24(__O0, __O1, __O2) TableC3[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]

/* Output at bit 0 for general purpose */
#define CRYPTO1_FILTER_OUTPUT_B0_24(__O0, __O1, __O2) TableC0[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]
#ifdef DESFIRE_CRYPTO1_SAVE_SPACE
#define CRYPTO1_FILTER_OUTPUT_B0_24(__O0, __O1, __O2) \
pgm_read_byte(TableC0 + \
(pgm_read_byte(abFilterTable + __O0) | \
pgm_read_byte(abFilterTable + AB_FILTER_TABLE_ENTRY_SIZE + __O1) | \
pgm_read_byte(abFilterTable + 2 * AB_FILTER_TABLE_ENTRY_SIZE + __O2)) \
)
#define CRYPTO1_FILTER_OUTPUT_B3_24(__O0, __O1, __O2) \
pgm_read_byte(TableC3 + \
(pgm_read_byte(abFilterTable + __O0) | \
pgm_read_byte(abFilterTable + AB_FILTER_TABLE_ENTRY_SIZE + __O1) | \
pgm_read_byte(abFilterTable + 2 * AB_FILTER_TABLE_ENTRY_SIZE + __O2)) \
)
#define CRYPTO1_FILTER_OUTPUT_B7_24(__O0, __O1, __O2) \
pgm_read_byte(TableC7 + \
(pgm_read_byte(abFilterTable + __O0) | \
pgm_read_byte(abFilterTable + AB_FILTER_TABLE_ENTRY_SIZE + __O1) | \
pgm_read_byte(abFilterTable + 2 * AB_FILTER_TABLE_ENTRY_SIZE + __O2)) \
)
#else
/* Output at bit 0 for general purpose */
#define CRYPTO1_FILTER_OUTPUT_B0_24(__O0, __O1, __O2) TableC0[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]
/* Output at bit 7 for optimized byte processing */
#define CRYPTO1_FILTER_OUTPUT_B7_24(__O0, __O1, __O2) TableC7[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]
/* Output at bit 3 for optimized nibble processing */
#define CRYPTO1_FILTER_OUTPUT_B3_24(__O0, __O1, __O2) TableC3[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]
#endif

/* Split Crypto1 state into even and odd bits */
/* to speed up the output filter network */
Expand Down
Loading

0 comments on commit c28597a

Please sign in to comment.