DÍA 245 DE 365

Fase 5: Diseño Industrial y Proyecto Final

📖 Teoría a Estudiar

La Anatomía de una Tarjeta Mifare Classic 1K (13.56 MHz)

A diferencia de las viejas tarjetas de 125 kHz que solo "escupían" un número fijo, las tarjetas Mifare (estándar ISO/IEC 14443A) son computadoras microscópicas con memoria EEPROM y procesadores criptográficos internos.

Tienen 1 Kilobyte de memoria dividido en 16 Sectores. Cada Sector tiene 4 Bloques (de 16 bytes cada uno). La magia ocurre en el último bloque de cada sector (El Bloque Tráiler). Este bloque no guarda datos; guarda dos contraseñas secretas de 48 bits: la Key A y la Key B.

El Sector 0 contiene el UID (Número de Serie único). Este sector NO tiene clave y es público. Por eso, leer el UID es trivial e inseguro.

El Algoritmo de Autenticación Criptográfica

Para crear un sistema seguro, tu Despachador jamás confiará en el UID. En su lugar, el algoritmo industrial es el siguiente:

  1. El usuario acerca la tarjeta. El STM32 lee el UID (solo lo usamos para saber que hay alguien ahí).
  2. El STM32 le dice a la tarjeta: "Quiero leer tus datos de saldo en el Sector 4. Aquí está mi llave secreta (Key A)."
  3. El lector RFID y la tarjeta realizan un apretón de manos criptográfico (Desafío-Respuesta). La llave no viaja en texto plano por el aire, se usan números aleatorios (Nonce) para evitar ataques de repetición (Replay Attacks).
  4. Solo si la tarjeta reconoce la Llave A como correcta, le permite al STM32 leer el Bloque de datos reales (ej. "Cliente VIP Gasolinera 45").
VULNERABILIDAD UID VS AUTENTICACIÓN POR SECTOR (MIFARE) AMATEUR: LECTURA DE UID (VULNERABLE) Tarjeta "Magic" UID Clonado: 4A:F2:C1 Solo lee el C.I. Despachador Gas if(UID == 4A:F2:C1) Abrir Valvula() ¡ROBO EXITOSO! El ladrón engañó a la máquina. Costo del fraude: Infinito. INDUSTRIAL: AUTENTICACIÓN CRYPTO1 (SEGURO) Tarjeta Falsa UID Clonado: 4A:F2:C1 Sec. 4 Key A = (Vacía/Falsa) Desafío (Nonce) Validación Key A ACCESO DENEGADO Despachador Gas 1. Ignorar UID. 2. Pedir Crypto_Auth(Sector 4, KEY_A) SISTEMA BLINDADO La tarjeta falsa no tiene la llave secreta. Gasolinera segura. Alarma enviada.

⚙️ Ejercicios Prácticos

Circuito (Módulo RFID vía SPI): Los módulos lectores industriales (como el chip NXP MFRC522 o PN532) se comunican con el STM32 usando el bus SPI (Serial Peripheral Interface). Son 4 líneas de datos (MISO, MOSI, SCK, CS). Sin embargo, la regla de oro del bajo consumo y RTOS es usar el pin de Interrupción (IRQ) del módulo. Nunca hagas *Polling* infinito leyendo el SPI para ver si hay tarjeta; conecta el pin IRQ del lector a un pin de interrupción (EXTI) de tu STM32. Así, el microcontrolador duerme tranquilamente hasta que el hardware de radio detecta una antena acercándose.

Ejercicio 1: Máquina de Estados Criptográfica MISRA-C. Programaremos el proceso de autenticación. Este flujo debe ser estricto: Detección -> Petición Crypto1 -> Lectura de Memoria -> Validación de Datos (Checksum interno).


/**
 * @file rfid_mifare_auth.c
 * @brief Tarea RTOS de Autenticación Criptográfica RFID (Mifare 1K) - MISRA-C
 */

#include "stm32f401xe.h"
#include "cmsis_os2.h"
#include <stdint.h>
#include <stdbool.h>

// =========================================================================
// DEFINICIONES CRIPTOGRÁFICAS DE FLOTILLA (SECRETO INDUSTRIAL)
// =========================================================================
// Nunca uses la llave por defecto (0xFF 0xFF 0xFF 0xFF 0xFF 0xFF)
// Esta llave debe inyectarse encriptada desde AWS, pero la definimos como constante para el ejemplo.
static const uint8_t LLAVE_A_EMPRESA[6] = {0x4A, 0x9B, 0xC1, 0x33, 0xF2, 0x88};

// Elegimos un sector aleatorio (ej. Sector 4) para guardar los datos.
// El Sector 4 abarca los Bloques 16, 17, 18 y el Trailer 19.
#define SECTOR_FLOTILLA         (4U)
#define BLOQUE_DATOS_CLIENTE    (16U)

// =========================================================================
// MÁQUINA DE ESTADOS RFID
// =========================================================================
typedef enum {
    RFID_ESTADO_DORMIDO     = 0U,
    RFID_ESTADO_DETECTANDO  = 1U,
    RFID_ESTADO_AUTENTICANDO= 2U,
    RFID_ESTADO_LEYENDO     = 3U,
    RFID_ESTADO_RECHAZADO   = 4U
} RFID_FSM_t;

