Skip to content
Open
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
93 changes: 93 additions & 0 deletions build_dev.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<#
.SYNOPSIS
Compila el firmware de ChameleonUltra (Application) y genera el paquete DFU.

.DESCRIPTION
Este script configura el entorno (PATH) para usar el compilador ARM descargado localmente
y las utilidades de Git, compila el código fuente en firmware/application usando 'make',
y finalmente empaqueta el resultado en un archivo .zip usando 'nrfutil'.

.NOTES
Requisitos:
- Carpeta 'tools' con 'arm-toolchain' y 'nrfutil.exe' en la raíz del repo.
- Git instalado (para utilidades Unix como mkdir, rm).
- 'make' instalado (vía Scoop o Choco).
#>

$ErrorActionPreference = "Stop"

# --- Configuración de Rutas ---
$ScriptDir = $PSScriptRoot
$ToolsDir = Join-Path $ScriptDir "tools"
$FirmwareDir = Join-Path $ScriptDir "firmware"
$AppDir = Join-Path $FirmwareDir "application"
$ObjDir = Join-Path $FirmwareDir "objects"

# Rutas específicas de herramientas
# Ajusta la versión del toolchain si cambia la carpeta descomprimida
$ArmBin = Join-Path $ToolsDir "arm-toolchain\arm-gnu-toolchain-12.2.rel1-mingw-w64-i686-arm-none-eabi\bin"
$NrfUtil = Join-Path $ToolsDir "nrfutil.exe"
$GitBin = "C:\Program Files\Git\usr\bin" # Necesario para comandos unix dentro del Makefile
$DfuKey = Join-Path $ScriptDir "resource\dfu_key\chameleon.pem"

# --- Verificaciones ---
Write-Host "Verificando herramientas..." -ForegroundColor Cyan

if (-not (Test-Path "$ArmBin\arm-none-eabi-gcc.exe")) {
Write-Error "No se encontró el compilador ARM en: $ArmBin"
exit 1
}

if (-not (Test-Path $NrfUtil)) {
Write-Error "No se encontró nrfutil en: $NrfUtil"
exit 1
}

# --- Configurar Entorno ---
Write-Host "Configurando entorno de compilación..."
# Añadimos ARM y Git/usr/bin al inicio del PATH
$env:PATH = "$ArmBin;$GitBin;$env:PATH"

# --- Compilar Aplicación ---
Write-Host "Compilando Aplicación (Make)..." -ForegroundColor Cyan
Push-Location $AppDir

try {
# Ejecutamos make. '-j' usa todos los núcleos para ir rápido.
make -j
if ($LASTEXITCODE -ne 0) { throw "Error en la compilación." }
}
finally {
Pop-Location
}

# --- Generar Paquete DFU ---
Write-Host "Generando paquete DFU (ZIP)..." -ForegroundColor Cyan

# Asegurar que existe directorio objects
if (-not (Test-Path $ObjDir)) { New-Item -ItemType Directory -Path $ObjDir | Out-Null }

$AppHex = Join-Path $ObjDir "application.hex"
$OutputZip = Join-Path $ObjDir "ultra-dfu-app.zip"

if (-not (Test-Path $AppHex)) {
Write-Error "No se encontró el archivo compilado: $AppHex"
exit 1
}

