Un sistema de punto de venta físico suele protegerse instalando un Micro-Switch (Interruptor de límite) en la puerta del chasis del equipo. Cuando la puerta está cerrada, el switch presiona un botón y mantiene un circuito cerrado.
El procesador STM32 tiene un pin especial diseñado exactamente para esto, usualmente enrutado en el pin PC13, llamado TAMP1 (Tamper 1). A diferencia de un GPIO normal (que necesita que el Cortex-M esté despierto y ejecutando un while(1) para ser leído), el pin TAMP pertenece al Dominio de Respaldo (VBAT). Funciona consumiendo micro-amperios directamente de la pila de botón CR2032.
El hardware del Tamper es despiadado. Si el ladrón corta la luz de la gasolinera para apagar tu software, y luego intenta forzar la puerta del chasis con una palanca, el micro-switch liberará el pin PC13, cambiando su voltaje. En una fracción de nanosegundo, el hardware interno del STM32 reaccionará sin ejecutar ni una sola línea de código C:
0x00000000).0xCAFE del Día 142) será destruido.Ejercicio 1: Configuraremos el hardware del pin de Tamper sobre PC13. Asumiremos que tenemos un microswitch a tierra con una resistencia Pull-Up conectada a la pila VBAT. Cuando se abre la puerta, la línea salta de 0V a 3V. Le pediremos al RTC que vigile este Flanco de Subida (Rising Edge) y que, al dispararse, active una Interrupción EXTI para el sistema en caso de que la luz principal esté encendida.
/**
* @file anti_tamper.c
* @brief Configuración Bare-Metal del hardware de defensa física (Pin TAMP1)
*/
#include "stm32f401xe.h"
#include <stdbool.h>
extern void habilitar_acceso_backup_domain(void); // Del Día 142
// Variables lógicas del sistema
volatile bool maquina_comprometida = false;
extern uint64_t totalizador_historico_ml; // Del Día 142
/**
* @brief Arma la trampa física en el pin PC13
*/
void inicializar_defensa_tamper(void) {
// 1. Desbloquear el dominio de respaldo (PWR DBP = 1)
habilitar_acceso_backup_domain();
// 2. Apagar temporalmente el Tamper para poder configurarlo sin dispararlo por error
// El control del Tamper se aloja en el registro TAFCR del RTC
RTC->TAFCR &= ~RTC_TAFCR_TAMP1E; // Tamper 1 Enable = 0
// 3. Configurar la polaridad (El gatillo)
// TAMP1TRG = 0: Se dispara cuando la señal SUBE (Rising Edge, 0V a 3.3V)
// TAMP1TRG = 1: Se dispara cuando la señal BAJA (Falling Edge, 3.3V a 0V)
// Nuestro switch NC a GND manda un "1" cuando se abre la puerta. (Rising Edge)
RTC->TAFCR &= ~RTC_TAFCR_TAMP1TRG;
// 4. Habilitar Interrupciones (Por si el procesador VDD está encendido)
// Cuando el TAMP se dispare, avisará al procesador.
RTC->TAFCR |= RTC_TAFCR_TAMPIE; // Tamper Interrupt Enable
RTC->TAFCR |= RTC_TAFCR_TAMP1IE; // Tamper 1 Interrupt Enable
// IMPORTANTE: La interrupción del Tamper viaja al NVIC a través
// de la línea EXTI 21 del controlador de interrupciones externas.
EXTI->IMR |= EXTI_IMR_MR21;
EXTI->RTSR |= EXTI_RTSR_TR21; // Sensible a flanco de subida
NVIC_SetPriority(TAMP_STAMP_IRQn, 0); // ¡Prioridad Máxima del Sistema!
NVIC_EnableIRQ(TAMP_STAMP_IRQn);
// 5. ENCENDER Y ARMAR LA DEFENSA FÍSICA
RTC->TAFCR |= RTC_TAFCR_TAMP1E;
}
/**
* @brief Vector de Interrupción Exclusivo de Tamper y TimeStamp
* Si el CPU está encendido durante el asalto, esta función se ejecuta.
* Si el CPU está apagado, el hardware de todos modos borra la BKP.
*/
void TAMP_STAMP_IRQHandler(void) {
// Comprobar que la causa de la interrupción fue el TAMP1
if (RTC->ISR & RTC_ISR_TAMP1F) {
// ¡Alerta Roja! Hardware Compromised!
maquina_comprometida = true;
// El hardware ya ha destruido los registros BKP de forma automática.
// Como medida adicional en el software, ponemos el totalizador a cero
// en la memoria RAM volátil para evitar que la máquina siga facturando.
totalizador_historico_ml = 0;
// Limpiar las banderas atómicamente
RTC->ISR &= ~RTC_ISR_TAMP1F; // Bajar bandera del RTC
EXTI->PR |= EXTI_PR_PR21; // Bajar bandera del EXTI
}
}
int main(void) {
// (Inicialización Cero: Del Día 142)
// cargar_variables_desde_bkp();
// Si la firma es basura (0x0000), significa que la máquina es virgen
// O bien, que alguien violó la puerta y el hardware borró todo.
if (RTC->BKP2R != 0xCAFE) {
// Enviar log por RS485 para notificar al servidor central (Día 139)
// LOG_ERROR("VIOLACION BKP DETECTADA", 0);
maquina_comprometida = true;
}
// Armar el seguro para futuras intrusiones
inicializar_defensa_tamper();
while(1) {
if (maquina_comprometida) {
// BLOQUEO TOTAL METROLÓGICO
// lcd_escribir_cadena("SISTEMA BLOQUEADO ");
// VALVULA_CERRADA();
// while(1); // Detener el firmware. Requiere servicio técnico autorizado.
}
// Despacho normal de Gas...
}
return 0;
}
Objetivo del día: Certificación de Seguridad Nivel Fiscal (NOM-005).
El fraude más sofisticado en las gasolineras no se hace hackeando el software mediante Modbus. Se hace mediante el robo de la electrónica. Un empleado corrupto desconecta la corriente principal a las 3:00 AM, rompe los sellos de plomo del gabinete, abre la placa, y con unos cables puentea voltaje a los chips de memoria para resetear el odómetro. Cuando la luz vuelve a las 4:00 AM, la máquina parece perfecta, pero acaban de "desaparecer" 10,000 litros de gas del inventario contable.
Al implementar el circuito de **Tamper (TAMP1)** en tu STM32, has dotado a tu sistema de una alarma que no duerme. Alimentada puramente por la pila CR2032 de respaldo, el circuito monitorea microscópicas caídas de voltaje de un micro-switch en el chasis de tu Despachador. Si el vándalo abre la puerta en medio de la oscuridad, el procesador ARM reacciona de forma refleja e instintiva y aniquila todo su Dominio de Respaldo. El vándalo se queda con una placa inútil. Cuando el sol sale y el gerente enciende la estación, la pantalla del equipo mostrará `SISTEMA BLOQUEADO`, revelando el intento de robo innegablemente.
VDD, consumiendo energía pasivamente del pin VBAT.TAMP1F, y genera una interrupción de altísima prioridad a través de la línea EXTI 21, permitiendo al software vivo tomar acciones inmediatas como bloquear válvulas, inhabilitar memorias Flash, o alertar al SCADA.