diff --git a/Dumps/NTAG215_empty.bin b/Dumps/NTAG215_empty.bin new file mode 100644 index 00000000..8b133bdf Binary files /dev/null and b/Dumps/NTAG215_empty.bin differ diff --git a/Firmware/Chameleon-Mini/Application/MifareUltralight.c b/Firmware/Chameleon-Mini/Application/MifareUltralight.c index 1ce11c2e..805aaf59 100644 --- a/Firmware/Chameleon-Mini/Application/MifareUltralight.c +++ b/Firmware/Chameleon-Mini/Application/MifareUltralight.c @@ -21,12 +21,13 @@ #define ACK_FRAME_SIZE 4 /* Bits */ #define NAK_INVALID_ARG 0x00 #define NAK_CRC_ERROR 0x01 -#define NAK_CTR_ERROR 0x04 +#define NAK_CTR_ERROR 0x04 /* counter overflow for EV1 */ +#define NAK_NOT_AUTHED 0x04 /* invalid authentication & counter overflow for NATG */ #define NAK_EEPROM_ERROR 0x05 #define NAK_OTHER_ERROR 0x06 /* NOTE: the spec is not crystal clear which error is returned */ -#define NAK_AUTH_REQUIRED NAK_OTHER_ERROR -#define NAK_AUTH_FAILED NAK_OTHER_ERROR +#define NAK_AUTH_REQUIRED NAK_OTHER_ERROR /* probably is NAK_NOT_AUTHED 0x04 */ +#define NAK_AUTH_FAILED NAK_OTHER_ERROR /* probably is NAK_NOT_AUTHED 0x04 */ #define NAK_FRAME_SIZE 4 /* ISO commands */ @@ -93,6 +94,7 @@ static enum { UL_EV0, UL_C, UL_EV1, + UL_NTAG_215 } Flavor; static enum { @@ -190,7 +192,7 @@ void MifareUltralightAppInit(void) { } static void AppInitEV1Common(void) { - uint8_t ConfigAreaAddress = PageCount * MIFARE_ULTRALIGHT_PAGE_SIZE - CONFIG_AREA_SIZE; + uint16_t ConfigAreaAddress = PageCount * MIFARE_ULTRALIGHT_PAGE_SIZE - CONFIG_AREA_SIZE; uint8_t Access; /* Set up the emulation flavor */ @@ -202,6 +204,19 @@ static void AppInitEV1Common(void) { AppInitCommon(); } +static void AppInitNTAG215Common(void) { + uint16_t ConfigAreaAddress = PageCount * MIFARE_ULTRALIGHT_PAGE_SIZE - CONFIG_AREA_SIZE; + uint8_t Access; + + /* Set up the emulation flavor */ + Flavor = UL_NTAG_215; + /* Fetch some of the configuration into RAM */ + MemoryReadBlock(&FirstAuthenticatedPage, ConfigAreaAddress + CONF_AUTH0_OFFSET, 1); + MemoryReadBlock(&Access, ConfigAreaAddress + CONF_ACCESS_OFFSET, 1); + ReadAccessProtected = !!(Access & CONF_ACCESS_PROT); + AppInitCommon(); +} + void MifareUltralightEV11AppInit(void) { PageCount = MIFARE_ULTRALIGHT_EV11_PAGES; AppInitEV1Common(); @@ -212,6 +227,11 @@ void MifareUltralightEV12AppInit(void) { AppInitEV1Common(); } +void MifareUltralightNTAG215AppInit(void) { + PageCount = MIFARE_ULTRALIGHT_NTAG_215_PAGES; + AppInitNTAG215Common(); +} + void MifareUltralightAppReset(void) { State = STATE_IDLE; } @@ -414,14 +434,26 @@ static uint16_t AppProcess(uint8_t *const Buffer, uint16_t ByteCount) { case CMD_GET_VERSION: { /* Provide hardcoded version response */ - Buffer[0] = 0x00; - Buffer[1] = 0x04; - Buffer[2] = 0x03; - Buffer[3] = 0x01; /**/ - Buffer[4] = 0x01; - Buffer[5] = 0x00; - Buffer[6] = PageCount == MIFARE_ULTRALIGHT_EV11_PAGES ? 0x0B : 0x0E; - Buffer[7] = 0x03; + if (Flavor == UL_EV1) { //VERSION RESPONSE FOR EV1 + Buffer[0] = 0x00; + Buffer[1] = 0x04; + Buffer[2] = 0x03; + Buffer[3] = 0x01; /**/ + Buffer[4] = 0x01; + Buffer[5] = 0x00; + Buffer[6] = PageCount == MIFARE_ULTRALIGHT_EV11_PAGES ? 0x0B : 0x0E; + Buffer[7] = 0x03; + } else { //VERSION RESPONSE FOR NTAG 215 + /* Provide hardcoded version response */ + Buffer[0] = 0x00; + Buffer[1] = 0x04; + Buffer[2] = 0x04; + Buffer[3] = 0x02; + Buffer[4] = 0x01; + Buffer[5] = 0x00; + Buffer[6] = 0x11; + Buffer[7] = 0x03; + } ISO14443AAppendCRCA(Buffer, VERSION_INFO_LENGTH); return (VERSION_INFO_LENGTH + ISO14443A_CRCA_SIZE) * 8; } @@ -449,7 +481,7 @@ static uint16_t AppProcess(uint8_t *const Buffer, uint16_t ByteCount) { } case CMD_PWD_AUTH: { - uint8_t ConfigAreaAddress = PageCount * MIFARE_ULTRALIGHT_PAGE_SIZE - CONFIG_AREA_SIZE; + uint16_t ConfigAreaAddress = PageCount * MIFARE_ULTRALIGHT_PAGE_SIZE - CONFIG_AREA_SIZE; uint8_t Password[4]; /* Verify value and increment authentication attempt counter */ @@ -522,7 +554,7 @@ static uint16_t AppProcess(uint8_t *const Buffer, uint16_t ByteCount) { return (1 + ISO14443A_CRCA_SIZE) * 8; case CMD_VCSL: { - uint8_t ConfigAreaAddress = PageCount * MIFARE_ULTRALIGHT_PAGE_SIZE - CONFIG_AREA_SIZE; + uint16_t ConfigAreaAddress = PageCount * MIFARE_ULTRALIGHT_PAGE_SIZE - CONFIG_AREA_SIZE; /* Input is ignored completely */ /* Read out the value */ MemoryReadBlock(Buffer, ConfigAreaAddress + CONF_VCTID_OFFSET, 1); diff --git a/Firmware/Chameleon-Mini/Application/MifareUltralight.h b/Firmware/Chameleon-Mini/Application/MifareUltralight.h index 91ac96b5..6cb773fd 100644 --- a/Firmware/Chameleon-Mini/Application/MifareUltralight.h +++ b/Firmware/Chameleon-Mini/Application/MifareUltralight.h @@ -21,13 +21,16 @@ #define MIFARE_ULTRALIGHT_PAGES 16 #define MIFARE_ULTRALIGHT_EV11_PAGES 20 #define MIFARE_ULTRALIGHT_EV12_PAGES 41 +#define MIFARE_ULTRALIGHT_NTAG_215_PAGES 135 //135 pages total, from 0 to 134 #define MIFARE_ULTRALIGHT_MEM_SIZE (MIFARE_ULTRALIGHT_PAGES * MIFARE_ULTRALIGHT_PAGE_SIZE) #define MIFARE_ULTRALIGHT_EV11_MEM_SIZE (MIFARE_ULTRALIGHT_EV11_PAGES * MIFARE_ULTRALIGHT_PAGE_SIZE) #define MIFARE_ULTRALIGHT_EV12_MEM_SIZE (MIFARE_ULTRALIGHT_EV12_PAGES * MIFARE_ULTRALIGHT_PAGE_SIZE) +#define MIFARE_ULTRALIGHT_NTAG_215_MEM_SIZE ( MIFARE_ULTRALIGHT_NTAG_215_PAGES * MIFARE_ULTRALIGHTC_PAGE_SIZE ) void MifareUltralightAppInit(void); void MifareUltralightEV11AppInit(void); void MifareUltralightEV12AppInit(void); +void MifareUltralightNTAG215AppInit(void); void MifareUltralightAppReset(void); void MifareUltralightAppTask(void); diff --git a/Firmware/Chameleon-Mini/Configuration.c b/Firmware/Chameleon-Mini/Configuration.c index aef4fb82..31286910 100644 --- a/Firmware/Chameleon-Mini/Configuration.c +++ b/Firmware/Chameleon-Mini/Configuration.c @@ -19,6 +19,7 @@ static const MapEntryType PROGMEM ConfigurationMap[] = { { .Id = CONFIG_MF_ULTRALIGHT_EV1_80B, .Text = "MF_ULTRALIGHT_EV1_80B" }, { .Id = CONFIG_MF_ULTRALIGHT_EV1_164B, .Text = "MF_ULTRALIGHT_EV1_164B" }, {.Id = CONFIG_MF_ULTRALIGHT_C, .Text = "MF_ULTRALIGHT_C"}, + { .Id = CONFIG_MF_ULTRALIGHT_NTAG_215, .Text = "MF_ULTRALIGHT_NTAG_215" }, #endif #ifdef CONFIG_MF_CLASSIC_MINI_4B_SUPPORT { .Id = CONFIG_MF_CLASSIC_MINI_4B, .Text = "MF_CLASSIC_MINI_4B" }, @@ -156,6 +157,22 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ReadOnly = false, .TagFamily = TAG_FAMILY_ISO14443A }, + [CONFIG_MF_ULTRALIGHT_NTAG_215] = { + .CodecInitFunc = ISO14443ACodecInit, + .CodecDeInitFunc = ISO14443ACodecDeInit, + .CodecTaskFunc = ISO14443ACodecTask, + .ApplicationInitFunc = MifareUltralightNTAG215AppInit, + .ApplicationResetFunc = MifareUltralightAppReset, + .ApplicationTaskFunc = MifareUltralightAppTask, + .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationProcessFunc = MifareUltralightAppProcess, + .ApplicationGetUidFunc = MifareUltralightGetUid, + .ApplicationSetUidFunc = MifareUltralightSetUid, + .UidSize = MIFARE_ULTRALIGHT_UID_SIZE, + .MemorySize = MIFARE_ULTRALIGHT_NTAG_215_MEM_SIZE, + .ReadOnly = false, + .TagFamily = TAG_FAMILY_ISO14443A + }, #endif #ifdef CONFIG_MF_CLASSIC_MINI_4B_SUPPORT [CONFIG_MF_CLASSIC_MINI_4B] = { diff --git a/Firmware/Chameleon-Mini/Configuration.h b/Firmware/Chameleon-Mini/Configuration.h index f348d44c..4f58ac47 100644 --- a/Firmware/Chameleon-Mini/Configuration.h +++ b/Firmware/Chameleon-Mini/Configuration.h @@ -25,6 +25,7 @@ typedef enum { CONFIG_MF_ULTRALIGHT_C, CONFIG_MF_ULTRALIGHT_EV1_80B, CONFIG_MF_ULTRALIGHT_EV1_164B, + CONFIG_MF_ULTRALIGHT_NTAG_215, #endif #ifdef CONFIG_MF_CLASSIC_MINI_4B_SUPPORT CONFIG_MF_CLASSIC_MINI_4B,