# Comando nrfutil para generar el paquete de actualización
& $NrfUtil pkg generate --hw-version 0 `
--key-file $DfuKey `
--application $AppHex `
--application-version 1 `
--sd-req 0x0100 `
$OutputZip

if ($LASTEXITCODE -eq 0) {
Write-Host "`n---------------------------------------------------" -ForegroundColor Green
Write-Host "¡ÉXITO! Firmware compilado y empaquetado." -ForegroundColor Green
Write-Host "Archivo listo para flashear: $OutputZip" -ForegroundColor Yellow
Write-Host "---------------------------------------------------"
} else {
Write-Error "Falló la generación del paquete DFU."
}
8 changes: 8 additions & 0 deletions firmware/application/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ SRC_FILES += \
$(PROJ_DIR)/utils/dataframe.c \
$(PROJ_DIR)/utils/delayed_reset.c \
$(PROJ_DIR)/utils/fds_util.c \
$(PROJ_DIR)/utils/ndef_gen.c \
$(PROJ_DIR)/utils/syssleep.c \
$(PROJ_DIR)/utils/timeslot.c \
$(SDK_ROOT)/modules/nrfx/mdk/gcc_startup_nrf52840.S \
Expand Down Expand Up @@ -336,6 +337,11 @@ LIB_FILES += \
ifeq (${CURRENT_DEVICE_TYPE}, ${CHAMELEON_ULTRA})
# Append reader module source code to compile list.
SRC_FILES +=\
$(PROJ_DIR)/rfid/emv.c \
$(PROJ_DIR)/rfid/desfire.c \
$(PROJ_DIR)/rfid/ntag_attack.c \
$(PROJ_DIR)/rfid/t5577_brute.c \
$(PROJ_DIR)/rfid/reader/hf/iso14443_4_transceiver.c \
$(PROJ_DIR)/rfid/reader/hf/mf1_toolbox.c \
$(PROJ_DIR)/rfid/reader/hf/rc522.c \
$(PROJ_DIR)/rfid/reader/lf/lf_125khz_radio.c \
Expand All @@ -345,6 +351,8 @@ ifeq (${CURRENT_DEVICE_TYPE}, ${CHAMELEON_ULTRA})
$(PROJ_DIR)/rfid/reader/lf/lf_t55xx_data.c \
$(PROJ_DIR)/rfid/reader/lf/lf_hidprox_data.c \
$(PROJ_DIR)/rfid/reader/lf/lf_viking_data.c \
$(PROJ_DIR)/rfid/reader/lf/fdx_b.c \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This includes the .c files but misses the header files, could be fixed by including the directory or the files one by one, would fix compilation issues

$(PROJ_DIR)/rfid/reader/lf/indala.c \

INC_FOLDERS +=\
${PROJ_DIR}/rfid/reader/ \
Expand Down
81 changes: 81 additions & 0 deletions firmware/application/src/app_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@
#include "settings.h"
#include "delayed_reset.h"
#include "netdata.h"
#include "emv.h"
#include "desfire.h"
#include "ntag_attack.h"
#include "ndef_gen.h"
#include "fdx_b.h"
#include "indala.h"
#include "t5577_brute.h"


#define NRF_LOG_MODULE_NAME app_cmd
Expand Down Expand Up @@ -490,6 +497,73 @@ static data_frame_tx_t *cmd_processor_mf1_write_one_block(uint16_t cmd, uint16_t

#if defined(PROJECT_CHAMELEON_ULTRA)

static data_frame_tx_t *cmd_processor_hf14a_scan_emv(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
char buffer[128];
bool result = emv_scan(buffer, sizeof(buffer));
uint16_t len = strlen(buffer);
if (result) {
return data_frame_make(cmd, STATUS_HF_TAG_OK, len, (uint8_t *)buffer);
} else {
return data_frame_make(cmd, STATUS_HF_ERR_STAT, len, (uint8_t *)buffer);
}
}

static data_frame_tx_t *cmd_processor_hf_desfire_scan(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
char buffer[128];
bool result = desfire_scan(buffer, sizeof(buffer));
uint16_t len = strlen(buffer);
if (result) {
return data_frame_make(cmd, STATUS_HF_TAG_OK, len, (uint8_t *)buffer);
} else {
return data_frame_make(cmd, STATUS_HF_ERR_STAT, len, (uint8_t *)buffer);
}
}

static data_frame_tx_t *cmd_processor_hf_ntag_brute(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
char buffer[128];
bool result = ntag_attack_run(buffer, sizeof(buffer));
uint16_t len = strlen(buffer);
if (result) {
return data_frame_make(cmd, STATUS_HF_TAG_OK, len, (uint8_t *)buffer);
} else {
return data_frame_make(cmd, STATUS_HF_ERR_STAT, len, (uint8_t *)buffer);
}
}

static data_frame_tx_t *cmd_processor_hf_ndef_gen_uri(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
// Input: URI String
if (length == 0) return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);

char uri[128] = {0};
memcpy(uri, data, length < 127 ? length : 127);

uint8_t buffer[256];
uint16_t gen_len = ndef_gen_uri(buffer, sizeof(buffer), uri);

return data_frame_make(cmd, STATUS_SUCCESS, gen_len, buffer);
}

static data_frame_tx_t *cmd_processor_lf_fdxb_scan(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
char buffer[128];
bool result = fdx_b_scan(buffer, sizeof(buffer));
uint16_t len = strlen(buffer);
return data_frame_make(cmd, result ? STATUS_LF_TAG_OK : STATUS_LF_TAG_NO_FOUND, len, (uint8_t *)buffer);
}

