
Un marco criptográfico para Baochip-1x.

Este proyecto está registrado en la Open Invention Network (OIN). OIN es un pool de patentes defensivo: los miembros otorgan licencias cruzadas de patentes relacionadas con Linux para que los participantes puedan distribuir y usar software de código abierto con menor exposición a patentes.
Estado: En espera de: https://github.com/betrusted-io/xous-core/pull/937
Firmware para dispositivos Baochip-1x (placa de evaluación Dabao) que ejecutan el
microkernel Xous, compilado
para riscv32imac-unknown-none-elf.
Se encuentra aquí: https://www.baochip.com/
El dispositivo es un token de seguridad de hardware en la misma categoría que los dispositivos de clase Nitrokey, con comportamiento de tarjeta inteligente de clase OpenPGP y una bóveda cifrada. Toda la pila de hardware — RTL, esquemáticos, bootloader, SO — es de código abierto y auditable.
La especificación de hardware, el modelo de arranque, las tablas de requisitos y el uso de ComboHash/PKE están documentados en Supermagnum/Baochip-1x-firmware. La placa de evaluación Dabao (KiCad, esquemáticos, interruptores, pinout) está en baochip/dabao. Para entrar en modo bootloader para el flashing, pulsa SW2 para alternarlo (consulta el esquemático de ese repositorio). Notas de arquitectura para este repositorio: docs/ARCHITECTURE.md.
La herramienta de host Galdra mantiene un directorio SQLite local de destinatarios (contactos). Cada identidad almacenada incluye material de clave pública más etiquetas laterales opcionales (consulta la tabla siguiente). Estas etiquetas viven en la base de datos del host y, para claves Galdra, en el almacén de contactos en chip (crates/contact-store). No están vinculadas mágicamente a los IDs de usuario OpenPGP a menos que las alinees tú mismo, y no se afirman criptográficamente a menos que las verifiques fuera de banda. El galdra keyserver push opcional puede enviar campos superpuestos a un registro del proyecto como JSON junto con la clave pública exportada. La procedencia por campo en el token utiliza SelfAttested, HostVerified, RegistrySync y OobVerified (consulta Comparación de metadatos (GnuPG vs Galdra) y el diseño del almacén de contactos en docs/RRAM_LAYOUT.md).
Detalles del lado del host y comportamiento de CLI: docs/GALDRA-TOOL.md. Diseño del cable y recuentos de ranuras: crates/contact-store/src/layout.rs y docs/RRAM_LAYOUT.md.
Este firmware es un token de seguridad de hardware para Baochip-1x: una aplicación de tarjeta OpenPGP sobre USB CCID, con una bóveda en el dispositivo, política de PIN y características específicas del repositorio (perfiles de cifrado — puedes apilar hasta cuatro cifrados simétricos diferentes en una sola cascada, cada uno con su propia clave derivada; consulta Capacidades clave), flujos relacionados con Shamir, ECDH efímero autenticado donde está implementado, y herramientas de host Galdra). El objetivo principal de interoperabilidad es el uso de tarjetas OpenPGP de estilo GnuPG, no todos los protocolos de token del mercado.
Este firmware no es:
Las exclusiones a nivel de crate alineadas con las mismas restricciones se enumeran en Crates Explícitamente Excluidos en docs/future-todo.md.
CESS: Este firmware cumple con CESS para las construcciones normativas implementadas en el árbol (incluyendo Modo A AEAD externo, HKDF-BLAKE3 para K_outer, y división Shamir byte a byte GF(2^8)). La declaración completa de alineación, el registro de desviaciones y el nivel de certificación (por ejemplo CESS-CORE para la capa fija completa) están documentados en docs/CESS_CONFORMANCE.md y CESS (estándar abierto relacionado) más abajo.
La lógica de aplicación OpenPGP / CCID está en crates/usb-personality. En Xous, el servicio USB que expone CCID es usb-bao1x (en tu checkout de xous-core), compilado con la característica ccid-openpgp, usando crates/baochip-openpgp para la ventana RRAM OpenPGP y el aprovisionamiento. Diseño: docs/RRAM_LAYOUT.md. Brechas de preproducción (UX de PIN de operador, aprobación del mapa de plataforma): Limitaciones conocidas / trabajo abierto.
El objetivo general sigue siendo un firmware completo, probado y de código abierto de token de seguridad de hardware: comportamiento de estilo tarjeta OpenPGP para GnuPG sobre CCID (consulta Compatibilidad OpenPGP y GnuPG), más características adicionales en el dispositivo no definidas actualmente por el estándar de tarjeta OpenPGP — ECDH efímero con secreto hacia adelante, Shamir K-de-N, perfiles agnósticos de cifrado, volumen señuelo microSD — como se resume en Estándares vs. características específicas del firmware. Todo sobre RTL abierto con un bootloader reproducible.
Para despliegues que necesitan dos tokens físicos separados (o titulares de acciones K-de-N) antes de desbloquear servidores, cortafuegos, bóvedas de medicamentos o volúmenes cifrados, consulta Quórum de doble clave de hardware (patrón integrador) en Capacidades clave. Cada dispositivo es una fuente de credenciales; la aplicación del quórum es tu puerta de acceso, capa PAM o panel — no este firmware.
El firmware distribuible para Baochip-1x está firmado con Ed25519. Firmas la imagen del firmware con una clave privada Ed25519; GnuPG puede hacer esto con gpg --sign usando una subclave de firma Ed25519 (el flujo de trabajo habitual de firma separada OpenPGP, adaptado al empaquetado que emita tu compilación). La ROM inmutable boot0 en el SoC verifica esa firma contra las claves públicas correspondientes grabadas en el dispositivo (y el manifiesto de claves más amplio para la cadena de arranque) antes de que se permita ejecutar la siguiente etapa — boot1. boot1 luego carga imágenes de aplicación firmadas (por ejemplo blobs UF2 entregados sobre almacenamiento masivo USB en modo bootloader). Las piezas predeterminadas llevan cuatro claves públicas Ed25519 en chip (roles como despliegue de código, beta y desarrollador); boot0 / boot1 aplican una política de desconfianza mutua entre Baochip y las claves de firma de terceros. Flujo de arranque completo, entrega UF2, consola, actualizaciones de boot1 y modelo de seguridad: Getting Started with Baochip Targets en xous-core.
No todas las pruebas se ejecutan en cada comando; eso es intencional.
xtask no está en la prueba predeterminada del workspace: La receta común es cargo test --workspace --exclude xtask porque xtask es un crate de orquestación de compilación. Ejecuta cargo test -p xtask cuando quieras sus pruebas.#[ignore]: Se omiten a menos que pases --ignored (y cualquier filtro de crate necesario). Las razones incluyen: cobertura que ya se ejercita en pruebas unitarias enfocadas (p. ej. zeroización posterior a drop), casos lentos (p. ej. generación de claves RSA) y flujos dependientes de hardware o token en herramientas de host como galdra que necesitan un dispositivo conectado o fixtures.test-all --no-fuzz: Omite el paso de cargo-fuzz para mantener CI o ejecuciones rápidas cortas y para evitar requerir un toolchain nightly para ese paso; ejecuta cargo run -p xtask -- test-all sin --no-fuzz, o invoca los objetivos de fuzzing por separado (consulta ).También se puede comprobar la integridad de los crates con esto cuando el PR esté cerrado: https://github.com/rust-lang/cargo/issues/16850
Estado: Listo para pruebas por humanos, en hardware real — no existe una versión lista para producción. Está escrito en Rust usando crates criptográficos validados y auditados. Las primitivas criptográficas se extraen exclusivamente de dependencias auditadas del workspace. Los algoritmos post-cuánticos están activados por características y marcados AUDITORÍA INDEPENDIENTE PENDIENTE. Consulta Estado post-cuántico.
Nota: Partes de este proyecto se desarrollaron con asistencia de IA (Claude, Anthropic). El diseño, las elecciones criptográficas y las decisiones de seguridad no han sido revisados por un criptógrafo profesional. Trata esto como un proyecto experimental y aplica tu propio juicio crítico. Se recomienda encarecidamente una revisión independiente por expertos antes de cualquier despliegue en producción.
Está listo para pruebas por humanos. Tú decides si compilar o ejecutar cualquiera de este software; puede haber errores que las pruebas unitarias, el fuzzing y otras comprobaciones no hayan encontrado. Usar una máquina virtual opcional para experimentación reduce el riesgo para tu sistema host pero no lo elimina. Los resultados detallados están en Resultados de pruebas (docs/TEST_RESULTS.md#run-metadata). Definiciones en lenguaje sencillo (A–Z) de términos técnicos: Glosario.
El desarrollador principal tiene una condición neurológica relacionada con la discalculia. La discalculia afecta el sentido numérico y el procesamiento simbólico relacionado de maneras que, para ellos, hacen que la programación tradicional — la edición de código escrita a mano como único flujo de trabajo — no sea viable sin herramientas asistidas (por ejemplo editores de IA conversacionales). Esa restricción es distinta de la corrección: los revisores deberían sopesar igualmente las pruebas, el fuzzing y la auditoría independiente como se documenta en otra parte de esta página.
Un criptógrafo o implementador serio que revise Galdralag normalmente abrirá crates/vault/tests/ y crates/cipher-profile/tests/ antes de leer prosa. La suite de pruebas es la prueba de trabajo: codifica conocimiento de dominio que no puede sustituirse solo con narrativa.
Esa no es una razón para ocultar el punto a todos los demás. Las personas que evalúan el proyecto para adquisición, deciden si contribuir o envían código sin formación profunda en metodología de pruebas criptográficas todavía merecen una referencia a la evidencia concreta.Qué mirar: El material de conformidad incluye ejemplos trabajados del RFC 8439 para ChaCha20-Poly1305 en crates/vault/tests/rfc_vectors/, JSON de Wycheproof incluido para casos límite de ChaCha20-Poly1305 y Brainpool ECDH/ECDSA en crates/vault/tests/data/wycheproof/, vectores BSI TR-03111 para BrainpoolP256r1 y P384r1 en crates/vault/tests/bsi_vectors/, vectores de referencia oficiales de BLAKE3 (las 35 longitudes de entrada, los tres modos) en crates/vault/tests/blake3_vectors.json, vectores de especificación de Twofish (1203 casos, incluido Monte Carlo) en crates/vault/tests/twofish_vectors.json, y el propio fixture KAT de la cascada CESS del proyecto con intermediarios verificados de forma independiente en crates/cipher-profile/tests/fixtures/cascade_cess_kat.json. Juntos, estos son la fuente de verdad que el ejecutor y los revisores pueden ejercitar con cargo test --workspace y python3 scripts/verify_cascade_kats.py.
RFC 8439 está publicado por el Internet Engineering Task Force (IETF), la organización que estandariza gran parte de cómo interoperan las redes. Los RFC (Request for Comments) son la forma habitual de las especificaciones de protocolos y de muchas especificaciones criptográficas. El RFC 8439 define el cifrado autenticado ChaCha20-Poly1305 (basándose en los diseños de Daniel Bernstein) e incluye ejemplos trabajados concretos con entradas y salidas esperadas específicas para que las implementaciones independientes puedan comprobar que coinciden con el estándar byte a byte. El texto plano ampliamente reproducido que comienza con Ladies and Gentlemen of the class of '99: wear sunscreen aparece en los ejemplos del apéndice del RFC: si tu código reproduce exactamente la salida AEAD, tienes una comprobación sólida de que implementaste la construcción correctamente. Es el análogo criptográfico de una clave de respuestas oficial. ChaCha20-Poly1305 es la capa interna de cada perfil de cascada multicapa de este firmware, por lo que esta comprobación se encuentra en la base de toda la pila de cifrado.
Wycheproof es un corpus de pruebas publicado por el equipo de seguridad de Google (2017). El nombre hace referencia al Monte Wycheproof en Australia — a menudo citado como la montaña más pequeña del mundo — porque el proyecto se centra en superar obstáculos pequeños pero fatales: desbordamientos de enteros, casos límite, entradas malformadas y etiquetas de autenticación manipuladas; fallos que aparecen repetidamente en criptografía real desplegada. Complementa los vectores de estilo RFC: los ejemplos de estilo RFC 8439 demuestran la corrección frente al AEAD publicado; Wycheproof pone a prueba la robustez donde históricamente fallan las implementaciones. En este repositorio, el JSON de Wycheproof cubre ChaCha20-Poly1305, AES-GCM, HMAC, HKDF, X25519, Ed25519, RSA y variantes de Brainpool ECDH/ECDSA.
BSI TR-03111 es la guía técnica para criptografía de curva elíptica publicada por la Oficina Federal Alemana de Seguridad de la Información (Bundesamt für Sicherheit in der Informationstechnik). La versión 2.10 es la revisión actual. Las curvas Brainpool utilizadas en este firmware — P256r1 y P384r1 — están especificadas en los estándares BSI, lo que convierte a TR-03111 en la referencia natural para sus vectores de prueba. Cada curva tiene cobertura de ECDH y ECDSA; las firmas ECDSA se contrastaron adicionalmente con una implementación independiente en Python que utiliza la librería cryptography.
Vectores de referencia de BLAKE3 son el corpus de pruebas oficial publicado junto con la especificación de BLAKE3 por sus autores. Cubren 35 longitudes de entrada de 0 a 102400 bytes, elegidas específicamente para ejercitar todas las condiciones límite internas de fragmentos y hash de árbol que son invisibles para pruebas de entradas cortas. Los tres modos de BLAKE3 — hash predeterminado, hash con clave y derivación de clave — están cubiertos. BLAKE3 se utiliza en todo este firmware para la derivación de claves HKDF y las comprobaciones de integridad entre capas en los perfiles de cifrado en cascada; la cobertura de límites importa porque la construcción de árbol de BLAKE3 solo se activa por encima de 1024 bytes.
El conjunto de pruebas también es detección de manipulación para la cadena de suministro. Todos los primitivos criptográficos de este firmware provienen de crates RustCrypto auditados — no se implementa criptografía dentro del árbol. Debido a que los vectores de conformidad anteriores se ejecutan contra esos crates en cada cargo test --workspace, cualquier dependencia que haya sido manipulada o sustituida producirá un fallo de prueba de respuesta conocida antes de que el código comprometido llegue a un sistema desplegado. python3 scripts/verify_cascade_kats.py añade una segunda vía independiente: una implementación en Python comprueba los mismos valores intermedios en el fixture KAT de la cascada, de modo que incluso una cadena de herramientas Rust comprometida que produzca una salida incorrecta es detectada por la verificación cruzada. Esto es una historia de integridad de cadena de suministro significativamente más sólida que vincularse a una librería C, donde la verificación equivalente de cada operación interna requiere considerablemente más esfuerzo y herramientas especializadas.
Ahora corresponde al lector juzgar si estas afirmaciones son falsas o no.
Lo conectas a un puerto USB. Desde la perspectiva del host, el firmware puede presentar modo criptográfico o modo camuflaje. En modo criptográfico, tu ordenador ve una tarjeta inteligente: usas GnuPG o una pila OpenPGP compatible (¿Qué es GnuPG?) igual que usarías cualquier otro token de seguridad de hardware — el token maneja las operaciones criptográficas sensibles para que tus claves privadas nunca existan sin protección en tu ordenador. En modo camuflaje puede enumerarse como almacenamiento extraíble ordinario con archivos de apariencia inocua para que una mirada rápida no revele su función real; consulta Camuflaje de almacenamiento más abajo.
GnuPG significa GNU Privacy Guard. Es la implementación del proyecto GNU de OpenPGP, el estándar abierto para gestión de claves y mensajes protegidos criptográficamente (la misma familia conceptual que PGP, pero especificada en documentos como el RFC 4880 y actualizaciones de la comunidad). Normalmente lo ejecutas como el comando gpg en Linux, BSD, macOS o Windows; muchas utilidades gráficas de correo y claves lo usan internamente.
La gente usa GnuPG para:
gpg-agent expone claves de autenticación desde una tarjeta inteligente o un almacén de claves local.GnuPG y discos cifrados (LUKS). Linux tiene una forma integrada de cifrar un disco o partición completo, llamada LUKS. Una vez que un disco está cifrado, parece ruido sin sentido para cualquiera sin la clave, por lo que un portátil perdido o robado no entrega tus archivos.
Normalmente desbloqueas ese tipo de disco escribiendo una contraseña. GnuPG te permite usar tu token en su lugar. La idea es simple: la clave de desbloqueo del disco está a su vez bloqueada con la clave de tu token. Cuando quieres abrir el disco, el token descifra esa clave de desbloqueo por ti, pero solo mientras el token esté conectado y hayas introducido tu PIN. Retira el token y el disco no puede abrirse en absoluto, incluso en el mismo ordenador.
En resumen, esto convierte el token en una llave física para tu disco cifrado. Configurarlo (y añadir una vía de respaldo, en caso de que el token se pierda alguna vez) se hace con las propias herramientas de disco de Linux; el token simplemente guarda la clave. Si prefieres compartir la capacidad de desbloquear un disco entre varias personas, de modo que nadie pueda hacerlo solo, consulta Compartición de secretos Shamir y cifrado de discos.
Por defecto, GnuPG almacena las claves en ~/.gnupg. Con una tarjeta inteligente OpenPGP, las claves privadas sensibles viven en la tarjeta; scdaemon (parte del conjunto GnuPG) habla CCID/USB con la tarjeta mientras gpg sigue ensamblando los paquetes OpenPGP en el host.
Para qué puedes usarlo. En modo criptográfico, el token está pensado para el mismo trabajo que otras tarjetas inteligentes OpenPGP: firmar y descifrar correo y archivos, autenticar (por ejemplo SSH cuando usas gpg-agent como de costumbre) y mantener claves privadas a largo plazo fuera de la máquina en la que escribes. Las organizaciones pueden combinar eso con acciones Shamir en el token para que ninguna persona tenga el secreto completo (descrito más adelante). GnuPG es el objetivo principal de interoperabilidad en el host: este firmware implementa la aplicación de tarjeta OpenPGP sobre CCID, que scdaemon maneja (gpg --card-status, gpg --card-edit y cifrado/firma/descifrado normales con claves en la tarjeta). Otro software que hable los mismos protocolos de tarjeta inteligente puede funcionar también; comandos, ranuras, algoritmos y límites de integración actuales están en Compatibilidad OpenPGP y GnuPG. Cuando se active NFC en el hardware (integración planificada — no aún en el firmware), la misma clase de dispositivo puede soportar acceso físico: tocar un lector NFC en una puerta, portón o panel de cerradura puede participar en una política que solo libera la cerradura tras comprobaciones criptográficas (a menudo combinadas con PIN, biometría o cuórum de estilo Shamir según el despliegue). El esquema orientado a PN532 para lectores y paneles está en docs/NFC_PN532_INTEGRATION.md.
Esa es la versión corta. Esto es lo que lo hace diferente de otros tokens que puedas haber encontrado.
Camuflaje de almacenamiento. El dispositivo puede actuar como almacenamiento extraíble ordinario para que su función real no sea evidente a simple vista. Cuando lo conectas a un ordenador típico, puede aparecer como una unidad USB normal o un volumen respaldado por SD; puedes llenar el sistema de archivos visible con archivos cotidianos plausibles (por ejemplo, fotos de vacaciones) para que una navegación casual refuerce la impresión de que solo es almacenamiento. Eso frustra la inspección superficial en un escritorio o punto de control. Descubrir que en realidad es un token de seguridad normalmente implica desmontar la carcasa, no solo conectarlo.
Tus claves permanecen en el dispositivo. Cuando firmas un correo o descifras un archivo, la clave privada nunca sale del token. El ordenador envía los datos, el token hace el trabajo y el resultado vuelve. Un atacante que comprometa tu ordenador no obtiene nada útil.
Las sesiones pasadas siguen seguras incluso si roban el token. La mayoría de los tokens de hardware usan una clave privada a largo plazo directamente para el acuerdo de claves. Este genera un par de claves desechables nuevas para cada sesión, lo firma con la clave a largo plazo para demostrar que es genuino y luego usa el par desechable para el intercambio real. Si alguien roba el token dentro de años y de algún modo extrae la clave a largo plazo, aun así no puede descifrar nada de sesiones pasadas. Esta propiedad se llama secreto hacia adelante y es inusual en tokens de hardware.
Puedes dividir la clave entre varias personas. El token puede dividir la clave a largo plazo en N acciones de modo que se necesiten K de esas acciones para reconstruirla — pero ningún titular individual de una acción puede hacer nada por sí solo. Esto se llama compartición de secretos Shamir. Es útil para claves organizativas donde ninguna persona debería tener acceso unilateral, o como estrategia de respaldo donde las acciones se almacenan en ubicaciones separadas. Esto también es inusual en tokens de hardware.
El cifrado está en capas. En lugar de cifrar tus datos con un solo cifrado, el token puede pasarlos por múltiples cifrados independientes en secuencia — por ejemplo ChaCha20, luego Serpent, luego Twofish — cada uno usando una clave derivada por separado. Un avance futuro que rompa un cifrado no rompe los demás. La combinación específica se llama perfil de cifrado, y puedes elegir entre varios integrados según el nivel de precaución que requiera tu situación.
Mi recomendación personal es BrainpoolP256r1 + ChaCha20-Poly1305 + BLAKE3. Este es el perfil standard integrado. Usa la curva Brainpool P-256 de BSI para el acuerdo de claves efímero, ChaCha20-Poly1305 para el cifrado simétrico y BLAKE3 para la derivación de claves y la integridad entre capas. Es rápido, bien probado, eficiente en batería (ChaCha20-Poly1305 fue diseñado para ser eficiente en hardware sin aceleración AES, reduciendo el tiempo de CPU y el consumo de energía del host; P-256 es la más pequeña de las tres curvas Brainpool de este firmware) y no depende de ningún primitivo diseñado por NIST. Si necesitas un mayor margen frente a una futura ruptura criptoanalítica de un solo cifrado, el perfil conservative añade una capa Serpent-256 encima.
Las elecciones de algoritmos son deliberadas. Los cifrados utilizados — ChaCha20-Poly1305, Serpent, Twofish, Camellia — fueron todos diseñados independientemente de los organismos de estándares gubernamentales. AES y el conjunto NIST están excluidos intencionalmente. Esta es una elección consciente para usuarios y organizaciones que quieren independencia criptográfica del proceso de estándares de un solo país. Camellia fue evaluado independientemente por el proyecto NESSIE de la UE y el programa CRYPTREC de Japón, y está especificado en el RFC 3713 e ISO/IEC 18033-3.
Un PIN incorrecto te bloquea correctamente. El token cuenta los intentos de PIN fallidos antes de comprobar si el PIN es correcto, no después. Esto significa que un fallo o pérdida de energía a mitad de un intento no puede explotarse para restablecer el contador. Tras demasiados intentos incorrectos, el token pone a cero el material sensible.
Lo que aún no hace. Todavía no hay hardware disponible — este es firmware en desarrollo activo. Las pruebas de extremo a extremo con hardware USB real y GnuPG son un hito futuro. El transporte NFC y los lectores de acceso tipo puerta están descritos en la documentación como objetivos de integración, no como comportamiento entregado aún. El tercer factor biométrico descrito en la documentación aún no está implementado. Algunas pruebas de canal lateral de temporización que requieren hardware real no pueden completarse hasta que exista un dispositivo.
Galdralag puede trabajar con dos tipos diferentes de clave asimétrica a la vez. Responden a preguntas diferentes en el dispositivo y en el host, y no son intercambiables incluso cuando pertenecen a la misma persona. Las secciones Compatibilidad OpenPGP y GnuPG, Web de Confianza y Fiestas de Firma de Claves, Metadatos de contacto Galdra y Comparación de metadatos (GnuPG vs Galdra) describen cada pila con más detalle; aquí está cómo difieren en términos cotidianos.
Una clave OpenPGP, en el sentido que GnuPG genera y usa, es un paquete estructurado, no un número público desnudo. Agrupa la clave primaria, subclaves para firma y cifrado, y uno o más IDs de Usuario — normalmente un nombre para mostrar y una dirección de correo como Alice Example <[email protected]>. Otras personas pueden firmar esos IDs de Usuario para decir que creen que la afirmación de identidad es genuina; ese grafo social es la base de la web de confianza descrita en Web de Confianza y Fiestas de Firma de Claves más adelante en este README. Cuando Galdralag actúa como tarjeta inteligente OpenPGP, mantiene el material de clave privada en el chip y realiza la firma y el descifrado allí. La clave pública, los IDs de Usuario y las firmas de otros viven en el host y son gestionados por GnuPG de la manera habitual. El token no cambia el formato de mensaje OpenPGP en el cable; GnuPG lo trata como cualquier otra tarjeta OpenPGP.
Una clave Galdra es un par de claves asimétricas desnudo — Ed25519, X25519, o una de las curvas Brainpool o NIST que soporta el firmware. Los bytes de la clave en sí no llevan afirmaciones de identidad: sin paquetes de ID de Usuario, sin correo incorporado, sin firmas de web de confianza adjuntas a la estructura de la clave. La identidad de una clave Galdra proviene del registro de contacto almacenado junto a ella en la base de datos SQLite del host y del almacén de contactos en el chip, vinculado a la clave por su huella digital.
La tabla siguiente compara metadatos de identidad y contacto campo por campo. Las columnas OpenPGP / GnuPG describen lo que obtienes de un certificado normal y un ID de Usuario (más filas de contacto opcionales en el lado del host en Galdra cuando almacenas una clave pública OpenPGP en el mismo directorio). Las columnas de clave Galdra describen campos laterales estructurados para contactos operativos (detalle completo en host y chip en Metadatos de contacto Galdra). Un guion significa que esa pila no tiene un campo estándar y separado para ese elemento.
OpenPGP pone nombre y correo en una sola cadena de ID de Usuario; no te da campos separados y legibles por máquina para indicativo, DMR o postal. Galdra los mantiene como columnas nombradas para que los equipos de radio y operaciones puedan buscarlos y mostrarlos sin analizar texto de certificado.
Los tokens actualizados desde firmware que ofrecía BrainpoolP512r1 pueden seguir devolviendo atributos P-512 en GET DATA; las operaciones GnuPG en esas ranuras fallan entonces con errores de tarjeta genéricos. Ejecuta galdra device status (o consulta docs/OPENPGP_CARD.md) para identificar ranuras obsoletas; los antecedentes de la eliminación están en CHANGELOG.md.
| PW1 / PW3 | Nunca almacenados | Verificador en chip (mín. 5 caracteres, 3 intentos por defecto) |
| DOs del titular (login, idioma, URL, …) | Almacenados en caché por GnuPG | Opcional (254 bytes máx. por DO) |
Aplicación de tarjeta 3.4.1, CCID y flujos de trabajo GnuPG: docs/OPENPGP_CARD.md y Compatibilidad OpenPGP y GnuPG.La división existe porque la información de identidad que importa en las comunidades a las que Galdralag apunta —indicativo, ID DMR, afiliación a redes de radio— no tiene un lugar natural en un User ID de OpenPGP. Un User ID está pensado para nombre y correo electrónico. Escribir algo como LA5XYZ <[email protected]> DMR:2345678 en una cadena de User ID es informal, no estructurado y no legible por máquina de ninguna forma estándar. Las claves Galdra mantienen el material criptográfico limpio y colocan la identidad operativa en un formato de registro que la herramienta anfitriona y el almacén en chip entienden de forma nativa.
En la práctica, un único dispositivo puede contener ambos tipos de clave sin conflicto. La aplicación de tarjeta OpenPGP sirve a GnuPG a través de los slots estándar SIG, DEC y AUT. El almacén de contactos contiene claves Galdra para trabajo operativo —por ejemplo, cifrar para un contacto de radio por indicativo, verificar un mensaje contra un ID de suscriptor DMR, o buscar a un colega por número de placa. Las dos vías no se pisan entre sí.
Si alguien tiene un certificado OpenPGP gestionado por GnuPG en el anfitrión y una clave Galdra en el almacén de contactos en chip, esas son dos claves separadas con dos huellas digitales separadas. La huella Galdra —con prefijo G: y derivada con BLAKE3 de los bytes brutos de la clave pública— no es el mismo valor que la huella OpenPGP v4 del certificado GnuPG de esa persona. La herramienta anfitriona y el dispositivo las tratan como identidades independientes. No asumas que una huella implica la otra sin verificar ambas.
Ningún tipo de clave avala automáticamente las etiquetas que la rodean. Un User ID de OpenPGP es autoafirmado hasta que otra persona lo firma. Un campo de indicativo o DMR en un registro de contacto Galdra es tan confiable como su fuente —una descarga de keyserver, una entrada manual o una verificación fuera de banda que realizaste tú mismo. Las etiquetas de procedencia (SelfAttested, HostVerified, RegistrySync, OobVerified) registran cómo llegó un campo; no reemplazan el trabajo de verificar realmente la identidad que te importa.
Este firmware está escrito en Rust, un lenguaje de programación de sistemas diseñado para ser tan rápido y de bajo nivel como C o C++, pero con un enfoque fundamentalmente diferente respecto a la seguridad.
Cada dependencia se clasifica como sin cambios upstream (crates.io tal como se publica), modificada o vendida en el árbol (copia fijada o parche del workspace), o creada por este proyecto (crates de firmware, anfitrión y herramientas). El inventario completo, los roles y el grafo de dependencias están en docs/CRATE_DEPENDENCIES.md.
Una gran parte de los bugs relevantes para la seguridad en los codebases de la industria provienen de la falta de seguridad de memoria (desbordamientos de buffer, use-after-free, desreferencias nulas y similares). El MSRC de Microsoft ha informado repetidamente que aproximadamente el 70% de los CVEs abordados en sus propios productos caen en esta categoría; el equipo de Chrome ha publicado proporciones similares para Chrome. Esas cifras describen los productos de esos proveedores, no una ley universal para todo firmware, pero ilustran por qué los lenguajes con seguridad de memoria importan.
En Rust seguro (el predeterminado), el borrow checker descarta las carreras de datos y los errores de memoria habituales de comportamiento indefinido en tiempo de compilación sin depender de la recolección de basura. Rust inseguro y FFI hacia C aún pueden introducir bugs de memoria; deben mantenerse pequeños y revisados.
El bounds checking de Rust en slices y sus reglas de propiedad reducen varias clases de modos de fallo comunes en código embebido en C/C++:
unsafe deben ser explícitos; MMIO y punteros brutos para registros viven ahí, de modo que los revisores pueden hacer grep de la superficie de auditoría (unsafe no hace imposible un MMIO incorrecto, solo más fácil de localizar).Rust no detiene por sí mismo bugs lógicos como un bucle cerrado que desgasta la flash, o elegir valores de registro incorrectos. Esos siguen siendo preocupaciones de ingeniería y revisión.
Este codebase aplica patrones comunes de Rust para secretos; no son automáticos para cada tipo:
zeroize::Zeroize / ZeroizeOnDrop limpian buffers al soltar; los llamadores optan por ello.subtle::ConstantTimeEq (y similares) donde el tiempo importa — el == ordinario no es mágicamente de tiempo constante.Copy en envoltorios de secretos reduce la duplicación accidental; la separación de dominios usa tipos distintos y etiquetas HKDF (Política de dependencias criptográficas).catch_unwind o abort donde tu plataforma requiera garantías más fuertes.unsafe debe escribirse explícitamente en el código fuente, lo que reduce la revisión manual. Dependencias: la política criptográfica de este proyecto favorece crates de Rust auditados (RustCrypto y otros); ver la tabla en Política de dependencias criptográficas — no cada dependencia proviene de un único proyecto paraguas. Para la lista completa de crates y si cada dependencia está sin cambios, modificada/vendida o escrita por el proyecto, ver docs/CRATE_DEPENDENCIES.md.
Rust no elimina deadlocks (p. ej. bloqueos Mutex mal ordenados), bugs lógicos, protocolos incorrectos, desgaste de flash por bucles defectuosos, ataques físicos (glitching, análisis de potencia) o riesgos de una compilación correcta de la imagen equivocada. Tampoco garantiza ejecución de tiempo constante en todo hardware sin codificación cuidadosa. Esas áreas dependen de diseño, revisión, pruebas y las prácticas criptográficas y de cadena de suministro del proyecto descritas en otras partes de este README.
Verificación (pruebas y fuzzing): Más allá del lenguaje, este repositorio usa pruebas unitarias, pruebas de integración, harnesses de temporización dudect y objetivos libFuzzer (cargo-fuzz). Los resúmenes y matrices están en Resultados de pruebas; los metadatos de ejecución registrados comienzan en docs/TEST_RESULTS.md#run-metadata. Las pruebas que pasan no demuestran preparación para producción ni ausencia de vulnerabilidades — reducen el riesgo. Tú decides si ejecutar builds o pruebas es aceptable para tu entorno; una máquina virtual es opcional pero limita el radio de impacto en tu máquina.
Cualquier plataforma de VM importante es adecuada — VirtualBox (gratuita, de código abierto), QEMU (gratuita, de código abierto, línea de comandos) o VMware. Se recomienda un invitado Linux ya que el entorno de compilación está mejor soportado allí.
Inicio rápido con QEMU y Ubuntu:```bash
sudo apt install qemu-system-x86 # Debian/Ubuntu host
brew install qemu # macOS host
qemu-system-x86_64 -m 2G -cdrom ubuntu-24.04-live-server-amd64.iso
Dentro de la VM, se aplican las instrucciones de compilación estándar. La VM puede
**capturarse como instantánea** antes de cada experimento y **revertirse limpiamente** si
algo sale mal.
### Evaluación de riesgos y despliegue
**En última instancia, si este firmware es seguro de desplegar en su
entorno es una decisión que solo usted puede tomar**, basada en su propia
evaluación de riesgos, la sensibilidad de lo que está protegiendo y
si elige esperar una auditoría independiente de terceros
antes del despliegue. Este proyecto pretende darle toda la
información necesaria para tomar esa decisión por sí mismo.
Una lista estructurada de activos, amenazas **T1–T14**, no-objetivos explícitos y brechas de verificación del Q2 está en **[docs/THREAT_MODEL.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREAT_MODEL.md)**.
---
## Sobre el nombre
**Galdr** es la práctica nórdica antigua de magia hablada o cantada: encantamientos
usados para atar, proteger o revelar. En las sagas nombra el acto de lanzar
el hechizo en sí, no solo las palabras. A veces también se usa para activar
inscripciones rúnicas mágicas, como en la [lanza Kragehul I](https://en.wikipedia.org/wiki/Kragehul_I),
el [amuleto de Lindholm](https://en.wikipedia.org/wiki/Lindholm_amulet),
el [bracteato de Vadstena](https://en.wikipedia.org/wiki/Vadstena_bracteate),
y otros hallazgos del Futhark antiguo.
**Galdralag** es la forma métrica usada para el galdr: verso estructurado, preciso,
regido por reglas en el que el patrón es parte de la fuerza del hechizo.
El sufijo *lag* es afín a "ley" o "patrón".
**Las runas** eran literalmente conocimiento secreto y codificado — el uso chamánico
solo era conocido por quienes lo entendían.
---
## Documentación
**Glosario:** [docs/GLOSSARY.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GLOSSARY.md) — términos explicados en **lenguaje sencillo** (ordenados A–Z). Empiece aquí si el README u otros documentos le resultan demasiado técnicos.
**Depuración:** [docs/DEBUG_INSTRUCTIONS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/DEBUG_INSTRUCTIONS.md) — backtraces, cómo acotar `cargo test`, atajos de `xtask`, triple verificación del firmware, fuzzing y qué recopilar antes de informar de un problema.
**Asistentes de IA (Claude, Cursor):** [CLAUDE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/CLAUDE.md) — instrucciones del proyecto para agentes de codificación. Reglas específicas de Cursor: [`.cursor/rules/`](https://github.com/supermagnum/galdralag-firmware/blob/main/.cursor/rules).
**Examinar todos los archivos:** [github.com/Supermagnum/Galdralag-firmware — `docs/`](https://github.com/Supermagnum/Galdralag-firmware/tree/main/docs)
**Hardware (llave USB y relacionado):** Dos árboles de KiCad: [Hardware/kicad-files-usb/](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-files-usb) — `dabao_v3c` (token USB-A **sin** micro-SD); y [Hardware/kicad-sd-card/](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-sd-card) — `dabao_v3c_sdcard` (misma disposición base **con** soporte para micro-SD), gerbers, BOM, salidas de producción y [documentación de pines](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-sd-card/docs/pinout/README.md). La disposición del PCB de la llave USB-A (token mínimo vs evaluación en formato Pico) se describe en [docs/USB_DONGLE_PCB.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/USB_DONGLE_PCB.md).
| Documento | Descripción |
|----------|-------------|
| [Hardware/kicad-files-usb/](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-files-usb) | Proyecto KiCad de **llave USB** `dabao_v3c` (sin micro-SD); gerbers, BOM, salidas de producción; complementa [USB_DONGLE_PCB.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/USB_DONGLE_PCB.md) |
| [Hardware/kicad-sd-card/](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-sd-card) | Proyecto KiCad de **llave USB** `dabao_v3c_sdcard` (soporte para micro-SD); gerbers, BOM, pines en [docs/pinout](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-sd-card/docs/pinout/README.md); complementa [USB_DONGLE_PCB.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/USB_DONGLE_PCB.md) |
| [docs/CODE_MAP.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CODE_MAP.md) | **Índice de funciones y módulos** del workspace (`pub fn` / tipos por archivo con anclas de línea) |
| [docs/CRATE_DEPENDENCIES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CRATE_DEPENDENCIES.md) | Crates de Rust **upstream vs del proyecto** y cómo dependen entre sí |
| [docs/API_REFERENCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/API_REFERENCE.md) | Mapa de código + **anexo** para IETF/I-D/GnuPG/Sequoia: construcción de Shamir GF(256), armour GALDRA SHARE, formato de cable ECDH efímero, etiquetas HKDF, preimágenes; rutas de `galdrad`; sugerencias de rustdoc |
| [docs/ARCHITECTURE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/ARCHITECTURE.md) | Arquitectura de firmware de alto nivel y subsistemas principales |
| [docs/AUDIT_LOG.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/AUDIT_LOG.md) | Registros de auditoría de perfiles (`cipher-profile`), hook OpenPGP `OpenPgpAudit`; **no** hay registro RRAM de solo anexión implementado todavía |
| [docs/BIOMETRIC_API.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/BIOMETRIC_API.md) | Pre-puerta biométrica: arquitectura, formato de cable, disposición de la bóveda; integración parcialmente implementada |
| [docs/BIOMETRIC_DEVICE_GUIDE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/BIOMETRIC_DEVICE_GUIDE.md) | Cómo añadir soporte para un nuevo backend de hardware biométrico |
| [docs/BIOMETRIC_TESTING.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/BIOMETRIC_TESTING.md) | Metodología de pruebas: métricas PAD ISO/IEC 30107-3, conjuntos de datos, cómo ejecutarlas |
| [docs/FINGERVEIN_DEVICE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/FINGERVEIN_DEVICE.md) | Dispositivo abierto de vena del dedo ESP32-CAM: hardware, esquema de protocolo, vivacidad |
| [docs/SWEET_PLATFORM_INTEGRATION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/SWEET_PLATFORM_INTEGRATION.md) | Escáner de mano de la plataforma sweet: hardware, integración, vivacidad, conjunto de datos |
| [docs/GALDRA-TOOL.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GALDRA-TOOL.md) | Herramientas de host (`galdra`, `galdrad`, `galdra-gtk`): flujos de trabajo, aprovisionamiento, política de PIN, comportamiento operativo |
| [Supermagnum/Fulla](https://github.com/Supermagnum/Fulla) | **Fulla**: registro de claves públicas OpenPGP orientado a WoT (repositorio e implementación del servidor). **Todavía no hay ninguna instancia pública del registro en ejecución**; está prevista una. **`galdra keyserver push`** / **`galdra keyserver fetch`** y la configuración opcional **`[keyserver]`** apuntan a este ecosistema—véase también [Web of Trust y fiestas de firma de claves](#web-of-trust-and-key-signing-parties). Las notas de diseño complementarias permanecen en [docs/server.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/server.md). |
| [docs/GLOSSARY.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GLOSSARY.md) | **Glosario en lenguaje sencillo** (A–Z) para lectores no técnicos; el detalle técnico permanece en los documentos enlazados |
| [CLAUDE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/CLAUDE.md) | Instrucciones para **Claude** / agentes de codificación de IA; apunta a [`.cursor/rules/`](https://github.com/supermagnum/galdralag-firmware/blob/main/.cursor/rules) para **Cursor** |
| [docs/GALDRALAG_DEV_REFERENCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GALDRALAG_DEV_REFERENCE.md) | Cadena de herramientas, comandos de `xtask`, puntos de entrada de pruebas de fuzzing y criptografía |
| [docs/dev-ref.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/dev-ref.md) | Disposición del workspace, crates, traits HAL, comportamiento de USB/PSRAM, invariantes de seguridad |
| [docs/DEBUG_INSTRUCTIONS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/DEBUG_INSTRUCTIONS.md) | Depuración: `RUST_BACKTRACE`, compilaciones verbosas, pruebas acotadas, recetas de `xtask`, comprobaciones de destino embebido, indicaciones de fuzzing, comprobaciones de host OpenPGP |
| [docs/KEY_LIFECYCLE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/KEY_LIFECYCLE.md) | Generación de claves, importación, política de exportación, rotación, zeroización, Shamir (tal como se refleja en `vault` / OpenPGP) |
| [docs/OPENPGP_CARD.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/OPENPGP_CARD.md) | Aplicación de tarjeta OpenPGP, configuración de host GnuPG/CCID, ranuras de claves, algoritmos, udev |
| [docs/CIPHER_PROFILES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILES.md) | Sistema de perfiles de cifrado y configuración |
| [docs/DUAL_KEY_QUORUM.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/DUAL_KEY_QUORUM.md) | Quórum de dos (o N) claves de hardware como patrón de extensión de integrador sobre Shamir y OpenPGP; no lo aplica el firmware |
| [docs/CIPHER_PROFILE_SECURITY.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILE_SECURITY.md) | Consideraciones de seguridad: identificadores de perfil en claro, análisis de tráfico, justificación del envoltorio externo BrainpoolP384r1, identificadores cifrados, propiedad de comodín |
| [docs/CESS_CONFORMANCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CESS_CONFORMANCE.md) | Alineación con [CESS](https://github.com/Supermagnum/CESS/tree/main): disposición de cable Modo A, `suite_id` de [ALGORITHM-REGISTRY.md — tabla de búsqueda](https://github.com/Supermagnum/CESS/blob/main/ALGORITHM-REGISTRY.md#cipher-suite-identifier-lookup-table), registro de desviaciones (AES/SHA-2 retenidos vs CESS-CORE), hoja de ruta |
| [crates/cess](https://github.com/supermagnum/galdralag-firmware/blob/main/crates/cess) | CESS Modo A: HKDF-BLAKE3 (`derive_k_outer`, `hkdf_blake3`), sellado/apertura exterior ChaCha, disposición `suite_id \|\| inner_blob`; véase [CESS_CONFORMANCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CESS_CONFORMANCE.md) |
| [docs/EPHEMERAL_SESSION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/EPHEMERAL_SESSION.md) | Protocolo de sesión ECDH efímera autenticada |
| [Supermagnum/CESS](https://github.com/Supermagnum/CESS) | **CESS** (*Cryptologically Enchanted Shamir's Secret*) — especificación abierta (texto normativo y vectores de prueba) para compartición de secretos por umbral con cifrado autenticado, envoltura de comparticiones basada en contraseña y intercambio de claves híbrido post-cuántico opcional; separado de este firmware pero en el mismo espacio de diseño que Shamir y los perfiles de cifrado aquí |
| [docs/PQ_SIGNATURES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/PQ_SIGNATURES.md) | Firmas post-cuánticas con estado (XMSS, LMS/HSS), activación por características |
| [docs/Psram.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/Psram.md) | Volumen señuelo opcional en microSD y comportamiento relacionado |
| [docs/RRAM_LAYOUT.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/RRAM_LAYOUT.md) | RRAM en chip de **4.194.304 bytes**: offsets de la bóveda desde el código fuente, mapeo HAL, notas de desgaste / zeroización |
| [docs/TEST_RESULTS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/TEST_RESULTS.md#run-metadata) | Abre en **Run metadata**; resumen de la canalización, vectores, dudect, cargo-fuzz ([Sección 6](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/TEST_RESULTS.md#6-cargo-fuzz-libfuzzer)), ciclo de vida de claves |
| [docs/THREE_FACTOR_AUTH.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREE_FACTOR_AUTH.md) | Token + PIN + biométrico opcional: qué implementa este repositorio vs marcador de posición; esbozo de amenazas |
| [docs/THREAT_MODEL.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREAT_MODEL.md) | Modelo de amenazas: activos, amenazas T1–T14, qué se defiende y qué no, elementos sin verificar pendientes del hardware Q2, estado de auditoría |
| [docs/PERFORMANCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/PERFORMANCE.md) | Notas de rendimiento |
| [docs/HARDWARE_BRINGUP_TEST_PLAN.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/HARDWARE_BRINGUP_TEST_PLAN.md) | Puesta en marcha del primer hardware Q2: imagen con `galdralag-service`, libccid `1D50:6197`, ATR → APDUs de `gpg --card-status`, PINs de laboratorio Dabao (no CDC en `dabao-ccid`) |
| [docs/XOUS_CORE_UPSTREAM_REQUESTS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/XOUS_CORE_UPSTREAM_REQUESTS.md) | Cambios que pertenecen a xous-core (documentos Persona A, política ATR, notas de cratespec); Galdralag no parchea ese árbol |
| [docs/HARDWARE_VERIFICATION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/HARDWARE_VERIFICATION.md) | Zeroización de hardware: verificación por simulación vs silicio |
| [docs/HARDWARE_TEST.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/HARDWARE_TEST.md) | Notas de pruebas orientadas a hardware |
| [docs/NFC_PN532_INTEGRATION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/NFC_PN532_INTEGRATION.md) | PN532 / NFC: libnfc, opciones de Rust, puerta pasiva vs panel USB, quórum con Shamir y PIN |
| [docs/SDMMC_STORAGE_INTEGRATION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/SDMMC_STORAGE_INTEGRATION.md) | `embedded-sdmmc` + microSD SPI como almacenamiento masivo opcional; alternativa BOM a PSRAM |
| [docs/USB_DONGLE_PCB.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/USB_DONGLE_PCB.md) | Cómo fabricar un PCB de llave USB-A a partir de la referencia Dabao: la evaluación en formato Pico es para la puesta en marcha del firmware; esto elimina el cabezal GPIO para un token mínimo; KiCad, FreeCAD, 5 V / 500 mA vs USB-C PD, enrutado QSPI PSRAM |
Las mismas rutas se resuelven en GitHub bajo [`tree/main/docs`](https://github.com/Supermagnum/Galdralag-firmware/tree/main/docs) y [`tree/main/Hardware`](https://github.com/Supermagnum/Galdralag-firmware/tree/main/Hardware).
---
## Compatibilidad con OpenPGP y GnuPG
El firmware implementa la **aplicación de tarjeta OpenPGP** (documentada como versión **3.4.1** en [docs/OPENPGP_CARD.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/OPENPGP_CARD.md)). Es la misma clase de dispositivo que GnuPG maneja para **tarjetas inteligentes OpenPGP** a través de **CCID/USB**: el host necesita una pila normal de tarjetas inteligentes (`pcscd`, controladores `ccid`, `scdaemon` de GnuPG). **No se requiere ningún controlador criptográfico personalizado en el host** más allá del que usaría para cualquier tarjeta OpenPGP.
**Lo que esto habilita en el host (una vez que el dispositivo es visible como lector CCID):**
| Área | Notas |
|------|--------|
| **Flujos de trabajo de GnuPG** | `gpg --card-status`, `gpg --card-edit`, cifrar/descifrar y firmar usando claves de la tarjeta |
| **SSH** | `gpg-agent` con `enable-ssh-support` y la configuración habitual de `SSH_AUTH_SOCK` |
| **Correo y archivos** | Clientes que usan GnuPG (p. ej. Thunderbird, Evolution, Kleopatra) y cifrado de archivos estándar con `gpg` |
| **Otras herramientas** | Cualquier cosa que hable OpenPGP card + CCID de la misma manera que GnuPG |
**Ranuras de claves (valores predeterminados típicos):** **SIG** (firma), **DEC** (descifrado / ECDH), **AUT** (autenticación, p. ej. SSH). Los algoritmos operativos por ranura son curvas Brainpool, NIST P-256/P-384 y Ed25519 / X25519. Los atributos de algoritmo RSA se pueden almacenar mediante PUT DATA, pero GENERATE, PSO:CDS y PSO:DECIPHER fallan todos para ranuras configuradas con RSA. La tabla completa y el comportamiento de `key-attr` están en [docs/OPENPGP_CARD.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/OPENPGP_CARD.md).
**No cubierto por OpenPGP card / GnuPG aquí:** **WebAuthn / FIDO2** es un protocolo diferente y está fuera del alcance de esta aplicación de tarjeta (véase el mismo documento).
**OpenPGP card vs. mensajes OpenPGP:** La especificación de la **tarjeta** define cómo el token expone PINs, ranuras de claves y operaciones en la tarjeta a través de CCID. **GnuPG** la usa a través de `scdaemon`. El **formato de mensaje OpenPGP** para archivos y correo (RFC 4880 y sucesores) es una capa **del lado del host**: la tarjeta suministra las claves; GnuPG sigue aplicando el formato de mensaje en el PC. Ni la especificación de la tarjeta ni RFC 4880 definen el **reparto Shamir**, las **sesiones ECDH efímeras** ni los **perfiles de cifrado** — esos son [características específicas del firmware](#standards-vs-firmware-specific-features).
**Estado de integración:** La lógica de OpenPGP y CCID vive en **`usb-personality`**, **`baochip-openpgp`** y el servicio **Xous** **`usb-bao1x`** (véase **xous-core** en **`feature/usb-bao1x-ccid-openpgp`**). El **`galdralag-service`** opcional (`services/galdralag`) se conecta a **`usb-bao1x`** para IPC de **CCID** y responde APDUs **XfrBlock**; las imágenes Dabao lo necesitan vía cratespec (`scripts/build_dabao_ccid_image.sh`). BaoSec puede seguir puenteando **PDDB** hacia **RRAM**. Detalles: [services/galdralag/README.md](https://github.com/supermagnum/galdralag-firmware/blob/main/services/galdralag/README.md). Disposición de memoria: [docs/RRAM_LAYOUT.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/RRAM_LAYOUT.md). **GnuPG de extremo a extremo en hardware real** todavía necesita una imagen completa con Galdralag, reconocimiento de **`1D50:6197`** por **libccid** del host y los elementos bajo [Limitaciones conocidas / trabajo abierto](#known-limitations--open-work).
## Sesión del token y exportación de claves
**Desconexión física (desenchufar):** El host pierde el dispositivo USB; cualquier operación en curso falla hasta que el token se vuelve a conectar y se re-enumera. En el dispositivo, la **sesión de tarjeta** OpenPGP se limpia: el **estado de verificación de PIN** no sobrevive al apagado ni a la extracción, por lo que **firmar, descifrar y otras operaciones protegidas requieren VERIFY PIN de nuevo** tras reconectar, como otras tarjetas inteligentes OpenPGP. **El material de clave privada permanece almacenado en el token** en almacenamiento de bóveda sellado; desenchufar no lo borra a menos que se ejecute una ruta separada de **zeroización** o borrado.
**Lo que puede salir del dispositivo:** Por diseño, **solo el material de clave pública** puede cruzar el enlace USB (por ejemplo, paquetes de clave **pública** OpenPGP y datos relacionados que la especificación de la tarjeta expone al host). Las claves **privadas**, los escalares secretos en bruto y los blobs de clave sellados **no** salen del dispositivo a través de las rutas normales del firmware; las operaciones con clave privada se ejecutan **en el token**. El host recibe **resultados criptográficos** (firmas, texto plano descifrado para flujos de descifrado asistidos por tarjeta) donde los comandos estándar lo requieren, no una copia portátil de la clave privada.
**Importar claves al dispositivo:** También es posible **importar claves públicas** al token (por ejemplo, anclas de confianza, certificados de pares o paquetes públicos OpenPGP para verificación en el dispositivo). La **bóveda** del firmware proporciona **ranuras de clave pública** para material no secreto (`crates/vault/src/public_key_vault.rs`). Las herramientas de host para cargar esas ranuras se describen en [docs/GALDRA-TOOL.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GALDRA-TOOL.md) a medida que madura la integración.
---
## Web of Trust y fiestas de firma de claves
OpenPGP y **GnuPG** usan un modelo de confianza descentralizado —la **web of trust**— para ayudar a verificar quién posee qué claves y si confiar en una **clave pública** determinada. Ese modelo es completamente **del lado del host**. Cuando las atestaciones respaldadas por chip como [eID alemán y Governikus](#german-eid-and-governikus-as-a-trust-anchor-for-public-keys) no están disponibles o no son apropiadas, es la alternativa descentralizada habitual (**fiestas de firma de claves**, firmas en certificados); cuando **sí** están disponibles, ambos enfoques pueden coexistir como rutas complementarias.
**Huella Galdralag (`G:`):** Para flujos de verificación en persona, **Galdra** puede mostrar una huella **vinculada al dispositivo** derivada de la clave pública **SIG** del token (**BLAKE3-160**, prefijo `G:`). **No** es una huella de certificado OpenPGP v4. **Solo** está disponible cuando el **perfil de cifrado** activo tiene **`ephemeral_ecdh: false`**; los perfiles integrados tienen por defecto **`ephemeral_ecdh: true`**, por lo que normalmente añade un perfil de usuario con **`galdra profile add ... --no-ephemeral-ecdh`** para flujos que necesitan este identificador junto con la firma de host estilo **WoT**. Definición en lenguaje sencillo y especificación de formato: [Huella Galdralag](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GLOSSARY.md#g). Ciclo de vida, política de rotación y la puerta ECDH efímera: [KEY_LIFECYCLE.md — Huella Galdralag](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/KEY_LIFECYCLE.md#galdralag-fingerprint-host).
### Obtención de su huella Galdralag
El host imprime una cadena que **siempre comienza con `G:`** (BLAKE3-160 sobre los bytes de la clave pública SIG, **40 caracteres hexadecimales en minúscula** después del prefijo en forma canónica).
1. Instale **[Galdra](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GALDRA-TOOL.md)** en el host y asegúrese de que **PC/SC** funciona (**`pcscd`**, **`libpcsclite`**) para que la herramienta pueda hablar CCID con el token (véase [Compilar e instalar herramientas de host](#compile-and-install-host-tools-galdra-galdrad-galdra-gtk)).
2. Conecte el token (desbloquéelo si su flujo de trabajo lo requiere).
3. Seleccione un **perfil de cifrado** con **`ephemeral_ecdh: false`**. Confirme con **`galdra profile show <name>`** (`ephemeral_ecdh: off`). El nombre de perfil predeterminado **`standard`** suele tener **`ephemeral_ecdh: on`**; cree uno con **`galdra profile add <name> ... --no-ephemeral-ecdh`** si es necesario.
4. Ejecute:```bash
galdra identity fingerprint
# If you use a non-default profile:
galdra identity fingerprint --profile <name>
Salida legible por máquina: galdra --emit json identity fingerprint (opcionalmente --profile <nombre>).
Las implementaciones compatibles con OpenPGP incluyen un esquema de verificación de certificados para ayudar a verificar la propiedad de las claves; su funcionamiento se ha denominado red de confianza. Los certificados OpenPGP (una o más claves públicas más material de ID de propietario/usuario) pueden ser firmados digitalmente por otros usuarios que, al hacerlo, respaldan la asociación entre esa clave pública y la persona o entidad nombrada en el certificado.
gpg --full-generate-key en el host, o portada en un token compatible con OpenPGP).Una fiesta de firma de claves es una reunión presencial donde los participantes intercambian huellas de clave y verifican la identidad de los demás antes de firmar certificados posteriormente.
Características típicas:
Eso produce un grafo social: si Alice confía en Bob y Bob firmó la clave de Charlie, Alice puede optar por confiar en la clave de Charlie según la profundidad de confianza y la política.
Por qué importan estos eventos:
Las fiestas normalmente evitan ordenadores durante el intercambio de identidad, para que los atacantes tengan menos oportunidades de colar claves sustituidas o malware en máquinas compartidas.
Antes del evento. Calcula y registra tu huella (un resumen derivado por hash de la clave pública—lo bastante corto para compararse de forma fiable). No dependas de intercambiar claves completas en papel en esta etapa, salvo que tus organizadores indiquen lo contrario.```bash
gpg --fingerprint YOUR_KEY_ID
Lleve la huella en papel u otro medio duradero (forma de ejemplo: `ABCD 1234 EFGH 5678 90AB CDEF 1234 5678 90AB CDEF`).
**En el evento (solo huellas).** Intercambie **huellas**, verifique las identificaciones y anote qué huellas pertenecen a qué persona verificada. Confirme que la identidad declarada de cada participante coincide con los documentos revisados.
**Después del evento.** Obtenga las **claves públicas** completas desde **servidores de claves** o mediante distribución directa; confirme que las claves descargadas coinciden con las **huellas** registradas en papel; **firme** las claves que verificó; opcionalmente **cargue** las firmas para que otros puedan usarlas.
### Huellas en lugar de claves completas en el evento
- **Seguridad operativa.** Mantiene los ataques de sustitución vinculados a huellas verificadas en lugar de confiar en máquinas arbitrarias a mitad del evento.
- **Simplicidad.** Las huellas caben en papel y son rápidas de leer en voz alta o comparar.
- **Verificación.** Tras la descarga, recalcular la huella comprueba la integridad de extremo a extremo.
### Servidores de claves
Los **servidores de claves** son repositorios en red que almacenan y replican claves OpenPGP **públicas** (y actualizaciones como firmas y revocaciones). Hacen que las claves sean localizables por **ID de usuario**, **ID de clave** o **huella** y sustentan la distribución a gran escala para la red de confianza.
Cómo se comportan en principio:
- **Replicación distribuida.** Cargar en un servidor que participa en una malla de sincronización a menudo propaga a los pares (los grupos clásicos de estilo **SKS** funcionaban así).
- **Sincronización.** Las claves nuevas, firmas y certificados de revocación se propagan según la política y conectividad de cada servidor.
- **Acceso de lectura público.** Solo el material **público** está destinado a publicación; las **claves privadas** nunca deben cargarse.
**Privacidad.** Las claves publicadas exponen **IDs de usuario** (a menudo incluyendo direcciones de correo). Trate las cargas como **públicas y de larga duración** en muchos servidores; cargue **certificados de revocación** cuando una clave deba retirarse. La política varía según el operador ([keys.openpgp.org](https://keys.openpgp.org/) difiere de los grupos heredados).
**Topología de pares.** Los gráficos de relaciones entre servidores aparecen en [spider.pgpkeys.eu/graphs/](https://spider.pgpkeys.eu/graphs/); listados de pares orientados a SKS en [spider.pgpkeys.eu/sks-peers](https://spider.pgpkeys.eu/sks-peers).
### Uso de servidores de claves```bash
# Upload your signed key (after local signing)
gpg --send-keys YOUR_KEY_ID
# Search by mail or name (behaviour depends on keyserver configured in gpg.conf)
gpg --search-keys [email protected]
# Refresh imported keys from configured keyservers
gpg --refresh-keys
| Servidor | Notas |
|---|---|
| keys.openpgp.org | Ampliamente utilizado; verificación orientada al consentimiento para IDs de usuario vinculados a correo |
| pgp.mit.edu | Servidor alojado por MIT históricamente ligado a las mallas de la era SKS |
| pool.sks-keyservers.net | Nombre de host de pool heredado asociado al antiguo ecosistema SKS; la conectividad hoy varía |
gpg --refresh-keys periódicamente para que las revocaciones y nuevas firmas se propaguen localmente.ephemeral_ecdh: false con galdra profile show <name>.Para el comportamiento autoritativo de gpg, los modelos de confianza y las opciones de distribución, consulta el manual de GnuPG y la documentación upstream.
El proyecto Fulla (Supermagnum/Fulla en GitHub) aloja el trabajo del servidor de registro alineado con la WoT: implementación y especificación en evolución para almacenar claves públicas de contribuyentes más etiquetas opcionales de radioaficionado, pistas postales, organisation (ortografía JSON), role, note, badge_number, phone_number y columnas relacionadas alineadas con los metadatos de contacto de Galdra. galdra keyserver push envía JSON POST /api/v1/keys (incluyendo armored_public_key, email y esos campos opcionales cuando pasas banderas CLI); galdra keyserver fetch y la estrofa de configuración [keyserver] están implementados en / hacia esa dirección. ; se espera un servicio operado públicamente en el futuro. Prosa histórica adicional de diseño vive en .
Diferentes partes de este proyecto se alinean con diferentes estándares. La interoperabilidad con GnuPG se limita a lo que definen la aplicación de tarjeta OpenPGP y CCID. Otras características están implementadas en el firmware (y a veces en las herramientas host de Galdra) pero no son algo que puedas invocar mediante flujos de trabajo estándar de tarjeta gpg.
Para el comportamiento diario de la tarjeta, confía en docs/OPENPGP_CARD.md. Para características solo de bóveda o únicas del token, usa el firmware de este repositorio y la documentación de la herramienta Galdra.
Las pilas de tarjeta OpenPGP y GnuPG no definen el Compartir Secretos de Shamir (SSS) para claves o para desbloqueo de disco. SSS sigue siendo útil junto con el cifrado normal: casi nunca reemplaza el cifrado simétrico en el disco — protege el pequeño secreto (clave maestra o frase de paso) que desbloquea ese cifrado.
Patrón (siempre la misma idea):
1. LUKS (Linux) y SSS externo
LUKS cifra el volumen con una clave maestra. Puedes extraer esa clave (o un secreto de ranura de clave, según tu procedimiento), dividirla con una herramienta SSS y almacenar las participaciones por separado. Al momento del desbloqueo, combina K participaciones, reconstruye el material de clave y suministralo a cryptsetup (consulta la documentación de tu distribución; manejar mal las claves puede bloquear el acceso).
Ejemplo de forma usando las utilidades ssss ("Shamir's Secret Sharing Scheme") (nombres y empaquetado varían según el SO):```bash
ssss-split -t 3 -n 5 < luks_master.key
ssss-combine -t 3 | cryptsetup luksOpen /dev/sdX vault
**2. HashiCorp Vault**
[Vault](https://www.hashicorp.com/products/vault) utiliza Shamir para el **desellado**: la clave de cifrado del almacenamiento se divide en la inicialización (p. ej., 3 de 5 operadores, cada uno posee una parte). Tras un reinicio, se deben ingresar **K** partes para desellar. El mismo patrón de **K-de-N sobre un secreto maestro** que en LUKS, aplicado a un motor de secretos en lugar de un dispositivo de bloques.
**3. Firmware Galdralag (`vsss-rs`)**
Este repositorio utiliza [`vsss-rs`](https://crates.io/crates/vsss-rs) (ecosistema RustCrypto) para Shamir en el dispositivo. El mismo **nivel de capas** se aplica si lo alineas con el cifrado masivo:
- Genera una clave maestra aleatoria de 256 bits (o la adecuada).
- Cifra la unidad o el almacenamiento masivo con **AES-GCM** o **ChaCha20-Poly1305** usando esa clave (esto coincide con las crates simétricas auditadas del workspace).
- Usa `vsss-rs` para dividir la clave maestra en **N** partes con un umbral **K**.
- Almacena las partes en ranuras de vault, otros dispositivos o con los titulares de las claves.
- Al arrancar o recuperar, recopila **K** partes, reconstruye y luego usa **HKDF** (o tu política) para subclaves separadas por dominio si es necesario.
**4. VeraCrypt**
VeraCrypt no implementa SSS internamente. Se aplica el mismo patrón **externo**: divide la **frase de contraseña o el material del archivo de claves** con una herramienta SSS; no intentes dividir el texto cifrado del volumen con Shamir.
### Patrón híbrido (datos grandes)
SSS es para **secretos pequeños** (tamaño de clave). **No** aplicas Shamir a texto cifrado de varios gigabytes. El nivel de capas habitual:```text
[Drive data]
encrypted by
[Symmetric master key, e.g. 32-byte AES-256]
split by SSS into
[Share 1] [Share 2] ... [Share N]
(each share may be wrapped with a recipient's PGP key, HSM, or offline media)
Eso coincide con lo que este proyecto ya acumula: aes-gcm / chacha20poly1305 para datos en reposo, vsss-rs para dividir el secreto maestro, hkdf para la derivación tras la reconstrucción.
| Decisión |
|---|
El manejo operativo de claves para LUKS y cifrado de disco completo es sensible a la seguridad; siga las guías del proveedor y de la distribución, así como los modelos de amenaza para su entorno.
Autorización de dos claves de hardware / quórum (que requiere dos tokens físicos separados
o titulares de participaciones antes de una operación crítica) es un patrón de extensión compatible,
no una característica del firmware. Galdralag proporciona primitivas Shamir K-de-N
(vault::shamir, galdra shamir)
y autenticación OpenPGP de token único; un envoltorio LUKS descendente, panel
de acceso o demonio personalizado debe imponer el quórum, las ventanas de sesión y la
reconstrucción segura. Ese límite, flujos de trabajo de referencia 2-de-N y notas de seguridad para
integradores están en docs/DUAL_KEY_QUORUM.md. Esto es
posible con las primitivas existentes hoy; la orquestación se deja intencionalmente a
el consumidor — no un compromiso de hoja de ruta de este repositorio.
Un patrón concreto es una unidad o volumen cifrado usando curvas Brainpool donde su pila las requiera (por ejemplo, ECDH/ECDSA alrededor de un secreto maestro), combinado con Shamir's Secret Sharing sobre el material de clave que desbloquea ese cifrado (el mismo capas de secreto pequeño que arriba: SSS protege la clave, no el texto cifrado de varios gigabytes). Si y cuando el firmware y el software del host que implementan ese flujo de trabajo hayan sido auditados de forma independiente, tal combinación puede ser valiosa para organizaciones que deben cumplir políticas de quórum y perfiles criptográficos nacionales al mismo tiempo.
Por qué las curvas Brainpool (p. ej., BrainpoolP256r1, BrainpoolP384r1) se discuten a menudo en ese contexto:
Escenarios donde combinar SSS con criptografía de clase Brainpool aborda necesidades institucionales (ilustrativo; no es asesoramiento legal ni de cumplimiento):
Si la firma OpenPGP estilo Governikus o la atestación eID nacional respaldada por chip comparable no está disponible o no es práctica para su jurisdicción o flujo de trabajo, Web of Trust y Key Signing Parties describe un enfoque alternativo del lado del host basado en verificación en persona y firmas de terceros sobre certificados.
Autenticación de clave OpenPGP de Governikus es un servicio en línea operado en nombre del BSI (Oficina Federal Alemana de Seguridad de la Información). Tras autenticarse el remitente con una tarjeta de identificación compatible con eID alemán, una tarjeta eID de la UE para ciudadanos de la UE, o un permiso de residencia electrónico, el servicio comprueba que el nombre legal autenticado coincide con el ID de usuario OpenPGP en la clave pública cargada. Si coincide, Governikus firma esa clave pública con la clave de firma del servicio para que terceros puedan verificar la atestación.
Un flujo de trabajo práctico con este firmware: genere una clave asimétrica Brainpool en el token (generación de tarjeta OpenPGP como de costumbre), exporte la clave pública o el certificado al host, complete el flujo de envío de Governikus incluida la autenticación eID (normalmente AusweisApp y lectura NFC de la tarjeta), y use la clave pública firmada devuelta por el servicio (por ejemplo, desde la distribución por correo electrónico). La clave privada permanece en Galdralag durante todo el proceso.
Ninguna vía reemplaza a la otra. eID y el paso de Governikus vinculan la clave pública a la identidad verificada contra el chip en el momento del envío; no proporcionan sigilo de reenvío, Shamir K-de-N para material de clave a largo plazo, ni perfiles de cifrado para datos masivos — esas son características específicas del firmware descritas en otra parte de este README. El chip eID y el proceso de emisión circundante tampoco implementan, por sí mismos, el comportamiento de ECDH efímero y cascada del token. A la inversa, una clave OpenPGP Brainpool generada en el dispositivo se alinea con el contexto de despliegue BSI/UE ya discutido para uso institucional de Brainpool, pero sin un paso de atestación externo los corresponsales deben confiar en otros medios para conectar una huella digital a una persona jurídica.
| Capa | Rol |
|---|---|
| Clave pública OpenPGP (p. ej., Brainpool en Galdralag) | Estructura criptográfica y control de clave privada en el token; las elecciones de curva siguen expectativas de clase BSI TR-03111 (ver las y la discusión de TR-03111 en ) |
Limitación: La verificación se basa en el nombre. Si dos personas comparten el mismo nombre legal en los campos que compara el servicio, la atestación no las distingue; confirma el vínculo de identidad con ese nombre en el momento de la atestación, no la unicidad global. Las preocupaciones habituales de OpenPGP (vinculación de correo electrónico, rotación de claves, revocación) siguen vigentes.
Alineación de políticas: el mismo BSI que define la guía técnica relacionada con Brainpool (BSI TR-03111; vectores de conformidad en crates/vault/tests/bsi_vectors/) también respalda el proceso de firma eID de Governikus, lo que a menudo importa en entornos alemanes y de la UE donde Brainpool ya es requerido o preferido — ver Shamir más Brainpool: ejemplo y encaje institucional.
Alcance más amplio (nota de investigación, no un estudio terminado): El mismo patrón —vincular una clave pública OpenPGP a una identidad verificada por chip— es aplicable en principio dondequiera que exista eID nacional; qué proveedores ofrecen un paso de firma similar a Governikus, y bajo qué reglas, es una cuestión aparte que vale la pena investigar a medida que se expanden los despliegues. Otros estados miembros de la UE ejecutan ecosistemas eID basados en tarjetas bajo eIDAS que podrían admitir anclas de confianza comparables o más fuertes que la vía alemana por sí sola; este README no las cataloga.
Estonia y Bélgica adoptaron ambos NIST P-384 en el chip en lugar de Brainpool, mientras que el perfil BSI del sector público alemán se centra en Brainpool (ver arriba). Galdralag ya admite Brainpool y NIST P-256/P-384 en la tarjeta OpenPGP (docs/OPENPGP_CARD.md); RSA en este repositorio es un helper de biblioteca galdr-vault, no una ranura de tarjeta funcional (Asimétrico / acuerdo de claves). El mismo patrón de ancla de confianza no depende solo de igualar la preferencia de curva de Alemania.
Fuera de la UE/EEE, el patrón de ancla de confianza basado en tarjeta es más difícil de aplicar: los EE. UU. tienen una tarjeta con chip (PIV) pero está restringida al personal federal y reside en X.509/FPKI, no integrada con OpenPGP; Canadá no tiene una tarjeta nacional de firma en chip en el sentido usado arriba. Eso limita el patrón principalmente a jurisdicciones con credenciales gubernamentales de chip emitidas universalmente — el área eIDAS de la UE es donde el modelo es actualmente más fuerte.
Cuando y si el hardware alcanza un estado listo para el consumidor, las personas que quieran que Shamir's Secret Sharing y el intercambio de claves efímero autenticado se conviertan en parte del comportamiento interoperable OpenPGP / GnuPG (en lugar de solo características específicas del firmware) necesitarían impulsar cambios de estándares e implementación en otro lugar. Este repositorio no habla en nombre de la IETF ni de GnuPG; los lugares a continuación son donde normalmente se persiguen tales enmiendas.
CESS — Cryptologically Enchanted Shamir's Secret — es un estándar criptográfico abierto para compartición de secretos por umbral junto con cifrado autenticado independiente del cifrado, envoltura de participaciones basada en contraseña y intercambio de claves híbrido post-cuántico opcional. El repositorio CESS contiene la especificación normativa, el registro de algoritmos, los vectores de prueba y el ejecutor de conformidad.
Este firmware cumple con CESS para las construcciones implementadas aquí: las reglas interoperables de participación y envoltura de la especificación se sitúan junto a los mismos temas de Shamir, Brainpool y perfil de cifrado descritos en otra parte de este README. El texto normativo es separado de este repositorio; postura de conformidad (qué coincide con la especificación, qué difiere mientras retiene algoritmos como AES y SHA-256 en los perfiles, y hoja de ruta hacia una interoperabilidad más fuerte): docs/CESS_CONFORMANCE.md.
Si los mantenedores de este repositorio de GitHub no responden a issues, pull requests o correo, aún puede avanzar nuevos cifrados, comportamiento OpenPGP y trabajo relacionado con estándares en el ecosistema más amplio. Sequoia PGP es una pila OpenPGP independiente basada en Rust (seguridad de memoria, diseño primero-biblioteca, participación activa en IETF/ecosistema) donde ocurre gran parte del desarrollo público. No es este proyecto; se documenta aquí como una vía alternativa práctica cuando el upstream aquí está en silencio.
La página Contribute describe el licenciamiento (LGPL 2.0 o posterior para la mayoría de los proyectos), el Developer Certificate of Origin, y que características comerciales más grandes pueden requerir acuerdo previo y acuerdos de mantenimiento a largo plazo — lea esa página antes de invertir esfuerzo significativo.
También vale la pena vigilar https://autocrypt2.org/#/
Este código base y las aplicaciones relevantes no se compilarán para macOS o Windows. Las herramientas del host (galdra, galdrad, galdra-gtk) y el tooling de soporte apuntan a Linux. Esta es una decisión deliberada basada en el modelo de amenaza del proyecto y los requisitos de auditabilidad establecidos a lo largo de este documento.
_NSAKEY descubierta en Windows NT en 1999 causó controversia significativa. Microsoft declaró que era una clave de respaldo; esto nunca se probó completamente en ningún sentido.Sospechado pero no probado:
main, restricted, universe y multiverse están firmados por la clave GPG de Canonical.security.ubuntu.com, que también está firmado.Los gestores de paquetes son generalmente seguros, pero las instalaciones de terceros .deb / .rpm / AppImage pueden ser inseguras. Prefiera paquetes firmados de repositorios confiables y verifique las firmas antes de instalar cualquier cosa obtenida fuera de ellos.
Use un toolchain Rust estable como se fija en rust-toolchain.toml. El firmware usa el objetivo riscv32imac-unknown-none-elf; las herramientas del host usan el triple del host.
test-hal se filtrara a las compilaciones de producción): ```bash
cargo run -p xtask -- check-fw
El código objeto y los archivos compilados se generan en target/riscv32imac-unknown-none-elf/release/. Una imagen completa y arrancable del sistema Xous para una placa específica se produce mediante el flujo de integración más amplio de Baochip / Xous cuando sigues el proceso de compilación de ese producto; xtask aquí ejecuta cargo build para los crates de la biblioteca de firmware listados en xtask (no un único archivo listo para flashear por sí mismo).
Daemon Xous CCID (galdralag-service) — requiere la cadena de herramientas Xous riscv32imac-unknown-xous-elf (no el triple de firmware desnudo riscv32imac-unknown-none-elf mencionado arriba).
Árbol xous-core requerido: las dependencias de ruta se resuelven a través de Galdralag-firmware/xous-core/. Las compilaciones de imagen deben usar un checkout hermano (o XOUS_CORE=) en la rama feature/usb-bao1x-ccid-openpgp (PR #937). Los árboles anidados y hermanos pueden divergir; cargo run -p xtask -- check-xous-core falla
con un código distinto de cero e imprime un ln -sfn <sibling> ./xous-core copiable y pegable (renombra primero un checkout anidado real si ./xous-core no es ya un enlace simbólico): ```bash
ln -sfn ../xous-core ./xous-core
cargo run -p xtask -- check-xous-core
Imagen Dabao CCID que incluye Galdralag (solo dabao-ccid sin más es únicamente de transporte): ```bash
scripts/build_dabao_ccid_image.sh
**BaoSec + PDDB:** **`cargo run -p xtask -- build-and-register release --xous-core /path/to/xous-core`**. Detalles: [services/galdralag/README.md](https://github.com/supermagnum/galdralag-firmware/blob/main/services/galdralag/README.md). Brechas solo en upstream: [docs/XOUS_CORE_UPSTREAM_REQUESTS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/XOUS_CORE_UPSTREAM_REQUESTS.md).
### Flasheo
Este repositorio **no** incluye aún un flasheador de un solo comando. La programación del **Baochip-1x** (JTAG, arranque ROM/USB o herramientas del proveedor) sigue la documentación de la placa y del silicio. Comience desde **[Supermagnum/Baochip-1x-firmware](https://github.com/Supermagnum/Baochip-1x-firmware)**; el **hardware de la placa de evaluación** está en **[baochip/dabao](https://github.com/baochip/dabao)** — en la placa Dabao, **SW2** alterna el **modo bootloader** (consulte ese esquemático).
**Enviar UF2 sin el botón físico de arranque:** Después de copiar **`loader.uf2`**, **`xous.uf2`** y **`apps.uf2`** al volumen **BAOCHIP**, puede presionar el botón físico **boot** **o** escribir **`boot`** en la consola serie USB **boot1** (1 000 000 baudios, p. ej. `screen /dev/ttyACM0 1000000`). Eso evita depender del botón **boot** solo para este paso. La consola **se desconecta** cuando escribe **`boot`**; eso es **esperado** (el sistema se reinicia en la siguiente etapa). En Linux, `dmesg --follow` ayuda a confirmar la re-enumeración USB. Esto es distinto de **PROG** (mantener presionado mientras se conecta USB para entrar al bootloader de almacenamiento masivo **BAOCHIP**). Consulte **[baochip/dabao#2](https://github.com/baochip/dabao/issues/2)** (cerrado).
**Flujo Xous / Baochip:** Las imágenes están **firmadas con Ed25519** y verificadas por **boot0** antes de la ejecución; consulte [Firmware firmado (Ed25519, boot0)](#signed-firmware-ed25519-boot0). Para **dabao**, el diseño **UF2**, mantener **PROG** mientras conecta USB para entrar al modo de almacenamiento masivo y los pasos de actualización de **boot1**, consulte **[Getting Started with Baochip Targets](https://github.com/betrusted-io/xous-core/blob/dev/README-baochip.md)**.
### Compilar e instalar herramientas del host (`galdra`, `galdrad`, `galdra-gtk`)
Los crates del host están en la raíz del workspace: `galdra/`, `galdrad/`, `galdra-gtk/`.
**Ubuntu / Debian** (instalar antes de `cargo build` / `cargo install`):```bash
sudo apt update
sudo apt install build-essential pkg-config libpcsclite-dev pcscd libssl-dev
# required only for `galdra-gtk`:
sudo apt install libgtk-4-dev
libpcsclite-dev satisface la ruta de enlace predeterminada de PC/SC de galdra; pcscd es el demonio que atiende los lectores de tarjetas inteligentes en tiempo de ejecución. libssl-dev es necesario para que openssl-sys pueda enlazar (las búsquedas de claves de sequoia-net y el TLS de ldap3 usan native-tls hoy en día). Omita libgtk-4-dev si nunca compila galdra-gtk.
GTK 4 (solo galdra-gtk): pkg-config debe resolver gtk4 (crate del workspace gtk 0.9.x, paquete gtk4). En Fedora use gtk4-devel; en Arch gtk4.
Compile los binarios de release desde la raíz del repositorio:```bash cargo build --release -p galdra -p galdrad -p galdra-gtk
Ejecutables: `target/release/galdra`, `target/release/galdrad`, `target/release/galdra-gtk`.
**Instalación** en `~/.cargo/bin` (ajusta `--path` si no estás en la raíz del repositorio):```bash
cargo install --locked --path galdra
cargo install --locked --path galdrad
cargo install --locked --path galdra-gtk
En su lugar, puede copiar esos tres binarios a cualquier directorio de su PATH.
galdrad y la GUI de escritorio (galdra-gtk)galdra-gtk es el binario de escritorio GTK4 (paquete Cargo galdra-gtk; no existe galdra-gui). Es una interfaz frontal para la API REST de galdrad — ejecute galdrad primero.
Demonio — galdrad escucha en 127.0.0.1:8742 por defecto (--listen lo anula); consulte galdrad/src/main.rs.```bash
galdrad
Comprobación rápida: `curl -s http://127.0.0.1:8742/health` (documentación interactiva de la API: **`http://127.0.0.1:8742/swagger-ui/`**).
**Interfaz gráfica de escritorio** — **`galdra-gtk`** usa **`http://127.0.0.1:8742`** por defecto (`--base-url` o **`GALDRAD_URL`**); consulta [`galdra-gtk/src/main.rs`](https://github.com/supermagnum/galdralag-firmware/blob/main/galdra-gtk/src/main.rs).```bash
galdra-gtk
galdra-gtk --base-url http://127.0.0.1:8742
GALDRAD_URL=http://127.0.0.1:8742 galdra-gtk
Desde una compilación limpia de cargo build --release, sin instalar: ./target/release/galdrad y luego ./target/release/galdra-gtk desde la raíz del repositorio.
Host vs token: galdra-gtk refleja lo que galdrad expone por HTTP; el desbloqueo de token, el aprovisionamiento y otros flujos CCID permanecen en la CLI de galdra (consulta galdra device en docs/GALDRA-TOOL.md y el Nivel 2c).
Directorio de contactos (galdra contact, galdrad /contacts): crear un contacto requiere un correo electrónico (CLI: --email; HTTP: campo JSON email). Los campos opcionales incluyen nombre para mostrar (--name / name), organización (--org / org), rol, insignia (--badge / badge), nota, indicativo, Fluxer, Discord e IRC ids, número de teléfono (--phone-number / phone_number), además de (, , , ), de radioaficionado y . Estos valores se almacenan solo en los metadatos locales de SQLite (no se contra servicios externos). un contacto (por ejemplo , rutas /, de , ids de miembros de grupo o de ) acepta el de la fila, el , el , una (se ignoran los espacios), esos ids sociales o un en cuando se proporciona como token decimal. puede reflejar muchas de las mismas etiquetas en un registro estilo Fulla (, , , , , campos de radio/sociales/postales y nombres — consulta ). Los comandos y los límites de campos se resumen en en y .
Si usaste cargo install --path como se indicó anteriormente:```bash
cargo uninstall galdra
cargo uninstall galdrad
cargo uninstall galdra-gtk
Si copiaste los binarios manualmente, elimina los archivos que añadiste. El firmware no está "instalado" en el host; borrar o reflashear el dispositivo está cubierto por la documentación de tu hardware.
---
## Capacidades clave
### Qué hace especial a este token
Los elementos siguientes son **capacidades del firmware Galdralag**, no requisitos de la [aplicación de tarjeta OpenPGP](#estándares-vs-características-específicas-del-firmware) ni de GnuPG.
- **Modelo de seguridad preparado para tres factores** — La **posesión** del token USB y el **conocimiento** del PIN se aplican en el firmware hoy en día; un tercer factor **biométrico** opcional **no** está implementado en este repositorio (marcador de posición: [docs/BIOMETRIC_API.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/BIOMETRIC_API.md)). Consulta [docs/THREE_FACTOR_AUTH.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREE_FACTOR_AUTH.md) para conocer el alcance y los límites.
- **ECDH efímero autenticado en el dispositivo** — verdadero secreto criptográfico hacia adelante.
Cada sesión genera un par de claves efímero nuevo en el TRNG de hardware del token.
La clave a largo plazo firma la oferta efímera pero nunca
participa en el acuerdo de claves. Las sesiones pasadas no pueden descifrarse ni siquiera
a partir de una clave a largo plazo totalmente comprometida. Según el conocimiento de los autores del proyecto, ningún
token de seguridad de hardware comercial ofrece esto como una característica de primera clase.
- **Intercambio de secretos Shamir K-de-N en el dispositivo** — la clave a largo plazo puede
dividirse en N participaciones que requieren K para reconstruirse, sin que ningún titular individual pueda
recuperar la clave por sí solo. Según el conocimiento de los autores del proyecto, ningún
token comercial ofrece esto como una característica de primera clase tampoco. El **doble control** (dos
tokens requeridos antes de que se abra una puerta o se monte un volumen) **no** se aplica
aquí; consulta [Cuórum de doble clave de hardware (patrón de integrador)](#cuórum-de-doble-clave-de-hardware-patrón-de-integrador).
- **Sistema de perfiles independiente del cifrado** — los cifrados simétricos, las curvas ECDHE y la
configuración Shamir se combinan en perfiles con nombre y auditables. Para datos
masivos bajo un perfil, el texto plano se cifra **de dentro hacia fuera**: puedes
apilar **hasta cuatro** **AEAD simétricos** **diferentes** unos sobre otros — así que
puedes usar **tres** cifrados independientes en un perfil (por ejemplo
ChaCha20-Poly1305, luego Serpent-256, luego Twofish-256), o una cuarta capa distinta
donde la política lo permita — con **ningún cifrado repetido** en el mismo perfil
y material de clave y nonce **independiente** derivado de HKDF por capa. Los nombres
integrados como `standard`, `conservative` y `conservative-shamir` incluyen **una
o dos** capas; las pilas más profundas son para perfiles avanzados o personalizados.
Reglas completas y diseño de cableado: [docs/CIPHER_PROFILES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILES.md).
Cada selección de perfil se registra en el rastro de auditoría.
- **BLAKE3 con clave entre capas de cascada (CESS)** — Además de la etiqueta AEAD propia de cada
capa y del sobre exterior ChaCha20-Poly1305 del **Modo A**, **CESS**
define integridad de estilo **BLAKE3 con clave** **entre** las etapas internas de la cascada. Para
perfiles **mapeados por registro** (`suite_id` mediante nombres integrados), **`cipher-profile`**
añade un **HMAC-BLAKE3 de 32 bytes** sobre la salida AEAD de cada capa interna antes de que la
siguiente capa cifre; las claves se derivan con **HKDF-BLAKE3** usando
`cess::cess_blake3_integrity_gap_info` ([`inner_info.rs`](https://github.com/supermagnum/galdralag-firmware/blob/main/crates/cess/src/inner_info.rs)).
Los integrados de **una sola capa** omiten etiquetas adicionales; los perfiles **personalizados** (sin `suite_id`)
mantienen la cascada heredada sin MAC entre capas. Consulta
[docs/CIPHER_PROFILES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILES.md) y
[docs/CESS_CONFORMANCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CESS_CONFORMANCE.md). **Recuentos de combinaciones**
bajo las reglas de cifrado de `cipher-profile` (**cinco** primitivas AEAD, **ningún cifrado
repetido** en un perfil, el orden importa); la columna BLAKE3 es el recuento del **espacio de diseño**
de CESS (activado/desactivado independiente por hueco), no un conmutador del host por mensaje:
| Longitud de cascada | Pilas de cifrados distintos ordenados | × BLAKE3 opcional activado/desactivado en cada uno de los **longitud−1** huecos entre capas |
|:--------------:|--------------------------------:|---------------------------------------------------------------------------:|
| 1 capa | 5 | 5 × 2^0 = **5** |
| 2 capas | 20 | 20 × 2^1 = **40** |
| 3 capas | 60 | 60 × 2^2 = **240** |
| 4 capas | 120 | 120 × 2^3 = **960** |
| **Total** | **205** | **1245** |
La cifra **205** cuenta **solo las pilas de cifrados** (permutaciones de 1–4 opciones
distintas de AES-256-GCM, ChaCha20-Poly1305, Twofish-256, Serpent-256, Camellia-256). La
cifra **1245** es la misma pila multiplicada por cada patrón **independiente**
de activado/desactivado para el BLAKE3 opcional entre capas (**2^(k−1)** patrones para **k**
capas). **Este firmware** aplica MAC entre capas para **todos** los huecos cuando un
perfil integrado con **`suite_id`** tiene **≥ 2** capas (no es un conmutador por hueco).
Los nombres de perfil integrados usan un subconjunto **pequeño** de los 205.
- **Volumen señuelo microSD opcional** — si hay un chip PSRAM instalado, puede aparecer una LUN
señuelo de datos masivos adicional tras el desbloqueo. **Si no hay microSD instalada, el dispositivo
sigue siendo un token de seguridad de hardware** (bóveda, política de PIN, OpenPGP/CCID y otras
funciones de token no cambian); solo falta ese volumen masivo opcional. Para
hosts no informados, el dispositivo sigue presentando la persona señuelo habitual de almacenamiento masivo
en chip donde esté configurada. El contenido de la microSD, cuando está presente, está intencionadamente
sin cifrar y sin nada destacable. El material de clave real reside en la RRAM del chip detrás de la
bóveda y la política de PIN.
- **Pila totalmente abierta** — RTL CERN-OHL-W-2.0, esquemáticos abiertos, cargador de arranque
reproducible, sistema operativo Rust/Xous, silicio inspeccionable con IRIS.
### Cuórum de doble clave de hardware (patrón de integrador)
**Qué es:** Una forma de que las organizaciones exijan **dos (o K-de-N) tokens
físicos o titulares de participaciones separados** antes de que un **sistema posterior** desbloquee algo
crítico — discos cifrados, sesiones de administración de **firewall o servidor**, **bóvedas de
medicamentos**, puertas seguras u otras acciones privilegiadas.
**Qué proporciona Galdralag:** Cada token es **una credencial independiente**:
autenticación de tarjeta OpenPGP (token + PIN) y, mediante herramientas del host, **exportación de
participaciones Shamir** del material de clave a largo plazo ([`vault::shamir`](https://github.com/supermagnum/galdralag-firmware/blob/main/crates/vault/src/shamir.rs),
[`galdra shamir`](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILES.md)). Las **identidades públicas** estables (huellas
OpenPGP, números de serie del token) respaldan los registros de auditoría de **qué clave se usó, cuándo**.
**Qué no proporciona Galdralag:** El firmware y las herramientas del host **no bloquean**
firmar, descifrar o desbloquear hasta que dos tokens estén presentes juntos. La **aplicación del cuórum**,
las ventanas de tiempo de sesión, el entorno seguro de reconstrucción y los **registros de acceso**
a prueba de manipulación son responsabilidad del **integrador** — demonio de desbloqueo LUKS,
gestión de acceso privilegiado (PAM), software de puertas/paneles o pasarela de política personalizada.
**Patrón típico:** Divide un secreto maestro de desbloqueo **2-de-3** (o similar); el custodio
A tiene la participación 1 en el token A, el custodio B tiene la participación 2 en el token B; en el momento del desbloqueo
la pasarela recoge **K** participaciones o **K** firmas de token, reconstruye o autoriza
**una vez**, y luego pone a cero el secreto. Alternativa: dos operaciones **SIGN** de OpenPGP
sobre un desafío dentro de una ventana de tiempo, sin reconstrucción Shamir.
Este es un **patrón de extensión compatible** que usa primitivas existentes — **no** una
característica de producto incluida y **no** un compromiso de hoja de ruta. Diseño, límites
de responsabilidad, notas de seguridad y registro de responsabilidad: [docs/DUAL_KEY_QUORUM.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/DUAL_KEY_QUORUM.md).
Consulta también [Intercambio de secretos Shamir y cifrado de unidades](#intercambio-de-secretos-shamir-y-cifrado-de-unidades)
y [docs/AUDIT_LOG.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/AUDIT_LOG.md).
### Capacidades criptográficas
Todas las primitivas provienen de dependencias del espacio de trabajo auditadas de forma independiente.
Nada está implementado en el árbol.
#### Asimétrico / acuerdo de claves
| Algoritmo | Estándar | Notas |
|-----------|----------|-------|
| BrainpoolP256r1 ECDH + ECDSA | RFC 5639, BSI TR-03111 | Estandarizado por BSI, sin participación de la NSA |
| BrainpoolP384r1 ECDH + ECDSA | RFC 5639, BSI TR-03111 | Seguridad de ~192 bits |
| X25519 ECDH | RFC 7748 | |
| Ed25519 firmar / verificar | RFC 8032 | |
| RSA-2048 / 3072 / 4096 OAEP, PSS, PKCS#1 v1.5 firmar/verificar | RFC 8017 | Solo biblioteca `galdr-vault` (mínimo 2048 bits). Cifrado/descifrado OAEP-SHA256; firmar/verificar PSS SHA-256/SHA-512; firmar/verificar PKCS#1 v1.5 detrás de un marcador `Pkcs1v15` en el código fuente (solo interoperabilidad heredada, no para nuevos diseños de protocolo). **No** accesible a través de la aplicación de tarjeta OpenPGP — SIG/DEC/AUT no operan con RSA; consulta [docs/OPENPGP_CARD.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/OPENPGP_CARD.md). |
| P-256, P-384 | NIST | Mediante dependencias del espacio de trabajo `p256` / `p384` |
#### Simétrico / AEAD
| Algoritmo | Estándar | Notas |
|-----------|----------|-------|
| AES-256-GCM | FIPS 197, NIST SP 800-38D | AES por hardware en Baochip-1x |
| ChaCha20-Poly1305 | RFC 8439 | Sin participación de la NSA |
| Twofish-256 | Schneier et al. 1998 | Finalista de AES, sin participación de la NSA |
| Serpent-256 | Anderson / Biham / Knudsen 1998 | Finalista de AES, 32 rondas, margen conservador |
#### Derivación de claves / MAC / digest
| Algoritmo | Estándar |
|-----------|----------|
| HKDF (SHA-256 / SHA-512) | RFC 5869 |
| HMAC (SHA-256 / SHA-512) | RFC 2104 |
| PBKDF2 | RFC 8018 |
| SHA-2 (224 / 256 / 384 / 512) | FIPS 180-4 |
| Familia SHA-3 | FIPS 202 |
| BLAKE2b / BLAKE2s | RFC 7693 |
| BLAKE3 | Especificación BLAKE3 |
#### Gestión de claves
| Característica | Notas |
|---------|-------|
| Intercambio de secretos Shamir K-de-N | `vsss-rs` — división y recuperación en el dispositivo |
| ECDH efímero autenticado | Protocolo de sesión con secreto hacia adelante — crate `ephemeral-session` |
| Sistema de perfiles de cifrado | **Cascada** simétrica: **hasta cuatro** AEAD diferentes apilados (p. ej. **tres** capas independientes); claves por capa — `cipher-profile` — [docs/CIPHER_PROFILES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILES.md) |
### Propiedades de seguridad
| Propiedad | Implementación |
|----------|---------------|
| Secreto hacia adelante | ECDH efímero: la clave a largo plazo solo firma, nunca acuerda |
| Contador de PIN antes de comparar | Contador vaciado a RRAM antes de `subtle::ConstantTimeEq` — sin excepciones |
| Puesta a cero por hardware | Sobrescritura multipaso originada en TRNG; boot0 pone a cero antes de la enumeración USB |
| Sin secretos en el bus USB | El host no informado ve solo almacenamiento masivo estándar; sin huella posible |
| Evidencia de manipulación monótona | Contadores unidireccionales por hardware en dominio siempre activo |
| Autenticación de tres factores | **Posesión:** token USB; **conocimiento:** PIN en el dispositivo (`pin-policy`); **biométrico** opcional no implementado — [docs/THREE_FACTOR_AUTH.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREE_FACTOR_AUTH.md) |
| Contadores RRAM y rastro de auditoría | HAL monótono para PIN (y futuras firmas PQ con estado); registros de auditoría de perfil y gancho de auditoría OpenPGP en RAM — registro de auditoría NV de solo añadido **no** implementado — [docs/AUDIT_LOG.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/AUDIT_LOG.md), [docs/RRAM_LAYOUT.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/RRAM_LAYOUT.md) |
| Operaciones en tiempo constante | Todas las comparaciones de secretos mediante `subtle`; verificado por arneses dudect |
| test-hal nunca en producción | Aplicado por `check-fw` (firmware) y `check-host` (binarios de host de lanzamiento) |
### Política de PIN
- Longitud mínima: **5 caracteres alfanuméricos** — aplicada en el límite del analizador,
antes de que se llame a `pin-policy`. Las entradas cortas no incrementan el contador.
- Umbral de intentos predeterminado: **3** (configurable **3–10** en el aprovisionamiento).
Coincide con el estándar de la industria de tokens de hardware (Nitrokey, YubiKey, ISO 7816).
- Al alcanzar el umbral: se activa la puesta a cero completa por hardware.
- Frase de contraseña de desafío/respuesta (ruta de host informado por USB): mínimo 5 caracteres,
transmitida solo como `HMAC-SHA256(HostChallengeKey, nonce || passphrase)`.
**Establecer o ajustar el umbral de intentos:** El límite del contador se escribe cuando el token se **aprovisiona por primera vez**; **no** es un ajuste de `gpg` en tiempo de ejecución. Usa la herramienta de host **`galdra`** después de [compilarla](#compilar-e-instalar-herramientas-de-host-galdra-galdrad-galdra-gtk):```bash
galdra device provision --pin-attempts 5
| Campo | Propósito | Host (galdra SQLite) | Almacén de contactos en chip | Formato / límite |
|---|
| ID de contacto | Clave primaria estable del host | Sí | No | Texto (id en SQLite) |
| Nombre para mostrar | Etiqueta legible por humanos | Sí | Sí | Cadena UTF-8; máx. 240 bytes por campo de heap en chip |
| Correo electrónico | Dirección de correo principal | Sí | Sí | Cadena UTF-8; búsqueda en chip por escaneo de correo |
| Indicativo | Indicativo de radioaficionado | Sí | Sí | 12 bytes, relleno con NUL; búsqueda en chip |
| ID de suscriptor DMR | ID de radio DMR | Sí | Sí | 32 bits sin signo (0 = ausente); búsqueda en chip |
| Número de placa | ID de empleado o placa | Sí | Sí | Cadena UTF-8 |
| Organización | Agencia o empleador | Sí | Sí | Cadena UTF-8 |
| Departamento | Equipo o unidad | Sí | Sí | Cadena UTF-8 |
| Rol | Etiqueta de puesto o función | Sí | Sí | Cadena UTF-8 |
| Nota | Comentario de formato libre | Sí | Sí | Cadena UTF-8 |
| Afiliación de radio | Etiqueta de club, red o alianza | Sí | Sí | Cadena UTF-8 |
| Calle | Línea de dirección postal | Sí | Sí | Cadena UTF-8 |
| País | Nombre o código de país | Sí | Sí | Cadena UTF-8 |
| Código postal | Código ZIP o postal | Sí | Sí | Cadena UTF-8 |
| Región | Estado, condado o región | Sí | Sí | Cadena UTF-8 |
| ID de Fluxer | Handle o ID de Fluxer | Sí | Sí | Cadena UTF-8 |
| ID de Discord | ID de usuario de Discord | Sí | Sí | Cadena UTF-8 |
| ID de IRC | Nick de IRC o similar | Sí | Sí | Cadena UTF-8 |
| Número de teléfono | Número de contacto de voz o SMS | Sí | No | Cadena UTF-8; máx. 32 caracteres en el host; declarado por el remitente, no verificado |
| Huella digital | Ancla de clave (búsqueda, sincronización) | Sí (pgp_fingerprint) | Sí | 32 bytes; estilo OpenPGP v4 en el cable; no es lo mismo que una huella digital de dispositivo G: |
| Clave pública | Material de cifrado / verificación | Sí (pgp_pubkey) | Sí (región de claves) | Algoritmo: Ed25519, X25519, Brainpool P-256/P-384/P-512, NIST P-256/P-384, RSA-2048/3072/4096; blob de hasta 768 bytes en chip |
| Clave protegida por PIN | La clave requiere desbloqueo con PIN | El host almacena claves OpenPGP por separado | Sí | Digest de verificación de PIN + metadatos de envoltura AES-GCM en chip |
| Última obtención | Cuándo se actualizó el material de clave | Sí (fetched_at) | Sí (last_fetched) | UTC en el host; marca de tiempo de 32 bits en chip |
| Expira en | Hora de expiración de la clave | Sí | No | Fecha y hora UTC solo en SQLite |
| Fuente de clave | Cómo se creó el registro del host | Sí (source) | No | p. ej. manual, keyserver, WKD, LDAP, archivo, peer |
| Procedencia de campo | Etiqueta de confianza por campo de metadatos | No | Sí (source_map) | Dos bits por campo: SelfAttested, HostVerified, RegistrySync, OobVerified |
| Indicadores de registro | Activo, obsoleto, identidad propia, revocado | Parcialmente (lógica del host) | Sí | p. ej. STALE, SELF_KEY en chip |
fuzz/README.mdtest-all --no-dudect: Omite la suite de temporización dudect (~15–20 minutos). El CI de pull-request usa esta bandera. Ejecuta cargo run -p xtask -- timing-test o test-all sin --no-dudect para la compuerta de temporización. El CI semanal (test-all-full) aún ejecuta dudect.docs/TEST_RESULTS.md para ver qué está en alcance.| Campo de metadatos | OpenPGP / GnuPG | Clave Galdra (host + almacén de contactos) |
|---|
| ID de contacto / registro | No (usar ID de clave o huella digital) | Sí (SQLite id en host; no en chip) |
| Nombre para mostrar | Solo dentro del texto del ID de Usuario (Nombre <correo>) | Sí (campo UTF-8 separado) |
| Correo electrónico | Solo dentro del texto del ID de Usuario | Sí (campo separado; búsqueda por correo en chip) |
| Dirección postal | Sin campo estándar | Sí |
| País | Sin campo estándar | Sí |
| Código postal / ZIP | Sin campo estándar | Sí |
| Región / estado | Sin campo estándar | Sí |
| Organización | Sin campo estándar | Sí |
| Departamento | Sin campo estándar | Sí |
| Rol / cargo | Sin campo estándar | Sí |
| Insignia / ID de empleado | Sin campo estándar | Sí |
| Indicativo | Sin campo estándar | Sí (12 bytes, rellenado con NUL en chip) |
| ID de suscriptor DMR | Sin campo estándar | Sí (32 bits; búsqueda en chip) |
| Afiliación de radio | Sin campo estándar | Sí |
| ID de Fluxer | Sin campo estándar | Sí |
| ID de Discord | Sin campo estándar | Sí |
| ID de IRC | Sin campo estándar | Sí |
| Número de teléfono | Sin campo estándar | Sí (solo SQLite en host) |
| Nota de formato libre | Sin campo estándar | Sí |
| Huella digital OpenPGP v4 | Sí (40 caracteres hex) | Opcional en fila del host al vincular un certificado (pgp_fingerprint); 32 bytes en chip para claves Galdra |
Huella digital de dispositivo G: | No | Sí (BLAKE3-160 sobre clave pública SIG; herramienta de host; no el valor OpenPGP v4) |
| ID de clave OpenPGP | Sí (forma corta / larga) | No |
| Confianza / procedencia | Firmas WoT en IDs de Usuario | Etiquetas por campo: SelfAttested, HostVerified, RegistrySync, OobVerified (en chip) |
| Caducidad de clave | Sí (certificado / subclave) | Solo host (expires_at en SQLite) |
| Hora de última obtención de clave | Dependiente de la herramienta del host | Sí (fetched_at / last_fetched) |
| Clave privada en token | Ranuras de tarjeta SIG, DEC, AUT | Región de clave Galdra separada (no paquetes de ID de Usuario) |
| PIN para usar clave privada | PW1 / PW3 (tarjeta OpenPGP) | Envoltura PIN opcional por registro de contacto Galdra |
| Objeto de tarjeta OpenPGP (no en la tabla anterior) | Host (GnuPG) | En token |
|---|
| Subclaves primaria + SIG / DEC / AUT | Públicas en llavero | Privadas en ranuras selladas |
| Firmas de certificación (WoT) | Sí | No |
| Certificado de revocación | Sí | No |
| Atributos de algoritmo (DO 0xC1 / 0xC2 / 0xC3) | gpg --card-edit | Sí |
galdragaldra-core-host| Alcance | Estándar / documento típico | ¿Expuesto como tarjeta OpenPGP estándar + GnuPG? |
|---|
| Aplicación de tarjeta OpenPGP — APDUs, PINs, ranuras SIG/DEC/AUT, generar/firmar/descifrar en tarjeta | Especificación de tarjeta OpenPGP (ver docs/OPENPGP_CARD.md) | Sí — misma pila host que otras tarjetas inteligentes OpenPGP (gpg, scdaemon, CCID) |
| USB CCID — comunicarse con el dispositivo como lector de tarjetas inteligentes | Clase de dispositivo USB CCID | Sí — controladores de clase |
| Formato de mensaje OpenPGP — archivos cifrados, correo, paquetes de claves | RFC 4880 (y actualizaciones) | Sí en el host — GnuPG lo usa; la tarjeta no analiza correo |
| Shamir K-de-N — dividir / recuperar material de clave a largo plazo en la bóveda | No en la especificación de tarjeta OpenPGP; no en GnuPG | No — solo firmware y herramientas de aprovisionamiento; no es una operación gpg --card-edit (ver Shamir y cifrado de disco completo) |
| Doble clave de hardware / autorización por quórum — se requieren dos (o N) tokens antes de que un consumidor actúe (desbloqueo de disco, liberación de puerta, operaciones privilegiadas) | No en la especificación de tarjeta OpenPGP | No — patrón de extensión soportado para integradores que usan Shamir y/o múltiples autenticaciones OpenPGP; la aplicación de la política pertenece al sistema downstream (docs/DUAL_KEY_QUORUM.md) |
| ECDH efímero autenticado — protocolo de sesión con secreto directo en el token | No en la especificación de tarjeta OpenPGP | No — específico del token; no es un comando de tarjeta GnuPG |
| Sistema de perfiles de cifrado — cascadas simétricas nombradas (apila cifrados independientes unos sobre otros; hasta cuatro capas, tres es una profundidad soportada) y política relacionada | No en la especificación de tarjeta OpenPGP | No — firmware / herramientas de token host |
| microSD señuelo / personas de almacenamiento masivo — comportamiento USB ante host desinformado | No en la especificación de tarjeta OpenPGP | No — rutas de código separadas de personalidad USB |
| WebAuthn / FIDO2 | CTAP / WebAuthn | No implementado — estándar diferente de la tarjeta OpenPGP |
| Capa | Rol |
|---|
| Disco | Cifrado con una clave maestra (p. ej. AES-256 vía LUKS, VeraCrypt o una capa de bloques en bruto) |
| Clave maestra | Dividida con SSS en N participaciones, umbral K-de-N |
| Participaciones | En manos de personas, dispositivos o almacenamiento fuera de línea; K participaciones juntas reconstruyen la clave maestra |
| Desbloqueo | Reconstruir la clave, luego pasarla a cryptsetup, veracrypt o tu pila |
| Opciones típicas |
|---|
| Umbral | 2-de-3 (equipo pequeño, algo de redundancia); 3-de-5 (común en organizaciones) |
| Almacenamiento de participaciones | Tokens de hardware, máquinas separadas, papel, sitios geográficamente divididos |
| Protección de participaciones | Cifrar cada participación para un destinatario específico (p. ej., con su clave OpenPGP) antes de la distribución |
| Dónde reconstruir | Máquina aislada (air-gapped), política HSM o entorno controlado — no en hosts compartidos no confiables |
| Escenario | Por qué importan SSS más curvas fuertes y alineadas con políticas |
|---|
| Un empleado se va o fallece | La recuperación sigue siendo posible sin el secreto exclusivo de esa persona |
| Acceso legal bajo debido proceso | Se puede exigir un quórum — ninguna parte individual posee el secreto completo de desbloqueo |
| Custodia corporativa de claves | División auditable; ningún administrador individual tiene acceso completo |
| Incautación de hardware | Los medios pueden ser capturados sin capturar K de N participaciones |
| Alineación regulatoria (UE / BSI) | Brainpool satisface muchos requisitos criptográficos alemanes y de la UE |
| Firma de Governikus | Confirma que el nombre en el certificado coincidió con la identidad autenticada por chip cuando el usuario completó el flujo |
| Jurisdicción | Estado tratado en este documento |
|---|
| Alemania | Flujo Governikus/BSI descrito arriba |
| Estonia | eID basado en chip. Migrado de RSA a NIST P-384 (secp384r1) ECDSA en 2017–2018 después de que la vulnerabilidad ROCA forzara el abandono total de RSA (el chip no podía generar claves RSA seguras y no tenía vía hacia tamaños de clave mayores). La clave privada está vinculada al hardware y no puede leerse de la tarjeta. No se encontró ningún servicio de firma OpenPGP estilo Governikus conocido. |
| Bélgica | eID basado en chip. Las tarjetas más antiguas usaban RSA de 1024 bits; las más nuevas (applet 1.8 en adelante) usan ECDSA NIST P-384. Ecosistema activo de middleware de código abierto (eid-mw, OpenSC). No se encontró ningún servicio de firma OpenPGP estilo Governikus conocido. |
| Noruega | El chip de la tarjeta de identidad nacional (emitida desde 2020) es compatible con ICAO 9303 e implementa solo un chip de documento de viaje; no lleva función de firma eID. La eID de firma es separada: proveedores privados acreditados (Buypass, Commfides) bajo SEID, históricamente RSA de 2048 bits, moviéndose a RSA de 3072 bits con ECC introducido en SEID 2.0. No se conoce ningún servicio de firma OpenPGP estilo Governikus. El chip de viaje y la eID de firma son distintos — relevante si alguien intenta usar solo el chip de la tarjeta directamente. |
| Austria | Investigado parcialmente. La eID usa ECC (confirmado); la curva específica no se confirmó en las fuentes disponibles. Modelo Bürgerkarte de múltiples tokens en lugar de una sola tarjeta; migrado en gran parte a una aplicación móvil. Se necesita más investigación sobre los detalles de la curva y cualquier servicio de firma OpenPGP. |
| EE. UU. | Tarjeta PIV (Personal Identity Verification, FIPS 201 / NIST SP 800-78): emitida solo a empleados y contratistas federales — no una tarjeta civil universal. Algoritmos: NIST P-256 obligatorio para claves de autenticación; P-256 o P-384 para firma/gestión de claves; RSA 2048/3072 también permitido; solo curvas NIST, sin Brainpool. La raíz de confianza es la Federal Common Policy CA (FCPCAG2), no incluida en los almacenes de confianza comerciales estándar. No se encontró ningún servicio de firma OpenPGP estilo Governikus; FPKI es una infraestructura X.509 separada de OpenPGP. Que PIV sea solo federal significa que no es un ancla de confianza civil como la eID alemana. |
| Canadá | No existe tarjeta nacional de identidad basada en chip con claves de firma en el chip. La identidad digital está fragmentada entre esquemas provinciales (por ejemplo, BC Services Card), aplicaciones móviles (por ejemplo, eID-Me) y un marco federal de credenciales digitales en evolución. No hay una sola tarjeta comparable al modelo alemán, estonio o belga. No se encontró infraestructura de tarjeta equivalente — no es un ancla de confianza viable en este sentido. |
| Otros países | No investigado |
| Objetivo | Dónde empezar |
|---|
| Resumen del proyecto, noticias, comunidad | sequoia-pgp.org |
| Contribuir (issues, correcciones, características, documentación); contactar antes de trabajo grande | Contribute, Contact |
Docs de desarrollador — superficie de API para extender la implementación (sequoia-openpgp y crates relacionados) | Docs — p. ej. sequoia-openpgp en docs.rs |
| Código fuente y rastreadores | gitlab.com/sequoia-pgp (biblioteca central y herramientas); github.com/sequoia-pgp (espejos / repos seleccionados); Projects |
| Nuevos algoritmos en el estándar OpenPGP | Siguen pasando por el grupo de trabajo OpenPGP de la IETF. Sequoia y otras implementaciones implementan borradores y RFC; proponga cambios de protocolo allí y coordine con los implementadores (incluido Sequoia) para que el comportamiento coincida con la especificación. |
streetcountrypostal_coderegiondmr_idradio_affiliationgaldra contact showPATCHDELETEGET /contacts/{id}galdradrecipientPOST /decryptgaldra keyserver pushorganisationrolenotebadge_numberphone_numbergaldra keyserver push --help