// Bandera levantada por la interrupción de hardware del chip RC522 (Pin IRQ)
extern osEventFlagsId_t rfid_event_flag;
#define FLAG_TARJETA_PRESENTE   (1U << 0)

// =========================================================================
// TAREA RTOS DE CONTROL DE ACCESO
// =========================================================================
void Task_RFID_ControlAcceso(void *argument) {
    
    RFID_FSM_t estado_rfid = RFID_ESTADO_DORMIDO;
    uint8_t buffer_lectura[16];
    uint8_t uid_tarjeta[4];
    
    // Iniciar Módulo RC522 vía SPI (Configura ganancia de antena e interrupciones)
    RC522_Init_SPI();
    
    for(;;) {
        switch (estado_rfid) {
            
            case RFID_ESTADO_DORMIDO:
                // El procesador bloquea esta tarea hasta que el PIN IRQ del Módulo RFID se active.
                // Consumo de CPU: 0%.
                osEventFlagsWait(rfid_event_flag, FLAG_TARJETA_PRESENTE, osFlagsWaitAny, osWaitForever);
                estado_rfid = RFID_ESTADO_DETECTANDO;
                break;
                
            case RFID_ESTADO_DETECTANDO:
                // Leemos el UID. No nos importa para la seguridad, pero es necesario
                // pasárselo a la función de autenticación criptográfica.
                if (RC522_AntiCollision_ReadUID(uid_tarjeta) == MFRC522_STATUS_OK) {
                    estado_rfid = RFID_ESTADO_AUTENTICANDO;
                } else {
                    estado_rfid = RFID_ESTADO_RECHAZADO; // Tarjeta se alejó muy rápido
                }
                break;
                
            case RFID_ESTADO_AUTENTICANDO:
                // PASO CRÍTICO: Solicitamos al chip RFID que ejecute el algoritmo Crypto1
                // intentando abrir el Sector 4 usando nuestra Llave A secreta.
                uint8_t status_auth = RC522_Authenticate(
                    PICC_CMD_MF_AUTH_KEY_A, 
                    BLOQUE_DATOS_CLIENTE, 
                    (uint8_t*)LLAVE_A_EMPRESA, 
                    uid_tarjeta
                );
                
                if (status_auth == MFRC522_STATUS_OK) {
                    estado_rfid = RFID_ESTADO_LEYENDO;
                } else {
                    // La tarjeta es de otra gasolinera, o es un clon "Magic" sin la llave.
                    estado_rfid = RFID_ESTADO_RECHAZADO;
                }
                break;
                
            case RFID_ESTADO_LEYENDO:
                // Si llegamos aquí, el sector está descifrado y abierto.
                if (RC522_ReadBlock(BLOQUE_DATOS_CLIENTE, buffer_lectura) == MFRC522_STATUS_OK) {
                    
                    // Extraemos los datos (ej. ID de Flotilla, Saldo Prepago)
                    uint32_t id_cliente_hex = (buffer_lectura[0] << 24) | (buffer_lectura[1] << 16) | 
                                              (buffer_lectura[2] << 8)  | buffer_lectura[3];
                    
                    // Autorizamos el Despacho
                    // Despachador_Habilitar_Venta(id_cliente_hex);
                    
                    // Imprimimos en Pantalla LCD
                    // LCD_Mostrar_Mensaje("Acceso Autorizado");
                }
                
                // MISRA-C: SIEMPRE detener la sesión criptográfica para que no quede abierta.
                RC522_StopCrypto1();
                estado_rfid = RFID_ESTADO_DORMIDO;
                break;
                
            case RFID_ESTADO_RECHAZADO:
                // LCD_Mostrar_Mensaje("Tarjeta Invalida!");
                RC522_StopCrypto1(); // Por seguridad
                
                // Un pequeño delay para evitar que pite 10 veces por segundo
                osDelay(pdMS_TO_TICKS(1000U)); 
                estado_rfid = RFID_ESTADO_DORMIDO;
                break;
                
            default:
                estado_rfid = RFID_ESTADO_DORMIDO;
                break;
        }
    }
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Control de Acceso Criptográfico y Gestión de Flotillas (B2B).

El mercado de las gasolineras está saturado. La forma en que las empresas despachadoras ganan millones hoy en día es ofreciendo contratos corporativos (B2B) a empresas con flotillas de camiones repartidores (ej. Bimbo, Coca-Cola). El administrador de la flotilla no quiere darle dinero en efectivo a sus choferes; quiere que lleguen a tu máquina de Gas LP, pongan una tarjeta RFID y carguen gas. Al final del mes, el sistema en la nube factura todo automáticamente.

Si construyes tu máquina leyendo el UID de la tarjeta (el error de los novatos), un chofer malicioso puede clonar su tarjeta con su celular Android (NFC), dársela a sus amigos y robar gas a cuenta de la empresa corporativa. Tú serías el responsable legal del robo por tener un hardware vulnerable. Al implementar **Autenticación de Sectores Criptográficos Mifare (Crypto1/AES)**, fuerzas al lector RFID de la placa a exigir una contraseña oculta que no puede ser clonada copiando el número de serie. Tu diseño de hardware acaba de habilitar un modelo de negocio Multi-Millonario (Gestión de Flotillas) blindado contra fraudes. Ese es el valor de la ingeniería segura.

📝 Resumen del Día