static data_frame_tx_t *cmd_processor_lf_indala_scan(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
char buffer[128];
bool result = indala_scan(buffer, sizeof(buffer));
uint16_t len = strlen(buffer);
return data_frame_make(cmd, result ? STATUS_LF_TAG_OK : STATUS_LF_TAG_NO_FOUND, len, (uint8_t *)buffer);
}

static data_frame_tx_t *cmd_processor_lf_t5577_brute(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
char buffer[128];
bool result = t5577_brute_run(buffer, sizeof(buffer));
uint16_t len = strlen(buffer);
return data_frame_make(cmd, result ? STATUS_LF_TAG_OK : STATUS_LF_TAG_NO_FOUND, len, (uint8_t *)buffer);
}

static data_frame_tx_t *cmd_processor_hf14a_set_field_on(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
device_mode_t mode = get_device_mode();
if (mode != DEVICE_MODE_READER) {
Expand Down Expand Up @@ -1599,13 +1673,20 @@ static cmd_data_map_t m_data_cmd_map[] = {
{ DATA_CMD_MF1_CHECK_KEYS_OF_SECTORS, before_hf_reader_run, cmd_processor_mf1_check_keys_of_sectors, after_hf_reader_run },
{ DATA_CMD_MF1_HARDNESTED_ACQUIRE, before_hf_reader_run, cmd_processor_mf1_hardnested_nonces_acquire, after_hf_reader_run },
{ DATA_CMD_MF1_CHECK_KEYS_ON_BLOCK, before_hf_reader_run, cmd_processor_mf1_check_keys_on_block, after_hf_reader_run },
{ DATA_CMD_HF14A_SCAN_EMV, before_hf_reader_run, cmd_processor_hf14a_scan_emv, after_hf_reader_run },
{ DATA_CMD_HF_DESFIRE_SCAN, before_hf_reader_run, cmd_processor_hf_desfire_scan, after_hf_reader_run },
{ DATA_CMD_HF_NTAG_BRUTE, before_hf_reader_run, cmd_processor_hf_ntag_brute, after_hf_reader_run },
{ DATA_CMD_HF_NDEF_GEN_URI, NULL, cmd_processor_hf_ndef_gen_uri, NULL },

{ DATA_CMD_EM410X_SCAN, before_reader_run, cmd_processor_em410x_scan, NULL },
{ DATA_CMD_EM410X_WRITE_TO_T55XX, before_reader_run, cmd_processor_em410x_write_to_t55xx, NULL },
{ DATA_CMD_HIDPROX_SCAN, before_reader_run, cmd_processor_hidprox_scan, NULL },
{ DATA_CMD_HIDPROX_WRITE_TO_T55XX, before_reader_run, cmd_processor_hidprox_write_to_t55xx, NULL },
{ DATA_CMD_VIKING_SCAN, before_reader_run, cmd_processor_viking_scan, NULL },
{ DATA_CMD_VIKING_WRITE_TO_T55XX, before_reader_run, cmd_processor_viking_write_to_t55xx, NULL },
{ DATA_CMD_LF_FDXB_SCAN, before_reader_run, cmd_processor_lf_fdxb_scan, NULL },
{ DATA_CMD_LF_INDALA_SCAN, before_reader_run, cmd_processor_lf_indala_scan, NULL },
{ DATA_CMD_LF_T5577_BRUTE, before_reader_run, cmd_processor_lf_t5577_brute, NULL },

{ DATA_CMD_HF14A_SET_FIELD_ON, before_reader_run, cmd_processor_hf14a_set_field_on, NULL },
{ DATA_CMD_HF14A_SET_FIELD_OFF, before_reader_run, cmd_processor_hf14a_set_field_off, NULL },
Expand Down
7 changes: 7 additions & 0 deletions firmware/application/src/data_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@
#define DATA_CMD_MF1_HARDNESTED_ACQUIRE (2013)
#define DATA_CMD_MF1_ENC_NESTED_ACQUIRE (2014)
#define DATA_CMD_MF1_CHECK_KEYS_ON_BLOCK (2015)
#define DATA_CMD_HF14A_SCAN_EMV (2016)
#define DATA_CMD_HF_DESFIRE_SCAN (2017)
#define DATA_CMD_HF_NTAG_BRUTE (2018)
#define DATA_CMD_HF_NDEF_GEN_URI (2019)

#define DATA_CMD_HF14A_SET_FIELD_ON (2100)
#define DATA_CMD_HF14A_SET_FIELD_OFF (2101)
Expand All @@ -91,6 +95,9 @@
#define DATA_CMD_HIDPROX_WRITE_TO_T55XX (3003)
#define DATA_CMD_VIKING_SCAN (3004)
#define DATA_CMD_VIKING_WRITE_TO_T55XX (3005)
#define DATA_CMD_LF_FDXB_SCAN (3006)
#define DATA_CMD_LF_INDALA_SCAN (3007)
#define DATA_CMD_LF_T5577_BRUTE (3008)

//
// ******************************************************************
Expand Down
83 changes: 83 additions & 0 deletions firmware/application/src/rfid/desfire.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#include "desfire.h"
#include "rc522.h"
#include "iso14443_4_transceiver.h"
#include "rfid_main.h"
#include <stdio.h>
#include <string.h>

bool desfire_scan(char *out_buffer, uint16_t max_len) {
picc_14a_tag_t tag;
uint8_t status;
uint8_t tx_buf[64];
uint8_t rx_buf[256];
uint16_t rx_len;

out_buffer[0] = '\0';

// Increase timeout
pcd_14a_reader_timeout_set(500);

// 1. Scan for card
status = pcd_14a_reader_scan_auto(&tag);
if (status != STATUS_HF_TAG_OK) {
snprintf(out_buffer, max_len, "No Card");
return false;
}

if (tag.ats_len == 0) {
snprintf(out_buffer, max_len, "Not DESFire (No ATS)");
return false;
}

iso14443_4_reset_block_num();

// 2. Get Version (0x60)
tx_buf[0] = 0x60;

if (iso14443_4_transceive(tx_buf, 1, rx_buf, &rx_len, sizeof(rx_buf))) {
// DESFire returns version in 3 frames usually (AF -> AF -> 00)
// Frame 1: HW Vendor, Type, Subtype, Version, Storage
if (rx_len > 0) {
uint8_t vendor = rx_buf[0];
uint8_t type = rx_buf[1];
uint8_t storage = rx_buf[5]; // 16=2k, 18=4k, 1A=8k usually (approx)

char type_str[20] = "Unknown";
if (type == 0x81) strcpy(type_str, "DESFire EV1");
else if (type == 0x82) strcpy(type_str, "DESFire EV2");
else if (type == 0x83) strcpy(type_str, "DESFire EV3");
else if (type == 0x88) strcpy(type_str, "DESFire Light");

snprintf(out_buffer, max_len, "%s (0x%02X), V:0x%02X, S:0x%02X", type_str, type, vendor, storage);

// Get more frames if status is 0xAF (More Data)
// We can stop here for basic info
}
} else {
snprintf(out_buffer, max_len, "GetVersion Failed");
return false;
}

// 3. Get Application IDs (0x6A)
tx_buf[0] = 0x6A;
if (iso14443_4_transceive(tx_buf, 1, rx_buf, &rx_len, sizeof(rx_buf))) {
if (rx_len > 0 && rx_buf[rx_len-1] == 0x00) { // Success
int apps = (rx_len - 1) / 3;
char temp[32];
snprintf(temp, sizeof(temp), ", Apps: %d", apps);
strncat(out_buffer, temp, max_len - strlen(out_buffer) - 1);

if (apps > 0) {
strncat(out_buffer, " [", max_len - strlen(out_buffer) - 1);
for (int i=0; i<apps && i<3; i++) { // Show first 3
uint32_t aid = (rx_buf[i*3] << 16) | (rx_buf[i*3+1] << 8) | rx_buf[i*3+2];
snprintf(temp, sizeof(temp), "%06lX ", (unsigned long)aid);
strncat(out_buffer, temp, max_len - strlen(out_buffer) - 1);
}
strncat(out_buffer, "]", max_len - strlen(out_buffer) - 1);
}
}
}

return true;
}
9 changes: 9 additions & 0 deletions firmware/application/src/rfid/desfire.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef DESFIRE_H
#define DESFIRE_H

#include <stdint.h>
#include <stdbool.h>

bool desfire_scan(char *buffer, uint16_t max_len);

#endif
Loading
Loading