Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mifare DESFire tag emulation support #287

Merged
merged 10 commits into from
Oct 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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