Compare commits

..
1 Commits
Author SHA1 Message Date
Iceman 1709c2ffd5 Merge pull request #37 from ceres-c/rrg-iso15693-codec-upd
Porting ISO15693 codec and applications updates
2020-09-13 00:50:25 +02:00
68 changed files with 7986 additions and 12922 deletions

No files matched your search

-36
View File
@@ -1,36 +0,0 @@
name: Firmware Build (Pull Request, Firmware Modified, Artifact in build job)
on:
pull_request:
paths:
- "Firmware/**"
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Make a firmware build folder
run: mkdir FirmwareBuild
- name: Print Kernel Ver
run: uname -a
- name: Update APT
run: sudo apt-get update -yqq
- name: Install AVR GCC Suite
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-avr binutils-avr gdb-avr avr-libc avrdude
- name: Make Firmware
run: make
working-directory: Firmware/Chameleon-Mini/
- name: Move hex file to FirmwareBuild
run: mv Chameleon*.hex $GITHUB_WORKSPACE/FirmwareBuild/
working-directory: Firmware/Chameleon-Mini/
- name: Move eep file to FirmwareBuild
run: mv Chameleon*.eep $GITHUB_WORKSPACE/FirmwareBuild/
working-directory: Firmware/Chameleon-Mini/
- name: Upload Build Artifact to Action
uses: actions/upload-artifact@v3
with:
name: "ChameleonBuild"
path: "FirmwareBuild/**"
-52
View File
@@ -1,52 +0,0 @@
name: Firmware Build (proxgrind Branch Push, Pre-release with Artifacts)
on:
push:
branches: [ proxgrind ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Make a firmware build folder
run: mkdir FirmwareBuild
- name: Print Kernel Ver
run: uname -a
- name: Update APT
run: sudo apt-get update -yqq
- name: Install AVR GCC Suite
run: sudo apt-get install -yqq make autoconf build-essential ca-certificates pkg-config libreadline-dev gcc-avr binutils-avr gdb-avr avr-libc avrdude
- name: Make Firmware
run: make
working-directory: Firmware/Chameleon-Mini/
- name: Move hex file to FirmwareBuild
run: mv Chameleon*.hex $GITHUB_WORKSPACE/FirmwareBuild/
working-directory: Firmware/Chameleon-Mini/
- name: Move eep file to FirmwareBuild
run: mv Chameleon*.eep $GITHUB_WORKSPACE/FirmwareBuild/
working-directory: Firmware/Chameleon-Mini/
- name: Upload Build Artifact to Action
uses: actions/upload-artifact@v3
with:
name: "ChameleonBuild"
path: "FirmwareBuild/**"
- name: Create a Pre-release
uses: DonghaoFeng-Moloco/create-release@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: "${{ format('Build-{0}', github.sha) }}"
release_name: Firmware Build ${{ github.sha }}
body: Built at commit ${{ github.sha }} from ${{ github.actor }}
draft: false
prerelease: true
- name: Upload Pre-release Artifacts
uses: linuxgemini/github-upload-release-artifacts-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
created_tag: "${{ format('Build-{0}', github.sha) }}"
args: "FirmwareBuild/"
-3
View File
@@ -1,3 +0,0 @@
.DS_Store
*.pyc
+7 -9
View File
@@ -1,10 +1,8 @@
/Chameleon-*.eep
/Chameleon-*.hex
/Chameleon-*.elf
/Chameleon-*.map
/Chameleon-*.bin
/Chameleon-*.lss
/Chameleon-*.sym
/Chameleon-Mini.eep
/Chameleon-Mini.hex
/Chameleon-Mini.elf
/Chameleon-Mini.map
/Chameleon-Mini.bin
/Chameleon-Mini.lss
/Chameleon-Mini.sym
/Bin/
dfu-programmer
dfu-programmer.exe
-1
View File
@@ -24,7 +24,6 @@
static inline
void AntennaLevelInit(void) {
ADCA.CAL = (PRODSIGNATURES_ADCACAL1 << 8) | PRODSIGNATURES_ADCACAL0; /* Load calibration data, source: https://www.avrfreaks.net/comment/2080211#comment-2080211 */
ADCA.CTRLA = ADC_ENABLE_bm;
ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc;
ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm;
@@ -21,9 +21,6 @@
#include "TITagitstandard.h"
#include "Sniff14443A.h"
#include "EM4233.h"
#include "NTAG21x.h"
#include "Sniff15693.h"
#include "IClass.h"
/* Function wrappers */
INLINE void ApplicationInit(void) {
@@ -56,20 +53,4 @@ INLINE void ApplicationSetUid(ConfigurationUidType Uid) {
LogEntry(LOG_INFO_UID_SET, Uid, ActiveConfiguration.UidSize);
}
INLINE void ApplicationGetSak(uint8_t * Sak) {
ActiveConfiguration.ApplicationGetSakFunc(Sak);
}
INLINE void ApplicationSetSak(uint8_t Sak) {
ActiveConfiguration.ApplicationSetSakFunc(Sak);
}
INLINE void ApplicationGetAtqa(uint16_t * Atqa) {
ActiveConfiguration.ApplicationGetAtqaFunc(Atqa);
}
INLINE void ApplicationSetAtqa(uint16_t Atqa) {
ActiveConfiguration.ApplicationSetAtqaFunc(Atqa);
}
#endif /* APPLICATION_H_ */
+14 -14
View File
@@ -293,26 +293,26 @@ static const uint8_t TableC0[32] = {
static const uint8_t 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,
FC(0, 1, 0, 0, 0) << 7, FC(0, 1, 0, 0, 1) << 7, FC(0, 1, 0, 1, 0) << 7, FC(0, 1, 0, 1, 1) << 7,
FC(0, 1, 1, 0, 0) << 7, FC(0, 1, 1, 0, 1) << 7, FC(0, 1, 1, 1, 0) << 7, FC(0, 1, 1, 1, 1) << 7,
FC(1, 0, 0, 0, 0) << 7, FC(1, 0, 0, 0, 1) << 7, FC(1, 0, 0, 1, 0) << 7, FC(1, 0, 0, 1, 1) << 7,
FC(1, 0, 1, 0, 0) << 7, FC(1, 0, 1, 0, 1) << 7, FC(1, 0, 1, 1, 0) << 7, FC(1, 0, 1, 1, 1) << 7,
FC(1, 1, 0, 0, 0) << 7, FC(1, 1, 0, 0, 1) << 7, FC(1, 1, 0, 1, 0) << 7, FC(1, 1, 0, 1, 1) << 7,
FC(1, 1, 1, 0, 0) << 7, FC(1, 1, 1, 0, 1) << 7, FC(1, 1, 1, 1, 0) << 7, FC(1, 1, 1, 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,
FC(0, 1, 0, 0, 0) << 7, FC(0, 1, 0, 0, 1) << 7, FC(0, 1, 0, 1, 0) << 7, FC(0, 1, 0, 1, 1) << 7,
FC(0, 1, 1, 0, 0) << 7, FC(0, 1, 1, 0, 1) << 7, FC(0, 1, 1, 1, 0) << 7, FC(0, 1, 1, 1, 1) << 7,
FC(1, 0, 0, 0, 0) << 7, FC(1, 0, 0, 0, 1) << 7, FC(1, 0, 0, 1, 0) << 7, FC(1, 0, 0, 1, 1) << 7,
FC(1, 0, 1, 0, 0) << 7, FC(1, 0, 1, 0, 1) << 7, FC(1, 0, 1, 1, 0) << 7, FC(1, 0, 1, 1, 1) << 7,
FC(1, 1, 0, 0, 0) << 7, FC(1, 1, 0, 0, 1) << 7, FC(1, 1, 0, 1, 0) << 7, FC(1, 1, 0, 1, 1) << 7,
FC(1, 1, 1, 0, 0) << 7, FC(1, 1, 1, 0, 1) << 7, FC(1, 1, 1, 1, 0) << 7, FC(1, 1, 1, 1, 1) << 7
};
/* Special table for nibble processing (e.g. ack), feedback at bit 3 */
static const uint8_t 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,
FC(0, 1, 0, 0, 0) << 3, FC(0, 1, 0, 0, 1) << 3, FC(0, 1, 0, 1, 0) << 3, FC(0, 1, 0, 1, 1) << 3,
FC(0, 1, 1, 0, 0) << 3, FC(0, 1, 1, 0, 1) << 3, FC(0, 1, 1, 1, 0) << 3, FC(0, 1, 1, 1, 1) << 3,
FC(1, 0, 0, 0, 0) << 3, FC(1, 0, 0, 0, 1) << 3, FC(1, 0, 0, 1, 0) << 3, FC(1, 0, 0, 1, 1) << 3,
FC(1, 0, 1, 0, 0) << 3, FC(1, 0, 1, 0, 1) << 3, FC(1, 0, 1, 1, 0) << 3, FC(1, 0, 1, 1, 1) << 3,
FC(1, 1, 0, 0, 0) << 3, FC(1, 1, 0, 0, 1) << 3, FC(1, 1, 0, 1, 0) << 3, FC(1, 1, 0, 1, 1) << 3,
FC(1, 1, 1, 0, 0) << 3, FC(1, 1, 1, 0, 1) << 3, FC(1, 1, 1, 1, 0) << 3, FC(1, 1, 1, 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,
FC(0, 1, 0, 0, 0) << 3, FC(0, 1, 0, 0, 1) << 3, FC(0, 1, 0, 1, 0) << 3, FC(0, 1, 0, 1, 1) << 3,
FC(0, 1, 1, 0, 0) << 3, FC(0, 1, 1, 0, 1) << 3, FC(0, 1, 1, 1, 0) << 3, FC(0, 1, 1, 1, 1) << 3,
FC(1, 0, 0, 0, 0) << 3, FC(1, 0, 0, 0, 1) << 3, FC(1, 0, 0, 1, 0) << 3, FC(1, 0, 0, 1, 1) << 3,
FC(1, 0, 1, 0, 0) << 3, FC(1, 0, 1, 0, 1) << 3, FC(1, 0, 1, 1, 0) << 3, FC(1, 0, 1, 1, 1) << 3,
FC(1, 1, 0, 0, 0) << 3, FC(1, 1, 0, 0, 1) << 3, FC(1, 1, 0, 1, 0) << 3, FC(1, 1, 0, 1, 1) << 3,
FC(1, 1, 1, 0, 0) << 3, FC(1, 1, 1, 0, 1) << 3, FC(1, 1, 1, 1, 0) << 3, FC(1, 1, 1, 1, 1) << 3
};
/* Filter Output Macros */
File diff suppressed because it is too large. Load diff
@@ -1,26 +0,0 @@
/*
* IClass.c
*
* Created on: 17-05-2020
* Author: NVX
*/
#ifndef ICLASS_H_
#define ICLASS_H_
#include "Application.h"
#define ICLASS_BLOCK_SIZE 8
#define ICLASS_CSN_SIZE ICLASS_BLOCK_SIZE
#define ICLASS_BLOCK_NUM 32
#define ICLASS_MEM_SIZE ( ICLASS_BLOCK_SIZE * ICLASS_BLOCK_NUM )
#define ICLASS_READ4_SIZE ( ICLASS_BLOCK_SIZE * 4 )
void IClassAppInit(void);
void IClassAppReset(void);
void IClassDetectionInit(void);
uint16_t IClassAppProcess(uint8_t *FrameBuf, uint16_t FrameBytes);
void IClassGetCsn(ConfigurationUidType Uid);
void IClassSetCsn(const ConfigurationUidType Uid);
#endif /* ICLASS_H_ */
@@ -133,7 +133,7 @@ bool ISO14443AWakeUp(void *Buffer, uint16_t *BitCount, uint16_t ATQAValue, bool
return true;
} else {
// *BitCount = 0;
*BitCount = 0;
return false;
}
File diff suppressed because it is too large. Load diff
@@ -16,13 +16,6 @@
#define MIFARE_CLASSIC_1K_MEM_SIZE 1024
#define MIFARE_CLASSIC_4K_MEM_SIZE 4096
extern bool DetectionMode;
void DetectionLogToFlash(uint8_t Entry, const void *Data, uint8_t Length);
void DetectionInit(void);
void DetectionLogClear(void);
void MifareDetectionInit1K(void);
void MifareDetectionInit4K(void);
void MifareClassicAppInitMini4B(void);
void MifareClassicAppInit1K(void);
void MifareClassicAppInit4K(void);
@@ -36,9 +29,5 @@ uint16_t MifareClassicAppProcess(uint8_t *Buffer, uint16_t BitCount);
void MifareClassicGetUid(ConfigurationUidType Uid);
void MifareClassicSetUid(ConfigurationUidType Uid);
void MifareClassicGetAtqa(uint16_t * Atqa);
void MifareClassicSetAtqa(uint16_t Atqa);
void MifareClassicGetSak(uint8_t * Sak);
void MifareClassicSetSak(uint8_t Sak);
#endif /* MIFARECLASSIC_H_ */
@@ -112,8 +112,6 @@ static uint8_t CompatWritePageAddress;
static bool Authenticated;
static uint8_t FirstAuthenticatedPage;
static bool ReadAccessProtected;
static uint16_t CardATQAValue;
static uint8_t CardSAKValue;
static uint8_t RNDBBuff [8];
static uint8_t InitialVector[8] = {0};
static uint8_t TripleDesKey [16];
@@ -155,8 +153,6 @@ static void AppInitCommon(void) {
FromHalt = false;
Authenticated = false;
ArmedForCompatWrite = false;
CardATQAValue = ATQA_VALUE;
CardSAKValue = SAK_CL1_VALUE;
}
void MifareUltralightCAppInit(void) {
Flavor = UL_C;
@@ -289,7 +285,7 @@ static uint16_t AppProcess(uint8_t *const Buffer, uint16_t ByteCount) {
//Handle MF ULC counter
if (CompatWritePageAddress == MF_ULC_COUNTER_ADDRESS && Flavor == UL_C) {
if (IncrementCounter(&Buffer[0])) {
if (IncrementCounter(&Buffer[2])) {
Buffer[0] = ACK_VALUE;
return ACK_FRAME_SIZE;
} else {
@@ -298,7 +294,7 @@ static uint16_t AppProcess(uint8_t *const Buffer, uint16_t ByteCount) {
}
}
AppWritePage(CompatWritePageAddress, &Buffer[0]);
AppWritePage(CompatWritePageAddress, &Buffer[2]);
Buffer[0] = ACK_VALUE;
return ACK_FRAME_SIZE;
}
@@ -677,22 +673,3 @@ void MifareUltralightSetUid(ConfigurationUidType Uid) {
MemoryWriteBlock(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE);
}
void MifareUltralightGetAtqa(uint16_t * Atqa)
{
*Atqa = CardATQAValue;
}
void MifareUltralightSetAtqa(uint16_t Atqa)
{
CardATQAValue = Atqa;
}
void MifareUltralightGetSak(uint8_t * Sak)
{
*Sak = CardSAKValue;
}
void MifareUltralightSetSak(uint8_t Sak)
{
CardSAKValue = Sak;
}
@@ -39,9 +39,6 @@ uint16_t MifareUltralightAppProcess(uint8_t *Buffer, uint16_t BitCount);
void MifareUltralightGetUid(ConfigurationUidType Uid);
void MifareUltralightSetUid(ConfigurationUidType Uid);
void MifareUltralightGetAtqa(uint16_t * Atqa);
void MifareUltralightSetAtqa(uint16_t Atqa);
void MifareUltralightGetSak(uint8_t * Sak);
void MifareUltralightSetSak(uint8_t Sak);
#endif /* MIFAREULTRALIGHT_H_ */
@@ -1,499 +0,0 @@
/*
* NTAG21x.c
*
* Created on: 20.02.2019
* Author: Giovanni Cammisa (gcammisa)
* Still missing support for:
* - The management of both static and dynamic lock bytes
* - Bruteforce protection (AUTHLIM COUNTER)
* Thanks to skuser for the MifareUltralight code used as a starting point
*/
#include "ISO14443-3A.h"
#include "../Codec/ISO14443-2A.h"
#include "../Memory.h"
#include "NTAG21x.h"
// DEFINE ATQA and SAK
#define ATQA_VALUE 0x0044
#define SAK_VALUE 0x00
#define SAK_CL1_VALUE ISO14443A_SAK_INCOMPLETE
#define SAK_CL2_VALUE ISO14443A_SAK_COMPLETE_NOT_COMPLIANT
// ACK and NACK
#define ACK_VALUE 0x0A
#define ACK_FRAME_SIZE 4 /* Bits */
#define NAK_INVALID_ARG 0x00
#define NAK_CRC_ERROR 0x01
#define NAK_NOT_AUTHED 0x04
#define NAK_EEPROM_ERROR 0x05
#define NAK_FRAME_SIZE 4
// DEFINING COMMANDS
/* ISO commands */
#define CMD_HALT 0x50
// NTAG COMMANDS
#define CMD_GET_VERSION 0x60
#define CMD_READ 0x30
#define CMD_FAST_READ 0x3A
#define CMD_WRITE 0xA2
#define CMD_COMPAT_WRITE 0xA0
#define CMD_READ_CNT 0x39
#define CMD_PWD_AUTH 0x1B
#define CMD_READ_SIG 0x3C
// MEMORY LAYOUT STUFF, addresses and sizes in bytes
// UID stuff
#define UID_CL1_ADDRESS 0x00
#define UID_CL1_SIZE 3
#define UID_BCC1_ADDRESS 0x03
#define UID_CL2_ADDRESS 0x04
#define UID_CL2_SIZE 4
#define UID_BCC2_ADDRESS 0x08
// LockBytes stuff
#define STATIC_LOCKBYTE_0_ADDRESS 0x0A
#define STATIC_LOCKBYTE_1_ADDRESS 0x0B
// CONFIG stuff
#define NTAG213_CONFIG_AREA_START_ADDRESS NTAG21x_PAGE_SIZE * 0x29
#define NTAG215_CONFIG_AREA_START_ADDRESS NTAG21x_PAGE_SIZE * 0x83
#define NTAG216_CONFIG_AREA_START_ADDRESS NTAG21x_PAGE_SIZE * 0xE3
#define CONFIG_AREA_SIZE 8
// CONFIG offsets, relative to config start address
#define CONF_AUTH0_OFFSET 0x03
#define CONF_ACCESS_OFFSET 0x04
#define CONF_PASSWORD_OFFSET 0x08
#define CONF_PACK_OFFSET 0x0C
// WRITE STUFF
#define BYTES_PER_WRITE 4
#define PAGE_WRITE_MIN 0x02
// CONFIG masks to check individual needed bits
#define CONF_ACCESS_PROT 0x80
#define VERSION_INFO_LENGTH 8 //8 bytes info lenght + crc
#define BYTES_PER_READ NTAG21x_PAGE_SIZE * 4
// SIGNATURE Lenght
#define SIGNATURE_LENGTH 32
static enum {
TYPE_NTAG213,
TYPE_NTAG215,
TYPE_NTAG216
} Ntag_Type;
static enum {
STATE_HALT,
STATE_IDLE,
STATE_READY1,
STATE_READY2,
STATE_ACTIVE
} State;
static uint32_t ConfigStartAddr = NTAG213_CONFIG_AREA_START_ADDRESS;
static bool FromHalt = false;
static uint8_t PageCount;
static bool ArmedForCompatWrite;
static uint8_t CompatWritePageAddress;
static bool Authenticated;
static uint8_t FirstAuthenticatedPage;
static bool ReadAccessProtected;
static uint8_t Access;
void NTAG21xAppInit(void)
{
State = STATE_IDLE;
FromHalt = false;
ArmedForCompatWrite = false;
Authenticated = false;
//PageCount = NTAG215_PAGES;
switch (Ntag_Type)
{
case TYPE_NTAG213:
PageCount = NTAG213_PAGES;
break;
case TYPE_NTAG215:
PageCount = NTAG215_PAGES;
break;
case TYPE_NTAG216:
PageCount = NTAG216_PAGES;
break;
}
/* Fetch some of the configuration into RAM */
MemoryReadBlock(&FirstAuthenticatedPage, ConfigStartAddr + CONF_AUTH0_OFFSET, 1);
MemoryReadBlock(&Access, ConfigStartAddr + CONF_ACCESS_OFFSET, 1);
ReadAccessProtected = !!(Access & CONF_ACCESS_PROT);
}
#if defined(CONFIG_NTAG213_SUPPORT)
void NTAG213AppInit(void)
{
Ntag_Type = TYPE_NTAG213;
PageCount = NTAG213_PAGES;
ConfigStartAddr = NTAG213_CONFIG_AREA_START_ADDRESS;
NTAG21xAppInit();
}
#endif // CONIFG_NTAG213_SUPPORT
#ifdef CONFIG_NTAG215_SUPPORT
void NTAG215AppInit(void)
{
Ntag_Type = TYPE_NTAG215;
PageCount = NTAG215_PAGES;
ConfigStartAddr = NTAG215_CONFIG_AREA_START_ADDRESS;
NTAG21xAppInit();
}
#endif // CONFIG_NTAG215_SUPPORT
#ifdef CONFIG_NTAG216_SUPPORT
void NTAG216AppInit(void)
{
Ntag_Type = TYPE_NTAG216;
PageCount = NTAG216_PAGES;
ConfigStartAddr = NTAG216_CONFIG_AREA_START_ADDRESS;
NTAG21xAppInit();
}
#endif // CONFIG_NTAG216_SUPPORT
void NTAG21xAppReset(void)
{
State = STATE_IDLE;
}
void NTAG21xAppTask(void)
{
}
// Verify authentication
static bool VerifyAuthentication(uint8_t PageAddress)
{
/* If authenticated, no verification needed */
if (Authenticated) {
return true;
}
/* Otherwise, verify the accessed page is below the limit */
return PageAddress < FirstAuthenticatedPage;
}
// Writes a page
static uint8_t AppWritePage(uint8_t PageAddress, uint8_t* const Buffer)
{
if (!ActiveConfiguration.ReadOnly) {
MemoryWriteBlock(Buffer, PageAddress * NTAG21x_PAGE_SIZE, NTAG21x_PAGE_SIZE);
} else {
/* If the chameleon is in read only mode, it silently
* ignores any attempt to write data. */
}
return 0;
}
// Basic sketch of the command handling stuff
static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount)
{
uint8_t Cmd = Buffer[0];
/* Handle the compatibility write command */
if (ArmedForCompatWrite) {
ArmedForCompatWrite = false;
AppWritePage(CompatWritePageAddress, &Buffer[2]);
Buffer[0] = ACK_VALUE;
return ACK_FRAME_SIZE;
}
switch (Cmd) {
case CMD_GET_VERSION: {
/* Provide hardcoded version response */ //VERSION RESPONSE FOR NTAG 215
Buffer[0] = 0x00;
Buffer[1] = 0x04;
Buffer[2] = 0x04;
Buffer[3] = 0x02;
Buffer[4] = 0x01;
Buffer[5] = 0x00;
switch (Ntag_Type) {
case TYPE_NTAG213:
Buffer[6] = 0x0F;
break;
case TYPE_NTAG215:
Buffer[6] = 0x11;
break;
case TYPE_NTAG216:
Buffer[6] = 0x13;
break;
}
Buffer[7] = 0x03;
ISO14443AAppendCRCA(Buffer, VERSION_INFO_LENGTH);
return (VERSION_INFO_LENGTH + ISO14443A_CRCA_SIZE) * 8;
}
case CMD_READ: {
uint8_t PageAddress = Buffer[1];
uint8_t PageLimit;
uint8_t Offset;
PageLimit = PageCount;
/* if protected and not autenticated, ensure the wraparound is at the first protected page */
if (ReadAccessProtected && !Authenticated) {
PageLimit = FirstAuthenticatedPage;
}
else {
PageLimit = PageCount;
}
/* Validation */
if (PageAddress >= PageLimit) {
Buffer[0] = NAK_INVALID_ARG;
return NAK_FRAME_SIZE;
}
/* Read out, emulating the wraparound */
for (Offset = 0; Offset < BYTES_PER_READ; Offset += 4) {
MemoryReadBlock(&Buffer[Offset], PageAddress * NTAG21x_PAGE_SIZE, NTAG21x_PAGE_SIZE);
PageAddress++;
if (PageAddress == PageLimit) { // if arrived ad the last page, start reading from page 0
PageAddress = 0;
}
}
ISO14443AAppendCRCA(Buffer, BYTES_PER_READ);
return (BYTES_PER_READ + ISO14443A_CRCA_SIZE) * 8;
}
case CMD_FAST_READ: {
uint8_t StartPageAddress = Buffer[1];
uint8_t EndPageAddress = Buffer[2];
/* Validation */
if ((StartPageAddress > EndPageAddress) || (StartPageAddress >= PageCount) || (EndPageAddress >= PageCount)) {
Buffer[0] = NAK_INVALID_ARG;
return NAK_FRAME_SIZE;
}
/* Check authentication only if protection is read&write (instead of only write protection) */
if (ReadAccessProtected) {
if (!VerifyAuthentication(StartPageAddress) || !VerifyAuthentication(EndPageAddress)) {
Buffer[0] = NAK_NOT_AUTHED;
return NAK_FRAME_SIZE;
}
}
ByteCount = (EndPageAddress - StartPageAddress + 1) * NTAG21x_PAGE_SIZE;
MemoryReadBlock(Buffer, StartPageAddress * NTAG21x_PAGE_SIZE, ByteCount);
ISO14443AAppendCRCA(Buffer, ByteCount);
return (ByteCount + ISO14443A_CRCA_SIZE) * 8;
}
case CMD_PWD_AUTH: {
uint8_t Password[4];
/* For now I don't care about bruteforce protection, so: */
/* TODO: IMPLEMENT COUNTER AUTHLIM */
/* Read and compare the password */
MemoryReadBlock(Password, ConfigStartAddr + CONF_PASSWORD_OFFSET, 4);
if (Password[0] != Buffer[1] || Password[1] != Buffer[2] || Password[2] != Buffer[3] || Password[3] != Buffer[4]) {
Buffer[0] = NAK_NOT_AUTHED;
return NAK_FRAME_SIZE;
}
/* Authenticate the user */
//RESET AUTHLIM COUNTER, CURRENTLY NOT IMPLEMENTED
Authenticated = 1;
/* Send the PACK value back */
MemoryReadBlock(Buffer, ConfigStartAddr + CONF_PACK_OFFSET, 2);
ISO14443AAppendCRCA(Buffer, 2);
return (2 + ISO14443A_CRCA_SIZE) * 8;
}
case CMD_WRITE: {
/* This is a write command containing 4 bytes of data that
* should be written to the given page address. */
uint8_t PageAddress = Buffer[1];
/* Validation */
if ((PageAddress < PAGE_WRITE_MIN) || (PageAddress >= PageCount)) {
Buffer[0] = NAK_INVALID_ARG;
return NAK_FRAME_SIZE;
}
if (!VerifyAuthentication(PageAddress)) {
Buffer[0] = NAK_NOT_AUTHED;
return NAK_FRAME_SIZE;
}
AppWritePage(PageAddress, &Buffer[2]);
Buffer[0] = ACK_VALUE;
return ACK_FRAME_SIZE;
}
case CMD_COMPAT_WRITE: {
uint8_t PageAddress = Buffer[1];
/* Validation */
if ((PageAddress < PAGE_WRITE_MIN) || (PageAddress >= PageCount)) {
Buffer[0] = NAK_INVALID_ARG;
return NAK_FRAME_SIZE;
}
if (!VerifyAuthentication(PageAddress)) {
Buffer[0] = NAK_NOT_AUTHED;
return NAK_FRAME_SIZE;
}
/* CRC check passed and page-address is within bounds.
* Store address and proceed to receiving the data. */
CompatWritePageAddress = PageAddress;
ArmedForCompatWrite = true; //TODO:IMPLEMENT ARMED COMPAT WRITE
Buffer[0] = ACK_VALUE;
return ACK_FRAME_SIZE;
}
case CMD_READ_SIG: {
/* Hardcoded response */
memset(Buffer, 0xCA, SIGNATURE_LENGTH);
ISO14443AAppendCRCA(Buffer, SIGNATURE_LENGTH);
return (SIGNATURE_LENGTH + ISO14443A_CRCA_SIZE) * 8;
}
//PART OF ISO STANDARD, NOT OF NTAG DATASHEET
case CMD_HALT: {
/* Halts the tag. According to the ISO14443, the second
* byte is supposed to be 0. */
if (Buffer[1] == 0) {
/* According to ISO14443, we must not send anything
* in order to acknowledge the HALT command. */
State = STATE_HALT;
return ISO14443A_APP_NO_RESPONSE;
} else {
Buffer[0] = NAK_INVALID_ARG;
return NAK_FRAME_SIZE;
}
}
default: {
break;
}
}
/* Command not handled. Switch to idle. */
State = STATE_IDLE;
return ISO14443A_APP_NO_RESPONSE;
}
// FINITE STATE MACHINE STUFF, SHOULD BE THE VERY SIMILAR TO Mifare Ultralight
uint16_t NTAG21xAppProcess(uint8_t* Buffer, uint16_t BitCount)
{
uint8_t Cmd = Buffer[0];
uint16_t ByteCount;
switch(State) {
case STATE_IDLE:
case STATE_HALT:
FromHalt = State == STATE_HALT;
if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE, FromHalt)) {
/* We received a REQA or WUPA command, so wake up. */
State = STATE_READY1;
return BitCount;
}
break;
case STATE_READY1:
if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE, FromHalt)) {
State = FromHalt ? STATE_HALT : STATE_IDLE;
return ISO14443A_APP_NO_RESPONSE;
} else if (Cmd == ISO14443A_CMD_SELECT_CL1) {
/* Load UID CL1 and perform anticollision. Since
* MF Ultralight use a double-sized UID, the first byte
* of CL1 has to be the cascade-tag byte. */
uint8_t UidCL1[ISO14443A_CL_UID_SIZE] = { [0] = ISO14443A_UID0_CT };
MemoryReadBlock(&UidCL1[1], UID_CL1_ADDRESS, UID_CL1_SIZE);
if (ISO14443ASelect(Buffer, &BitCount, UidCL1, SAK_CL1_VALUE)) {
/* CL1 stage has ended successfully */
State = STATE_READY2;
}
return BitCount;
} else {
/* Unknown command. Enter halt state */
State = STATE_IDLE;
}
break;
case STATE_READY2:
if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE, FromHalt)) {
State = FromHalt ? STATE_HALT : STATE_IDLE;
return ISO14443A_APP_NO_RESPONSE;
} else if (Cmd == ISO14443A_CMD_SELECT_CL2) {
/* Load UID CL2 and perform anticollision */
uint8_t UidCL2[ISO14443A_CL_UID_SIZE];
MemoryReadBlock(UidCL2, UID_CL2_ADDRESS, UID_CL2_SIZE);
if (ISO14443ASelect(Buffer, &BitCount, UidCL2, SAK_CL2_VALUE)) {
/* CL2 stage has ended successfully. This means
* our complete UID has been sent to the reader. */
State = STATE_ACTIVE;
}
return BitCount;
} else {
/* Unknown command. Enter halt state */
State = STATE_IDLE;
}
break;
// Only ACTIVE state, no AUTHENTICATED state, PWD_AUTH is handled in commands.
case STATE_ACTIVE:
/* Preserve incoming data length */
ByteCount = (BitCount + 7) >> 3;
if (ISO14443AWakeUp(Buffer, &BitCount, ATQA_VALUE, FromHalt)) {
State = FromHalt ? STATE_HALT : STATE_IDLE;
return ISO14443A_APP_NO_RESPONSE;
}
/* At the very least, there should be 3 bytes in the buffer. */
if (ByteCount < (1 + ISO14443A_CRCA_SIZE)) {
State = STATE_IDLE;
return ISO14443A_APP_NO_RESPONSE;
}
/* All commands here have CRCA appended; verify it right away */
ByteCount -= 2;
if (!ISO14443ACheckCRCA(Buffer, ByteCount)) {
Buffer[0] = NAK_CRC_ERROR;
return NAK_FRAME_SIZE;
}
return AppProcess(Buffer, ByteCount);
default:
/* Unknown state? Should never happen. */
break;
}
/* No response has been sent, when we reach here */
return ISO14443A_APP_NO_RESPONSE;
}
// HELPER FUNCTIONS
void NTAG21xGetUid(ConfigurationUidType Uid)
{
/* Read UID from memory */
MemoryReadBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
MemoryReadBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
}
void NTAG21xSetUid(ConfigurationUidType Uid)
{
/* Calculate check bytes and write everything into memory */
uint8_t BCC1 = ISO14443A_UID0_CT ^ Uid[0] ^ Uid[1] ^ Uid[2];
uint8_t BCC2 = Uid[3] ^ Uid[4] ^ Uid[5] ^ Uid[6];
MemoryWriteBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
MemoryWriteBlock(&BCC1, UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE);
MemoryWriteBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
MemoryWriteBlock(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE);
}
@@ -1,34 +0,0 @@
/*
* NTAG21x.h
*
* Created on: 20.02.2019
* Author: gcammisa
*/
#ifndef NTAG21x_H_
#define NTAG21x_H_
#include "Application.h"
#include "ISO14443-3A.h"
#define NTAG21x_UID_SIZE ISO14443A_UID_SIZE_DOUBLE // 7 bytes UID
#define NTAG21x_PAGE_SIZE 4 // bytes per page
#define NTAG213_PAGES 45 //45 pages total for ntag213, from 0 to 44
#define NTAG215_PAGES 135 //135 pages total for ntag215, from 0 to 134
#define NTAG216_PAGES 231 //231 pages total for ntag216, from 0 to 230
#define NTAG213_MEM_SIZE ( NTAG21x_PAGE_SIZE * NTAG213_PAGES )
#define NTAG215_MEM_SIZE ( NTAG21x_PAGE_SIZE * NTAG215_PAGES )
#define NTAG216_MEM_SIZE ( NTAG21x_PAGE_SIZE * NTAG216_PAGES )
void NTAG213AppInit(void);
void NTAG215AppInit(void);
void NTAG216AppInit(void);
void NTAG21xAppReset(void);
void NTAG21xAppTask(void);
uint16_t NTAG21xAppProcess(uint8_t* Buffer, uint16_t BitCount);
void NTAG21xGetUid(ConfigurationUidType Uid);
void NTAG21xSetUid(ConfigurationUidType Uid);
#endif
@@ -4,7 +4,6 @@
#include "../Codec/Reader14443-2A.h"
#include "Crypto1.h"
#include "../System.h"
#include "../uartcmd.h"
#include "../Terminal/Terminal.h"
@@ -142,8 +141,8 @@ uint16_t addParityBits(uint8_t *Buffer, uint16_t BitCount) {
uint16_t removeParityBits(uint8_t *Buffer, uint16_t BitCount) {
// Short frame, no parity bit is added
if (BitCount <= 7)
return BitCount;
if (BitCount == 7)
return 7;
uint16_t i;
for (i = 0; i < (BitCount / 9); i++) {
@@ -151,7 +150,7 @@ uint16_t removeParityBits(uint8_t *Buffer, uint16_t BitCount) {
if (i % 8)
Buffer[i] |= (Buffer[i + i / 8 + 1] << (8 - (i % 8)));
}
return (BitCount / 9) * 8;
return BitCount / 9 * 8;
}
bool checkParityBits(uint8_t *Buffer, uint16_t BitCount) {
@@ -230,7 +229,7 @@ static uint16_t Reader14443A_Select(uint8_t *Buffer, uint16_t BitCount) {
switch (ReaderState) {
case STATE_IDLE:
case STATE_HALT:
Reader_FWT = ISO14443A_RX_PENDING_TIMEOUT;
Reader_FWT = 4;
/* Send a REQA */
Buffer[0] = ISO14443A_CMD_WUPA; // whenever REQA works, WUPA also works, so we choose WUPA always
ReaderState = STATE_READY;
@@ -818,7 +817,9 @@ uint16_t Reader14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
int cfgid = -1;
switch (CardCandidates[0]) {
case CardType_NXP_MIFARE_Ultralight: {
#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
cfgid = CONFIG_MF_ULTRALIGHT;
#endif
// TODO: enter MFU clone mdoe
break;
}
@@ -828,8 +829,8 @@ uint16_t Reader14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT
cfgid = CONFIG_MF_CLASSIC_1K;
#endif
#ifdef CONFIG_MF_CLASSIC_1K_7B_SUPPORT
} else if (CardCharacteristics.UIDSize == UIDSize_Double) {
#ifdef CONFIG_MF_CLASSIC_1K_7B_SUPPORT
cfgid = CONFIG_MF_CLASSIC_1K_7B;
#endif
}
@@ -842,8 +843,8 @@ uint16_t Reader14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT
cfgid = CONFIG_MF_CLASSIC_4K;
#endif
#ifdef CONFIG_MF_CLASSIC_4K_7B_SUPPORT
} else if (CardCharacteristics.UIDSize == UIDSize_Double) {
#ifdef CONFIG_MF_CLASSIC_4K_7B_SUPPORT
cfgid = CONFIG_MF_CLASSIC_4K_7B;
#endif
}
@@ -11,6 +11,7 @@
extern bool checkParityBits(uint8_t *Buffer, uint16_t BitCount);
Sniff14443Command Sniff14443CurrentCommand = Sniff14443_Do_Nothing;
//bool selected = false;
static enum {
STATE_IDLE,
STATE_REQA,
@@ -22,7 +23,8 @@ static enum {
} SniffState = STATE_IDLE;
static uint16_t tmp_th = CODEC_THRESHOLD_CALIBRATE_MIN;
static uint8_t Thresholds[(CODEC_THRESHOLD_CALIBRATE_MAX - CODEC_THRESHOLD_CALIBRATE_MIN) / CODEC_THRESHOLD_CALIBRATE_STEPS] = {0};
static uint8_t Thresholds[(CODEC_THRESHOLD_CALIBRATE_MAX - CODEC_THRESHOLD_CALIBRATE_MIN) /
CODEC_THRESHOLD_CALIBRATE_STEPS] = {0};
void Sniff14443AAppInit(void) {
SniffState = STATE_REQA;
@@ -67,7 +69,7 @@ uint16_t Sniff14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
case STATE_REQA:
LED_PORT.OUTCLR = LED_RED;
// If received Reader REQA or WUPA
if (SniffTrafficSource == TRAFFIC_READER &&
if (TrafficSource == TRAFFIC_READER &&
(Buffer[0] == 0x26 || Buffer[0] == 0x52)) {
SniffState = STATE_ATQA;
} else {
@@ -76,7 +78,7 @@ uint16_t Sniff14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
break;
case STATE_ATQA:
// ATQA: P RRRR XXXX P XXRX XXXX
if (SniffTrafficSource == TRAFFIC_CARD &&
if (TrafficSource == TRAFFIC_CARD &&
BitCount == 2 * 9 &&
(Buffer[0] & 0x20) == 0x00 && // Bit6 RFU shall be 0
(Buffer[1] & 0xE0) == 0x00 && // bit13-16 RFU shall be 0
@@ -87,7 +89,7 @@ uint16_t Sniff14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
} else {
// If not ATQA, but REQA, then stay on this state,
// Reset to REQA, save the counter and reset the counter
if (SniffTrafficSource == TRAFFIC_READER &&
if (TrafficSource == TRAFFIC_READER &&
(Buffer[0] == 0x26 || Buffer[0] == 0x52)) {
} else {
// If not ATQA and not REQA then reset to REQA
@@ -97,7 +99,7 @@ uint16_t Sniff14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
break;
case STATE_ANTICOLLI:
// SEL: 93/95/97
if (SniffTrafficSource == TRAFFIC_READER &&
if (TrafficSource == TRAFFIC_READER &&
BitCount == 2 * 8 &&
(Buffer[0] & 0xf0) == 0x90 &&
(Buffer[0] & 0x09) == 0x01) {
@@ -108,7 +110,7 @@ uint16_t Sniff14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
}
break;
case STATE_UID:
if (SniffTrafficSource == TRAFFIC_CARD &&
if (TrafficSource == TRAFFIC_CARD &&
BitCount == 5 * 9 &&
checkParityBits(Buffer, BitCount)) {
SniffState = STATE_SELECT;
@@ -119,7 +121,7 @@ uint16_t Sniff14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
case STATE_SELECT:
// SELECT: 9 bytes, SEL = 93/95/97, NVB=70
if (SniffTrafficSource == TRAFFIC_READER &&
if (TrafficSource == TRAFFIC_READER &&
BitCount == 9 * 8 &&
(Buffer[0] & 0xf0) == 0x90 &&
(Buffer[0] & 0x09) == 0x01 &&
@@ -132,7 +134,7 @@ uint16_t Sniff14443AAppProcess(uint8_t *Buffer, uint16_t BitCount) {
break;
case STATE_SAK:
// SAK: 1Byte SAK + CRC
if (SniffTrafficSource == TRAFFIC_CARD &&
if (TrafficSource == TRAFFIC_CARD &&
BitCount == 3 * 9 &&
checkParityBits(Buffer, BitCount)) {
if ((Buffer[0] & 0x04) == 0x00) {
@@ -1,38 +0,0 @@
/*
* SniffISO15693.h
*
* Created on: 05.11.2019
* Author: ceres-c
*/
#ifdef CONFIG_ISO15693_SNIFF_SUPPORT
#include "../Codec/SniffISO15693.h"
#include "Sniff15693.h"
void SniffISO15693AppInit(void)
{
}
void SniffISO15693AppReset(void)
{
}
void SniffISO15693AppTask(void)
{
}
void SniffISO15693AppTick(void)
{
}
uint16_t SniffISO15693AppProcess(uint8_t* FrameBuf, uint16_t FrameBytes)
{
return 0;
}
#endif /* CONFIG_ISO15693_SNIFF_SUPPORT */
Loaded 20 of 68 files, more files were not shown because too many files have changed in this diff. Show more