
本项目已在 开放发明网络(OIN) 注册。OIN 是一个防御性专利池:成员之间交叉许可与 Linux 相关的专利,使参与者能够在降低专利风险的情况下发布和使用开源软件。
状态:等待: https://github.com/betrusted-io/xous-core/pull/937
面向运行 Xous 微内核的 Baochip-1x(Dabao 评估板)设备的固件,为 riscv32imac-unknown-none-elf 构建。
其位置如下: https://www.baochip.com/
该设备是一款硬件安全令牌,与 Nitrokey 类设备属于同一类别,具有 OpenPGP 智能卡类行为和一个加密保险库。完整的硬件栈 — RTL、原理图、引导加载程序、操作系统 — 均为开源且可审计。
硬件规格、引导模型、需求表和 ComboHash/PKE 用法记录在 Supermagnum/Baochip-1x-firmware 中。Dabao 评估板(KiCad、原理图、开关、引脚布局)位于 baochip/dabao。要进入引导加载程序模式进行烧录,按下 SW2 进行切换(参见该仓库的原理图)。本仓库的架构说明:docs/ARCHITECTURE.md。
Galdra 主机工具维护一个本地 SQLite 收件人(联系人)目录。每个存储的身份包含公钥材料以及可选的侧车标签(参见下表)。这些标签存在于主机数据库中,对于 Galdra 密钥,也存在于片上联系人存储(crates/contact-store)中。除非您自行对齐,否则它们不会神奇地绑定到 OpenPGP 用户 ID,并且除非您带外检查,否则它们不会被密码学断言。可选的 galdra keyserver push 可以将重叠字段作为 JSON 与导出的公钥一起发送到项目注册表。令牌上的逐字段来源使用 SelfAttested、HostVerified、RegistrySync 和 OobVerified(参见 元数据对比(GnuPG 与 Galdra) 以及 docs/RRAM_LAYOUT.md 中的联系人存储布局)。
主机端详情和 CLI 行为:docs/GALDRA-TOOL.md。线上布局和槽位数量:crates/contact-store/src/layout.rs 和 docs/RRAM_LAYOUT.md。
该固件是 面向 Baochip-1x 的硬件安全令牌:一个基于 USB CCID 的 OpenPGP 卡应用程序,具有设备上保险库、PIN 策略和仓库特定功能(密码配置文件 — 您可以在一个级联中堆叠 最多四个不同的对称密码,每个都有自己派生的密钥;参见 关键能力)、Shamir 相关流程、已实现处的认证临时 ECDH,以及 Galdra 主机工具)。主要互操作目标是 GnuPG 风格的 OpenPGP 卡使用,而非市场上的每种令牌协议。
该固件不是:
与相同约束一致的 crate 级排除项列于 docs/future-todo.md 中的 明确排除的 Crates 下。
CESS: 该固件符合 CESS,适用于树内实现的规范性构造(包括 Mode A 外部 AEAD、用于 K_outer 的 HKDF-BLAKE3,以及逐字节 GF(2^8) Shamir 拆分)。完整的对齐声明、偏差登记表和认证级别(例如完整固定层的 CESS-CORE)记录在 docs/CESS_CONFORMANCE.md 和下方 CESS(相关开放标准) 中。
OpenPGP / CCID 应用程序逻辑位于 crates/usb-personality 中。在 Xous 上,暴露 CCID 的 USB 服务是 usb-bao1x(位于您的 xous-core 检出中),使用功能 ccid-openpgp 构建,并使用 crates/baochip-openpgp 处理 OpenPGP RRAM 窗口和配置。布局:docs/RRAM_LAYOUT.md。量产前差距(操作员 PIN 用户体验、平台映射签署):已知限制 / 待办工作。
总体目标仍然是完整、经过测试、开源硬件安全令牌固件:通过 CCID 为 GnuPG 提供 OpenPGP 卡风格行为(参见 OpenPGP 和 GnuPG 兼容性),以及当前 OpenPGP 卡标准未定义的额外设备上功能 — 具有前向保密性的临时 ECDH、Shamir K-of-N、密码无关配置文件、microSD 诱饵卷 — 如 标准与固件特定功能 中所总结。全部基于开放 RTL 和可复现的引导加载程序。
对于需要在解锁服务器、防火墙、药品保险库或加密卷之前使用两个独立物理令牌(或 K-of-N 份额持有者)的部署,请参见 关键能力 下的 双硬件密钥法定人数(集成器模式)。每个设备是一个凭据源;法定人数强制执行是您的访问网关、PAM 层或面板 — 而非此固件。
面向 Baochip-1x 的可发布固件使用 Ed25519 签名。您使用 Ed25519 私钥对固件镜像进行签名;GnuPG 可以使用 Ed25519 签名子密钥通过 gpg --sign 完成此操作(通常的 OpenPGP 分离签名工作流程,根据您的构建产出的打包方式进行调整)。SoC 中不可变的 boot0 ROM 在下一阶段 — boot1 — 被允许运行之前,会验证该签名是否与烧录到设备中的相应公钥(以及引导链的更广泛密钥清单)匹配。然后 boot1 加载签名的应用程序镜像(例如在引导加载程序模式下通过 USB 大容量存储交付的 UF2 blob)。默认部件携带四个片上 Ed25519 公钥(代码部署、测试版和开发者等角色);boot0 / boot1 在 Baochip 和第三方签名密钥之间强制执行相互不信任策略。完整引导流程、UF2 交付、控制台、boot1 更新和安全模型:xous-core 中的 Baochip 目标入门。
并非每个测试都会在每条命令中运行;这是有意为之。
xtask 不在默认工作区测试中: 常用配方是 cargo test --workspace --exclude xtask,因为 xtask 是构建编排 crate。当您需要其测试时,运行 cargo test -p xtask。#[ignore] 的测试: 除非您传递 --ignored(以及任何所需的 crate 过滤器),否则这些测试会被跳过。原因包括:已在聚焦单元测试中覆盖的测试(例如释放后清零)、慢速用例(例如 RSA 密钥生成),以及主机工具(如 galdra)中需要连接设备或夹具的硬件或令牌相关流程。test-all --no-fuzz: 跳过 cargo-fuzz 步骤以保持 CI 或快速运行简短,并避免该步骤需要 nightly 工具链;运行 cargo run -p xtask -- test-all(不带 --no-fuzz),或单独调用模糊测试目标(参见 fuzz/README.md)。test-all --no-dudect: 跳过 时序套件(约 15–20 分钟)。PR CI 使用此标志。运行 或 (不带 )以进行时序门控。每周 CI()仍会运行 dudect。当 PR 关闭时,也可以使用此命令检查 crate 的完整性: https://github.com/rust-lang/cargo/issues/16850
状态: 已准备好由人类在真实硬件上进行测试 — 尚无生产就绪版本。 它使用 Rust 编写,采用经过验证和审计的加密 crate。 密码学原语完全来自已审计的工作区依赖。 后量子算法为功能门控,并标记为 待独立审计。参见 后量子状态。
注意: 本项目的部分内容是在 AI 辅助(Claude、Anthropic)下开发的。 设计、密码学选择和安全性决策尚未经过 专业密码学家的审查。请将此视为实验性项目,并运用 您自己的批判性判断。在任何生产部署之前, 强烈建议进行独立专家审查。
它已准备好由人类进行测试。您决定是否构建或运行此软件的任何部分;可能存在单元测试、模糊测试和其他检查未发现的错误。使用可选的虚拟机进行实验降低了对您主机系统的风险,但并不能消除风险。详细结果见 测试结果(docs/TEST_RESULTS.md#run-metadata)。技术术语的通俗定义(A–Z):术语表。
主要开发者患有与计算障碍相关的神经系统疾病。计算障碍以某种方式影响数字感和相关符号处理,对他们而言,这使得传统编程 — 以手工编写代码编辑作为唯一工作流程 — 在没有辅助工具(例如对话式 AI 编辑器)的情况下不可行。该限制与正确性不同:审阅者仍应按照本页其他地方所述,权衡测试、模糊测试和独立审计。
审阅 Galdralag 的密码学家或严肃实现者通常会先打开 crates/vault/tests/ 和 crates/cipher-profile/tests/,然后再阅读文字。测试套件就是工作证明:它编码了无法仅靠叙述替代的领域知识。
这不是向其他人隐瞒这一点的理由。评估项目采购、决定是否贡献,或在不具备深入密码测试方法学培训的情况下发布代码的人,仍然值得获得指向具体证据的指引。查看内容: 一致性测试材料包括 crates/vault/tests/rfc_vectors/ 下的 RFC 8439 ChaCha20-Poly1305 工作示例、crates/vault/tests/data/wycheproof/ 下随附的 Wycheproof JSON(涵盖 ChaCha20-Poly1305 及 Brainpool ECDH/ECDSA 边界情况)、crates/vault/tests/bsi_vectors/ 下的 BSI TR-03111 BrainpoolP256r1 和 P384r1 向量、crates/vault/tests/blake3_vectors.json 下的官方 BLAKE3 参考向量(全部 35 种输入长度、全部三种模式)、crates/vault/tests/twofish_vectors.json 下的 Twofish 规范向量(1203 个案例,含 Monte Carlo),以及 crates/cipher-profile/tests/fixtures/cascade_cess_kat.json 下项目自有的 CESS 级联 KAT 固件(其中间值经过独立验证)。这些共同构成了运行器和审查者可通过 cargo test --workspace 和 python3 scripts/verify_cascade_kats.py 进行验证的基准真值。
RFC 8439 由互联网工程任务组(IETF)发布,该组织负责标准化互联网互操作的大部分规则。RFC(Request for Comments,意见征求稿)是协议及许多密码学规范的常见形式。RFC 8439 定义了 ChaCha20-Poly1305 认证加密(基于 Daniel Bernstein 的设计),并包含具体的输入和预期输出工作示例,以便独立实现能够逐字节核对是否与标准一致。RFC 附录示例中出现的、被广泛复现的明文开头 Ladies and Gentlemen of the class of '99: wear sunscreen 正是这样的例子:如果你的代码能精确复现 AEAD 输出,就强有力地证明你正确实现了该构造。这相当于密码学领域的官方答案。ChaCha20-Poly1305 是本固件中每个多层级联配置文件的内部层,因此这一检查是整个密码栈的基础。
Wycheproof 是谷歌安全团队(2017 年)发布的测试语料库。其名称源自澳大利亚的 Wycheproof 山——常被称为世界上最小的山——因为该项目专注于清除微小但致命的问题:整数溢出、边界情况、畸形输入和被篡改的认证标签;这些失败在真实部署的密码系统中反复出现。它是对 RFC 风格向量的补充:RFC 8439 风格的示例证明实现与已发布 AEAD 的正确性;Wycheproof 则强调实现历史上容易出错的鲁棒性。在本仓库中,Wycheproof JSON 涵盖 ChaCha20-Poly1305、AES-GCM、HMAC、HKDF、X25519、Ed25519、RSA 及 Brainpool ECDH/ECDSA 变体。
BSI TR-03111 是德国联邦信息安全办公室(Bundesamt für Sicherheit in der Informationstechnik)发布的椭圆曲线密码技术指南。2.10 版为当前修订版。本固件使用的 Brainpool 曲线——P256r1 和 P384r1——在 BSI 标准中有明确规定,因此 TR-03111 是其测试向量的自然参考。每条曲线均涵盖 ECDH 和 ECDSA;ECDSA 签名还额外使用 cryptography 库的独立 Python 实现进行了交叉验证。
BLAKE3 参考向量 是 BLAKE3 作者随规范一同发布的官方测试语料库。它们涵盖从 0 到 102400 字节的 35 种输入长度,专门用于测试短输入测试无法覆盖的所有内部分块和树哈希边界条件。BLAKE3 的三种模式——默认哈希、密钥哈希和派生密钥——均被覆盖。BLAKE3 在本固件中广泛用于 HKDF 密钥派生和级联密码配置文件中的层间完整性检查;边界覆盖之所以重要,是因为 BLAKE3 的树结构仅在超过 1024 字节时才激活。
该测试套件同时也是供应链篡改检测机制。 本固件中的所有密码学原语均来自经过审计的 RustCrypto crate——仓库内不实现任何密码学代码。由于上述一致性向量在每次 cargo test --workspace 时都会针对这些 crate 运行,任何被篡改或被替换的依赖都会在受损代码到达部署系统之前产生已知答案测试失败。python3 scripts/verify_cascade_kats.py 提供了第二条独立路径:一个 Python 实现检查级联 KAT 固件中的相同中间值,因此即使受损的 Rust 工具链产生错误输出,也会被交叉检查捕获。这比绑定 C 库具有更强的供应链完整性保障——后者对每个内部操作进行等效验证需要显著更多的精力和专业工具。
现在,这些说法是否属实,交由读者自行判断。
将其插入 USB 端口。从主机的角度来看,固件可以呈现加密模式或伪装模式。在加密模式下,你的计算机会看到一个智能卡:你可以像使用任何其他硬件安全令牌一样使用 GnuPG 或兼容的 OpenPGP 软件栈(什么是 GnuPG?)——令牌负责处理敏感的加密操作,因此你的私钥绝不会以未受保护的状态存在于计算机上。在伪装模式下,它可以枚举为普通的可移动存储设备,并带有看似无害的文件,因此快速查看不会暴露其真实用途;详见下文存储伪装。
GnuPG 是 GNU Privacy Guard 的缩写。它是 GNU 项目对 OpenPGP 的实现——OpenPGP 是密钥管理和密码保护消息的开放标准(与 PGP 属于同一概念家族,但在 RFC 4880 等文档和社区更新中有明确规定)。你通常在 Linux、BSD、macOS 或 Windows 上以 gpg 命令运行它;许多图形化邮件和密钥工具在其底层封装了它。
人们使用 GnuPG 来:
gpg-agent 从智能卡或本地密钥库暴露认证密钥时的 SSH 登录。GnuPG 与加密驱动器(LUKS)。 Linux 内置了一种加密整个驱动器或分区的方法,称为 LUKS。驱动器加密后,对没有密钥的人来说就像无意义的噪声,因此丢失或被盗的笔记本电脑不会泄露你的文件。
通常你通过输入密码来解锁此类驱动器。GnuPG 允许你改用令牌。原理很简单:驱动器的解锁密钥本身由你令牌的密钥锁定。当你想打开驱动器时,令牌会为你解扰该解锁密钥,但仅在令牌已插入且你已输入 PIN 的情况下。拔出令牌后,即使在同一台计算机上,驱动器也无法打开。
简而言之,这使令牌成为你加密驱动器的物理钥匙。设置过程(以及添加备用进入方式,以防令牌丢失)使用 Linux 自带的磁盘工具完成;令牌仅负责持有密钥。如果你希望多人共享解锁驱动器的能力,使任何人都无法单独完成,请参阅 Shamir 秘密共享与驱动器加密。
默认情况下,GnuPG 将密钥存储在 ~/.gnupg 下。使用 OpenPGP 智能卡时,敏感的私钥存储在卡上;scdaemon(GnuPG 套件的一部分)通过 CCID/USB 与卡通信,而 gpg 仍在主机上组装 OpenPGP 数据包。
你可以用它做什么。 在加密模式下,令牌的用途与其他 OpenPGP 智能卡相同:签名和解密邮件和文件、身份验证(例如像往常一样使用 gpg-agent 进行 SSH),以及将长期私钥保存在你输入信息的机器之外。组织可以将其与令牌上的 Shamir 份额结合使用,使没有任何单人持有完整秘密(下文将进一步描述)。GnuPG 是主机上的主要互操作目标:本固件通过 CCID 实现 OpenPGP 卡应用,由 scdaemon 驱动(gpg --card-status、gpg --card-edit,以及使用卡上密钥进行正常的加密/签名/解密)。其他使用相同智能卡协议(smart-card protocols)的软件也可能正常工作;命令、插槽、算法和当前集成限制见 OpenPGP 与 GnuPG 兼容性。当 NFC 在硬件上启用时(计划中的集成——尚未包含在固件中),同一设备类别可以支持物理访问:在门、闸机或门禁面板上轻触 NFC 读卡器,可以参与仅在密码学检查通过后才释放锁的策略(通常根据部署情况与 PIN、生物识别或 Shamir 式法定人数结合)。面向读卡器和面板的 PN532 相关方案见 docs/NFC_PN532_INTEGRATION.md。
以上就是简要版本。以下是它与你可能遇到的其他令牌的不同之处。
存储伪装。 该设备可以充当普通可移动存储设备,使其真实用途不易被快速查看发现。当你将其插入典型计算机时,它可以显示为普通 USB 驱动器或 SD 支持的卷;你可以用看似日常的文件(例如度假照片)填满可见文件系统,使随意浏览强化其仅为存储的印象。这可以挫败在办公桌或检查站的表面检查。要发现它实际上是安全令牌,通常需要拆开外壳,而不仅仅是插入。
你的密钥保留在设备上。 当你签名电子邮件或解密文件时,私钥永远不会离开令牌。计算机将数据发送进来,令牌完成工作,结果返回。入侵你计算机的攻击者得不到任何有用的东西。
即使令牌被盗,过去的会话仍然安全。 大多数硬件令牌直接使用长期私钥进行密钥协商。本令牌为每次会话生成全新的临时密钥对,用长期密钥签名以证明其真实性,然后使用临时密钥对进行实际交换。如果多年后有人偷走令牌并以某种方式提取长期密钥,他们仍然无法解密过去会话的任何内容。这一特性称为前向保密,在硬件令牌中并不常见。
你可以将密钥拆分给多人。 令牌可以将长期密钥分成 N 份份额,使得重建密钥需要其中任意 K 份——但没有任何单一份额持有者能单独完成任何操作。这称为 Shamir 秘密共享。它适用于组织密钥,即不应有任何单人拥有单方面访问权,或作为备份策略,将份额存储在不同位置。这在硬件令牌中也不常见。
加密是分层的。 令牌不是用单一密码加密你的数据,而是可以依次通过多个独立密码运行——例如 ChaCha20,然后 Serpent,然后 Twofish——每个密码使用单独派生的密钥。未来对一种密码的突破不会影响其他密码。具体组合称为密码配置文件(cipher profile),你可以根据情况所需的谨慎程度从多个内置配置中选择。
我个人推荐 BrainpoolP256r1 + ChaCha20-Poly1305 + BLAKE3。这是内置的 standard 配置文件。它使用 BSI Brainpool P-256 曲线进行临时密钥协商,使用 ChaCha20-Poly1305 进行对称加密,使用 BLAKE3 进行密钥派生和层间完整性。它速度快、经过充分测试、对电池友好(ChaCha20-Poly1305 设计为在没有 AES 加速的硬件上高效运行,减少 CPU 时间和主机功耗;P-256 是本固件中三种 Brainpool 曲线中最小的),并且不依赖任何 NIST 设计的原语。如果你需要更高的安全边际以应对未来对单一密码的密码分析突破,conservative 配置文件会在其上增加 Serpent-256 层。
算法选择是经过深思熟虑的。 所使用的密码——ChaCha20-Poly1305、Serpent、Twofish、Camellia——均独立于政府标准机构设计。AES 和 NIST 套件被有意排除。这是为希望在任何单一国家标准流程之外获得密码学独立性的用户和组织做出的自觉选择。Camellia 由欧盟 NESSIE 项目和日本 CRYPTREC 计划独立评估,并在 RFC 3713 和 ISO/IEC 18033-3 中有明确规定。
错误的 PIN 会正确地将你锁定。 令牌在检查 PIN 是否正确之前先计数失败的 PIN 尝试次数,而不是之后。这意味着尝试中途崩溃或断电无法被利用来重置计数器。错误尝试次数过多后,令牌会清零敏感材料。
它尚未实现的功能。 目前还没有可用的硬件——这是正在积极开发中的固件。使用真实 USB 硬件和 GnuPG 的端到端测试是未来的里程碑。NFC 传输和门式访问读卡器在文档中被描述为集成目标,而非已交付的行为。文档中描述的生物识别第三因素尚未实现。一些需要真实硬件的时序侧信道测试在设备存在之前无法完成。
Galdralag 可以同时使用两种不同类型的非对称密钥。它们在设备和主机上回答不同的问题,即使属于同一个人也不能互换。OpenPGP 与 GnuPG 兼容性、信任网与密钥签名聚会、Galdra 联系元数据和元数据比较(GnuPG 与 Galdra)各节详细描述了每个栈;以下是它们在日常使用中的区别。
OpenPGP 密钥,在 GnuPG 生成和使用的意义上,是一个结构化数据包,而非裸公钥数字。它捆绑了主密钥、用于签名和加密的子密钥,以及一个或多个 User ID——通常是显示名称和电子邮件地址,如 Alice Example <[email protected]>。其他人可以签名这些 User ID,以表示他们相信身份声明是真实的;这种社交图谱是本文档后面信任网与密钥签名聚会中描述的信任网的基础。当 Galdralag 充当 OpenPGP 智能卡时,它在芯片上持有私钥材料并在那里执行签名和解密。公钥、User ID 和他人的签名存在于主机上,由 GnuPG 以通常方式管理。令牌不会改变线路上的 OpenPGP 消息格式;GnuPG 将其视为任何其他 OpenPGP 卡。
Galdra 密钥是裸非对称密钥对——Ed25519、X25519,或固件支持的 Brainpool 或 NIST 曲线之一。密钥字节本身不携带任何身份声明:没有 User ID 数据包、没有内嵌的电子邮件、没有附加到密钥结构的信任网签名。Galdra 密钥的身份来自主机 SQLite 数据库中存储在其旁边的联系记录以及芯片上的联系存储,通过其指纹与密钥关联。
下表逐字段比较身份和联系元数据。OpenPGP / GnuPG 列描述从普通证书和 User ID 获得的内容(加上在 Galdra 中存储 OpenPGP 公钥时可选的主机侧联系行)。Galdra 密钥列描述操作联系人的结构化 sidecar 字段(完整的主机和芯片详情见 Galdra 联系元数据)。破折号表示该栈没有该项目的标准独立字段。
OpenPGP 将名称和电子邮件放在一个 User ID 字符串中;它不提供独立的、机器可读的呼号、DMR 或邮政字段。Galdra 将这些保留为命名列,使无线电和运营团队无需解析证书文本即可搜索和显示它们。
从提供 BrainpoolP512r1 的固件升级而来的令牌在 GET DATA 时可能仍返回 P-512 属性;这些插槽上的 GnuPG 操作随后会以通用卡错误失败。运行 galdra device status(或参阅 docs/OPENPGP_CARD.md)以识别过时插槽;移除背景见 CHANGELOG.md。
| PW1 / PW3 | 从不存储 | 芯片上的验证器(最少 5 个字符,默认 3 次尝试) |
| 持卡人 DO(登录名、语言、URL 等) | 由 GnuPG 缓存 | 可选(每个 DO 最多 254 字节) |
卡应用 3.4.1、CCID 和 GnuPG 工作流:docs/OPENPGP_CARD.md 和 OpenPGP 与 GnuPG 兼容性。拆分的原因是,Galdralag 所针对的社区中真正重要的身份信息——呼号、DMR ID、无线电网络归属——在 OpenPGP 用户 ID 中没有自然的归属位置。用户 ID 是为姓名和电子邮件设计的。将类似 LA5XYZ <[email protected]> DMR:2345678 的内容写入用户 ID 字符串,既非正式、也无结构,且无法以任何标准方式被机器读取。Galdra 密钥保持加密材料的整洁,并将操作身份放入宿主工具和片上存储原生理解的记录格式中。
实际上,单个设备可以同时持有两种密钥而互不冲突。OpenPGP 卡应用通过标准的 SIG、DEC 和 AUT 槽位为 GnuPG 提供服务。联系人存储则持有用于操作工作的 Galdra 密钥——例如按呼号加密给某个无线电联系人、根据 DMR 订阅者 ID 校验消息,或按徽章编号查找同事。这两条路径互不干扰。
如果某人在宿主机上拥有由 GnuPG 管理的 OpenPGP 证书,并且在片上联系人存储中拥有 Galdra 密钥,那么这是两个独立的密钥,具有两个独立的指纹。Galdra 指纹——以 G: 为前缀,并使用 BLAKE3 从原始公钥字节派生——并非该人 GnuPG 证书的 OpenPGP v4 指纹。宿主工具和设备将它们视为独立的身份。不要假设一个指纹意味着另一个指纹,除非你同时核验两者。
两种密钥类型都不会自动为其周围的标签背书。OpenPGP 用户 ID 是自我声明的,直到其他人对其签名。Galdra 联系人记录中的呼号或 DMR 字段,其可信度仅取决于其来源——密钥服务器获取、手动输入,或你自行执行的带外核验。来源标签(SelfAttested、HostVerified、RegistrySync、OobVerified)记录字段如何到达;它们并不能替代你实际核验所关心身份的工作。
该固件使用 Rust 编写,这是一种系统编程语言,设计目标是与 C 或 C++ 一样快速且底层,但在安全性方面采用了根本不同的方法。
每个依赖项都被分类为上游未修改(按发布版本来自 crates.io)、在树内修改或供应商化(固定副本或工作区补丁),或由本项目创建(固件、宿主和工具 crate)。完整的清单、角色和依赖关系图见 docs/CRATE_DEPENDENCIES.md。
行业代码库中大量与安全相关的缺陷源于内存不安全(缓冲区溢出、释放后使用、空指针解引用等)。微软的 MSRC 多次报告,其自身产品中解决的约 70% 的 CVE 属于此类;Chrome 团队也发布了类似比例的 Chrome 数据。这些数字描述的是这些厂商的产品,并非适用于所有固件的普遍规律,但它们说明了内存安全语言为何重要。
在安全 Rust(默认模式)中,借用检查器在编译时排除数据竞争和常见的未定义行为内存错误,无需依赖垃圾回收。不安全 Rust 和与 C 的 FFI 仍可能引入内存缺陷;它们必须保持最小化并接受审查。
Rust 对切片执行的边界检查及其所有权规则减少了 C/C++ 嵌入式代码中常见的几类故障模式:
unsafe 块必须显式声明;寄存器的 MMIO 和裸指针位于其中,因此审查者可以grep 审计面(unsafe 并不能使错误的 MMIO 变得不可能,只是更容易定位)。Rust 本身并不能阻止逻辑缺陷,例如导致闪存磨损的紧循环,或选择错误的寄存器值。这些仍然是工程和审查方面的问题。
此代码库应用了常见的 Rust 密钥处理模式;它们并非对每种类型自动生效:
zeroize::Zeroize / ZeroizeOnDrop 的类型在丢弃时清除缓冲区;调用者需主动选择使用。subtle::ConstantTimeEq(及类似工具)——普通的 == 并不会神奇地变成恒定时间。Copy 以减少意外复制;域分离使用不同的类型和 HKDF 标签(加密依赖策略)。catch_unwind 或 abort 策略。unsafe 必须在源码中明确写出,这缩小了人工审查的范围。依赖项: 本项目的加密策略倾向于经过审计的 Rust crate(RustCrypto 及其他);见 加密依赖策略 中的表格——并非每个依赖项都来自单一伞形项目。关于完整的 crate 列表以及每个依赖项是未修改、修改/供应商化还是项目自有的,请参阅 docs/CRATE_DEPENDENCIES.md。
Rust 并不能消除死锁(例如 Mutex 锁顺序错误)、逻辑缺陷、错误的协议、由不良循环导致的闪存磨损、物理攻击(故障注入、功耗分析),或正确构建的错误镜像带来的风险。它也不能保证在所有硬件上无需仔细编码即可实现恒定时间执行。这些领域依赖于设计、审查、测试,以及本 README 其他部分所述项目的加密和供应链实践。
验证(测试和模糊测试): 除语言本身外,此仓库还使用单元测试、集成测试、dudect 时序测试框架和 libFuzzer(cargo-fuzz)目标。摘要和矩阵见 测试结果;记录的运行元数据始于 docs/TEST_RESULTS.md#run-metadata。测试通过并不能证明生产就绪或不存在漏洞——它们只是缩小风险。您自行判断在您的环境中运行构建或测试是否可接受;虚拟机是可选的,但能限制对您机器的爆炸半径**。
任何主流虚拟机平台都适用——VirtualBox(免费、开源)、QEMU(免费、开源、命令行)或 VMware。建议使用 Linux 客户机,因为构建环境在该平台上支持最佳。
使用 QEMU 和 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
在虚拟机内部,标准构建说明同样适用。虚拟机可以在每次实验前进行**快照**,如果出现任何问题,可以干净地**回滚**。
### 风险评估与部署
**最终,此固件是否适合在您的环境中部署,只有您自己才能决定**,这取决于您自身的风险评估、您所保护数据的敏感性,以及您是否选择在部署前等待独立的第三方审计。本项目旨在为您提供做出该决定所需的全部信息。
资产、威胁 **T1–T14**、明确的非目标以及 Q2 验证差距的结构化列表位于 **[docs/THREAT_MODEL.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREAT_MODEL.md)**。
---
## 关于名称
**Galdr** 是古诺尔斯语中口头或歌唱魔法的实践:用于束缚、保护或揭示的咒语。在萨迦中,它指的是施放咒语本身的行为,而不仅仅是咒语文字。有时也用于激活魔法符文铭文,如 [Kragehul I 矛杆](https://en.wikipedia.org/wiki/Kragehul_I)、[Lindholm 护身符](https://en.wikipedia.org/wiki/Lindholm_amulet)、[Vadstena 金饰](https://en.wikipedia.org/wiki/Vadstena_bracteate) 以及其他 Elder Futhark 发现物。
**Galdralag** 是用于 galdr 的韵律形式:结构化、精确、遵循规则的诗歌,其中模式本身就是咒语力量的一部分。后缀 *lag* 类似于“法则”或“模式”。
**符文** 字面上是秘密的、编码的知识——萨满式的用法只有懂行的人才知道。
---
## 文档
**术语表:** [docs/GLOSSARY.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GLOSSARY.md) — 以**通俗语言**解释的术语(按 A–Z 排序)。如果 README 或其他文档感觉术语过多,请从这里开始。
**调试:** [docs/DEBUG_INSTRUCTIONS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/DEBUG_INSTRUCTIONS.md) — 回溯、缩小 `cargo test` 范围、`xtask` 快捷方式、固件三重检查、模糊测试,以及报告问题前应收集的内容。
**AI 助手(Claude、Cursor):** [CLAUDE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/CLAUDE.md) — 面向编码代理的项目说明。Cursor 特定规则:[`.cursor/rules/`](https://github.com/supermagnum/galdralag-firmware/blob/main/.cursor/rules)。
**浏览所有文件:** [github.com/Supermagnum/Galdralag-firmware — `docs/`](https://github.com/Supermagnum/Galdralag-firmware/tree/main/docs)
**硬件(USB 加密狗及相关):** 两个 KiCad 树:[Hardware/kicad-files-usb/](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-files-usb) — `dabao_v3c`(USB-A 令牌,**不带** micro-SD);以及 [Hardware/kicad-sd-card/](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-sd-card) — `dabao_v3c_sdcard`(相同基础布局,**带** micro-SD 卡座)、gerber 文件、BOM、生产输出,以及 [引脚文档](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-sd-card/docs/pinout/README.md)。USB-A 加密狗 PCB 布局(最小令牌 vs Pico 格式评估板)在 [docs/USB_DONGLE_PCB.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/USB_DONGLE_PCB.md) 中描述。
| 文档 | 描述 |
|----------|-------------|
| [Hardware/kicad-files-usb/](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-files-usb) | **USB 加密狗** KiCad 项目 `dabao_v3c`(无 micro-SD);gerber 文件、BOM、生产输出;补充 [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) | **USB 加密狗** KiCad 项目 `dabao_v3c_sdcard`(micro-SD 卡座);gerber 文件、BOM、引脚位于 [docs/pinout](https://github.com/supermagnum/galdralag-firmware/blob/main/Hardware/kicad-sd-card/docs/pinout/README.md);补充 [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) | 工作区**函数和模块索引**(每个文件的 `pub fn` / 带行锚点的类型) |
| [docs/CRATE_DEPENDENCIES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CRATE_DEPENDENCIES.md) | **上游 vs 项目** Rust crates 及其相互依赖关系 |
| [docs/API_REFERENCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/API_REFERENCE.md) | 代码映射 + IETF/I-D/GnuPG/Sequoia 的**附录**:Shamir GF(256) 构造、GALDRA SHARE 装甲、临时 ECDH 线格式、HKDF 标签、原像;`galdrad` 路由;rustdoc 提示 |
| [docs/ARCHITECTURE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/ARCHITECTURE.md) | 高层固件架构和主要子系统 |
| [docs/AUDIT_LOG.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/AUDIT_LOG.md) | 配置文件审计记录(`cipher-profile`)、OpenPGP `OpenPgpAudit` 钩子;**尚未**实现追加式 RRAM 日志 |
| [docs/BIOMETRIC_API.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/BIOMETRIC_API.md) | 生物识别前置门:架构、线格式、保险库布局;集成已部分实现 |
| [docs/BIOMETRIC_DEVICE_GUIDE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/BIOMETRIC_DEVICE_GUIDE.md) | 如何添加对新生物识别硬件后端的支持 |
| [docs/BIOMETRIC_TESTING.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/BIOMETRIC_TESTING.md) | 测试方法:ISO/IEC 30107-3 PAD 指标、数据集、运行方式 |
| [docs/FINGERVEIN_DEVICE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/FINGERVEIN_DEVICE.md) | ESP32-CAM 开放式手指静脉设备:硬件、协议草案、活体检测 |
| [docs/SWEET_PLATFORM_INTEGRATION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/SWEET_PLATFORM_INTEGRATION.md) | sweet 平台手掌扫描仪:硬件、集成、活体检测、数据集 |
| [docs/GALDRA-TOOL.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GALDRA-TOOL.md) | 主机工具(`galdra`、`galdrad`、`galdra-gtk`):工作流、配置、PIN 策略、操作行为 |
| [Supermagnum/Fulla](https://github.com/Supermagnum/Fulla) | **Fulla**:面向 WoT 的 OpenPGP 公钥注册表(服务器仓库和实现)。**目前尚无公开注册表实例在运行**;计划运行一个。**`galdra keyserver push`** / **`galdra keyserver fetch`** 以及可选的 **`[keyserver]`** 配置面向此生态系统——另见 [信任网和密钥签名聚会](#web-of-trust-and-key-signing-parties)。补充设计说明保留在 [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) | 面向非技术读者的**通俗语言术语表**(A–Z);技术细节保留在链接文档中 |
| [CLAUDE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/CLAUDE.md) | 面向 **Claude** / AI 编码代理的说明;指向 [`.cursor/rules/`](https://github.com/supermagnum/galdralag-firmware/blob/main/.cursor/rules) 以获取 **Cursor** 规则 |
| [docs/GALDRALAG_DEV_REFERENCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GALDRALAG_DEV_REFERENCE.md) | 工具链、`xtask` 命令、模糊测试和加密测试入口点 |
| [docs/dev-ref.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/dev-ref.md) | 工作区布局、crates、HAL 特性、USB/PSRAM 行为、安全不变量 |
| [docs/DEBUG_INSTRUCTIONS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/DEBUG_INSTRUCTIONS.md) | 调试:`RUST_BACKTRACE`、详细构建、范围测试、`xtask` 配方、嵌入式目标检查、模糊测试指引、OpenPGP 主机检查 |
| [docs/KEY_LIFECYCLE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/KEY_LIFECYCLE.md) | 密钥生成、导入、导出策略、轮换、清零、Shamir(如 `vault` / OpenPGP 中所反映) |
| [docs/OPENPGP_CARD.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/OPENPGP_CARD.md) | OpenPGP 卡应用、GnuPG/CCID 主机设置、密钥槽、算法、udev |
| [docs/CIPHER_PROFILES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILES.md) | 密码配置文件系统及配置 |
| [docs/DUAL_KEY_QUORUM.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/DUAL_KEY_QUORUM.md) | 双(或 N)硬件密钥法定人数作为 Shamir 和 OpenPGP 上的集成商扩展模式;固件不强制执行 |
| [docs/CIPHER_PROFILE_SECURITY.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILE_SECURITY.md) | 安全考量:明文配置文件标识符、流量分析、BrainpoolP384r1 外层包装理由、加密标识符、通配符属性 |
| [docs/CESS_CONFORMANCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CESS_CONFORMANCE.md) | [CESS](https://github.com/Supermagnum/CESS/tree/main) 对齐:Mode A 线布局、来自 [ALGORITHM-REGISTRY.md — 查找表](https://github.com/Supermagnum/CESS/blob/main/ALGORITHM-REGISTRY.md#cipher-suite-identifier-lookup-table) 的 `suite_id`、偏差登记(保留 AES/SHA-2 vs CESS-CORE)、路线图 |
| [crates/cess](https://github.com/supermagnum/galdralag-firmware/blob/main/crates/cess) | CESS Mode A:HKDF-BLAKE3(`derive_k_outer`、`hkdf_blake3`)、ChaCha 外层密封/开启、`suite_id \|\| inner_blob` 布局;参见 [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) | 认证临时 ECDH 会话协议 |
| [Supermagnum/CESS](https://github.com/Supermagnum/CESS) | **CESS**(*Cryptologically Enchanted Shamir's Secret*)— 阈值秘密共享的开放规范(规范性文本和测试向量),带认证加密、基于密码的份额包装,以及可选的后量子混合密钥交换;与本固件分离,但与本处的 Shamir 和密码配置文件处于同一设计空间 |
| [docs/PQ_SIGNATURES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/PQ_SIGNATURES.md) | 后量子有状态签名(XMSS、LMS/HSS)、特性门控 |
| [docs/Psram.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/Psram.md) | 可选 microSD 诱饵卷及相关行为 |
| [docs/RRAM_LAYOUT.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/RRAM_LAYOUT.md) | **4,194,304 字节**片上 RRAM:来自源码的保险库偏移、HAL 映射、磨损 / 清零说明 |
| [docs/TEST_RESULTS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/TEST_RESULTS.md#run-metadata) | 打开于**运行元数据**;流水线摘要、向量、dudect、cargo-fuzz([第 6 节](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/TEST_RESULTS.md#6-cargo-fuzz-libfuzzer))、密钥生命周期 |
| [docs/THREE_FACTOR_AUTH.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREE_FACTOR_AUTH.md) | 令牌 + PIN + 可选生物识别:本仓库实现的内容 vs 占位符;威胁草图 |
| [docs/THREAT_MODEL.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREAT_MODEL.md) | 威胁模型:资产、威胁 T1–T14、受保护与不受保护的内容、待 Q2 硬件验证的未验证项、审计状态 |
| [docs/PERFORMANCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/PERFORMANCE.md) | 性能说明 |
| [docs/HARDWARE_BRINGUP_TEST_PLAN.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/HARDWARE_BRINGUP_TEST_PLAN.md) | Q2 首版硬件启动:带 `galdralag-service` 的镜像、libccid `1D50:6197`、ATR → `gpg --card-status` APDU、Dabao 实验室 PIN(非 `dabao-ccid` 上的 CDC) |
| [docs/XOUS_CORE_UPSTREAM_REQUESTS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/XOUS_CORE_UPSTREAM_REQUESTS.md) | 应归属于 xous-core 的更改(Persona A 文档、ATR 策略、cratespec 说明);Galdralag 不修补该树 |
| [docs/HARDWARE_VERIFICATION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/HARDWARE_VERIFICATION.md) | 硬件清零:仿真 vs 硅片验证 |
| [docs/HARDWARE_TEST.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/HARDWARE_TEST.md) | 面向硬件的测试说明 |
| [docs/NFC_PN532_INTEGRATION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/NFC_PN532_INTEGRATION.md) | PN532 / NFC:libnfc、Rust 选项、门禁被动式 vs USB 面板、与 Shamir 和 PIN 的法定人数 |
| [docs/SDMMC_STORAGE_INTEGRATION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/SDMMC_STORAGE_INTEGRATION.md) | `embedded-sdmmc` + SPI microSD 作为可选大容量存储;BOM 中 PSRAM 的替代方案 |
| [docs/USB_DONGLE_PCB.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/USB_DONGLE_PCB.md) | 如何从 Dabao 参考设计制作 USB-A 加密狗 PCB:Pico 格式评估板用于固件启动;此设计移除 GPIO 排针以形成最小令牌;KiCad、FreeCAD、5 V / 500 mA vs USB-C PD、QSPI PSRAM 布线 |
相同路径可在 GitHub 上通过 [`tree/main/docs`](https://github.com/Supermagnum/Galdralag-firmware/tree/main/docs) 和 [`tree/main/Hardware`](https://github.com/Supermagnum/Galdralag-firmware/tree/main/Hardware) 解析。
---
## OpenPGP 和 GnuPG 兼容性
固件实现了 **OpenPGP 卡应用**(在 [docs/OPENPGP_CARD.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/OPENPGP_CARD.md) 中记录为版本 **3.4.1**)。这与 GnuPG 通过 **CCID/USB** 驱动 **OpenPGP 智能卡** 的设备类别相同:主机需要标准的智能卡栈(`pcscd`、`ccid` 驱动、GnuPG 的 `scdaemon`)。**无需**超出任何 OpenPGP 卡所需的自定义主机端加密驱动。
**这在主机上启用的功能(一旦设备作为 CCID 读卡器可见):**
| 领域 | 说明 |
|------|--------|
| **GnuPG 工作流** | `gpg --card-status`、`gpg --card-edit`、使用卡上密钥进行加密/解密和签名 |
| **SSH** | 带 `enable-ssh-support` 的 `gpg-agent` 以及常规的 `SSH_AUTH_SOCK` 设置 |
| **邮件和文件** | 使用 GnuPG 的客户端(例如 Thunderbird、Evolution、Kleopatra)以及标准 `gpg` 文件加密 |
| **其他工具** | 任何以与 GnuPG 相同方式与 OpenPGP 卡 + CCID 通信的工具 |
**密钥槽(典型默认值):** **SIG**(签名)、**DEC**(解密 / ECDH)、**AUT**(认证,例如 SSH)。每个槽位的操作算法为 Brainpool 曲线、NIST P-256/P-384 以及 Ed25519 / X25519。RSA 算法属性可通过 PUT DATA 存储,但 GENERATE、PSO:CDS 和 PSO:DECIPHER 对配置为 RSA 的槽位均失败。完整表格和 `key-attr` 行为见 [docs/OPENPGP_CARD.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/OPENPGP_CARD.md)。
**此处 OpenPGP 卡 / GnuPG 不涵盖的内容:** **WebAuthn / FIDO2** 是不同协议,不在本卡应用的范围内(参见同一文档)。
**OpenPGP 卡 vs. OpenPGP 消息:** **卡**规范定义了令牌如何通过 CCID 暴露 PIN、密钥槽和卡上操作。**GnuPG** 通过 `scdaemon` 使用该规范。文件和邮件的 **OpenPGP 消息格式**(RFC 4880 及其后继者)是**主机端**层:卡提供密钥;GnuPG 仍在 PC 上应用消息格式。卡规范或 RFC 4880 均未定义 **Shamir 分割**、**临时 ECDH 会话**或**密码配置文件**——这些是[固件特定功能](#standards-vs-firmware-specific-features)。
**集成状态:** OpenPGP 和 CCID 逻辑位于 **`usb-personality`**、**`baochip-openpgp`** 以及 Xous 的 **`usb-bao1x`** 服务中(参见 **`feature/usb-bao1x-ccid-openpgp`** 分支上的 **xous-core**)。可选的 **`galdralag-service`**(`services/galdralag`)连接到 **`usb-bao1x`** 以进行 **CCID** IPC,并应答 **XfrBlock** APDU;Dabao 镜像通过 cratespec 需要它(`scripts/build_dabao_ccid_image.sh`)。BaoSec 仍可能将 **PDDB** 桥接到 **RRAM**。详情:[services/galdralag/README.md](https://github.com/supermagnum/galdralag-firmware/blob/main/services/galdralag/README.md)。内存布局:[docs/RRAM_LAYOUT.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/RRAM_LAYOUT.md)。**在真实硬件上进行端到端 GnuPG** 仍需要包含 Galdralag 的完整镜像、主机 **libccid** 对 **`1D50:6197`** 的识别,以及[已知限制 / 未完成工作](#known-limitations--open-work)下列出的项目。
## 令牌会话和密钥导出
**物理断开(拔除):** 主机丢失 USB 设备;任何进行中的操作都会失败,直到令牌重新连接并重新枚举。在设备上,OpenPGP **卡会话**被清除:**PIN 验证状态**在断电或移除后不会保留,因此**签名、解密和其他受保护操作**在重新连接后需要再次 **VERIFY PIN**,与其他 OpenPGP 智能卡一样。**私钥材料仍存储在令牌**的密封保险库存储中;拔除不会擦除它,除非运行单独的**清零**或擦除路径。
**可能离开设备的内容:** 按设计,**只有公钥材料**被允许通过 USB 链路传输(例如 OpenPGP **公钥**包以及卡规范向主机暴露的相关数据)。**私钥**、原始秘密标量和密封密钥块**不会**通过正常固件路径离开设备;私钥操作在**令牌上**运行。主机接收**加密结果**(签名、卡辅助解密工作流中的解密明文),这是标准命令所要求的,而非私钥的可移植副本。
**将密钥导入设备:** 也可以将**公钥**导入令牌(例如信任锚、对端证书或用于设备上验证的 OpenPGP 公钥包)。固件 **vault** 为非秘密材料提供**公钥槽**(`crates/vault/src/public_key_vault.rs`)。随着集成成熟,用于加载这些槽位的主机工具在 [docs/GALDRA-TOOL.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GALDRA-TOOL.md) 中描述。
---
## 信任网和密钥签名聚会
OpenPGP 和 **GnuPG** 使用去中心化信任模型——**信任网**——来帮助验证谁拥有哪些密钥,以及是否应依赖给定的**公钥**。该模型完全是**主机端**的。在芯片背书认证(如 [德国 eID 和 Governikus](#german-eid-and-governikus-as-a-trust-anchor-for-public-keys))不可用或不合适的情况下,它是通常的去中心化替代方案(**密钥签名聚会**、证书上的签名);在**可用**的情况下,两种方法可以共存为互补路径。
**Galdralag 指纹(`G:`):** 对于面对面验证工作流,**Galdra** 可以显示从令牌 **SIG** 公钥派生的**设备绑定**指纹(**BLAKE3-160**,`G:` 前缀)。它**不是** OpenPGP v4 证书指纹。它**仅**在活动**密码配置文件**具有 **`ephemeral_ecdh: false`** 时可用;内置配置文件默认 **`ephemeral_ecdh: true`**,因此对于需要此标识符配合 **WoT** 风格主机签名的工作流,您通常需要添加一个带 **`galdra profile add ... --no-ephemeral-ecdh`** 的用户配置文件。通俗定义和格式规范:[Galdralag 指纹](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GLOSSARY.md#g)。生命周期、轮换策略和临时 ECDH 门控:[KEY_LIFECYCLE.md — Galdralag 指纹](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/KEY_LIFECYCLE.md#galdralag-fingerprint-host)。
### 获取您的 Galdralag 指纹
主机打印一个**始终以 `G:` 开头**的字符串(对 SIG 公钥字节进行 BLAKE3-160 哈希,规范形式中前缀后为 **40 个小写十六进制字符**)。
1. 在主机上安装 **[Galdra](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/GALDRA-TOOL.md)**,并确保 **PC/SC** 正常工作(**`pcscd`**、**`libpcsclite`**),以便工具可以通过 CCID 与令牌通信(参见[编译和安装主机工具](#compile-and-install-host-tools-galdra-galdrad-galdra-gtk))。
2. 连接令牌(如果工作流要求,请解锁)。
3. 选择具有 **`ephemeral_ecdh: false`** 的**密码配置文件**。使用 **`galdra profile show <name>`** 确认(`ephemeral_ecdh: off`)。默认配置文件名称 **`standard`** 通常具有 **`ephemeral_ecdh: on`**;如有需要,使用 **`galdra profile add <name> ... --no-ephemeral-ecdh`** 创建一个。
4. 运行:```bash
galdra identity fingerprint
# If you use a non-default profile:
galdra identity fingerprint --profile <name>
机器可读输出:galdra --emit json identity fingerprint(可选 --profile <name>)。
符合 OpenPGP 规范的实现包含一套证书审核方案,用于协助验证密钥所有权;其运作方式被称为信任网。OpenPGP 证书(一个或多个公钥以及所有者/用户 ID 材料)可以被其他用户数字签名,签名者以此认可该公钥与证书上所列个人或实体之间的关联。
gpg --full-generate-key 生成的密钥,或存储在支持 OpenPGP 的令牌上)。密钥签名聚会是一种面对面会议,参与者交换密钥指纹并相互验证身份,之后再对证书进行签名。
典型特征:
由此形成一张社交图谱:如果 Alice 信任 Bob,而 Bob 签署了 Charlie 的密钥,那么 Alice 可以根据信任深度和策略选择是否信任 Charlie 的密钥。
此类活动为何重要:
聚会通常在身份交换期间避免使用计算机,从而减少攻击者在共享机器上混入被替换密钥或恶意软件的机会。
活动之前。 计算并记录你的指纹(由公钥派生出的哈希摘要——长度足够短,便于可靠比对)。除非组织者另有规定,此阶段不要依赖在纸上交换完整密钥。```bash
gpg --fingerprint YOUR_KEY_ID
将指纹记录在纸上或其他耐用介质上(示例格式:`ABCD 1234 EFGH 5678 90AB CDEF 1234 5678 90AB CDEF`)。
**活动期间(仅指纹)。** 交换**指纹**,核验身份,并记录哪些指纹属于哪个已核验的人。确认每位参与者的声称身份与所检查的证件一致。
**活动之后。** 从**密钥服务器**或直接分发渠道获取完整的**公钥**;确认下载的密钥与纸上记录的**指纹**匹配;**签署**你已核验的密钥;可选地**上传**签名,以便他人使用。
### 活动期间使用指纹而非完整密钥
- **操作安全。** 将替换攻击与已核验的指纹绑定,而不是在活动期间信任任意机器。
- **简洁性。** 指纹可写在纸上,便于快速朗读或比对。
- **核验。** 下载后,重新计算指纹可端到端检查完整性。
### 密钥服务器
**密钥服务器**是存储并复制**公开** OpenPGP 密钥(以及签名、撤销等更新)的网络化仓库。它们通过**用户 ID**、**密钥 ID** 或**指纹**使密钥可被发现,并为信任网的广域分发提供支撑。
其原理上的行为方式:
- **分布式复制。** 上传到参与同步网格的某一服务器,通常会传播到对等节点(经典的 **SKS** 风格池即如此运作)。
- **同步。** 新密钥、签名和撤销证书根据各服务器的策略与连接状况进行传播。
- **公开读取访问。** 仅**公开**材料用于发布;**私钥**绝不能上传。
**隐私。** 已发布的密钥会暴露**用户 ID**(通常包含邮箱地址)。请将上传视为**公开且长期存在**于许多服务器上;当密钥需要退役时,请上传**撤销证书**。策略因运营方而异([keys.openpgp.org](https://keys.openpgp.org/) 与传统池有所不同)。
**对等拓扑。** 服务器关系图见 [spider.pgpkeys.eu/graphs/](https://spider.pgpkeys.eu/graphs/);面向 SKS 的对等节点列表见 [spider.pgpkeys.eu/sks-peers](https://spider.pgpkeys.eu/sks-peers)。
### 使用密钥服务器```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
| 服务器 | 说明 |
|---|---|
| keys.openpgp.org | 广泛使用;针对邮件关联用户 ID 提供基于同意的验证 |
| pgp.mit.edu | MIT 托管的服务器,历史上与 SKS 时代的网格相关联 |
| pool.sks-keyservers.net | 旧版池主机名,与曾经的 SKS 生态系统相关;如今连接状况不一 |
gpg --refresh-keys,以便撤销和新的签名在本地传播。galdra profile show <name> 确认活动配置文件具有 ephemeral_ecdh: false。有关 gpg 的权威行为、信任模型和分发选项,请参阅 GnuPG 手册和上游文档。
Fulla 项目(GitHub 上的 Supermagnum/Fulla)托管了 WoT 对齐的注册表服务器工作:用于存储贡献者公钥以及可选的业余无线电标签、邮政提示、organisation(JSON 拼写)、role、note、badge_number、phone_number 及相关列的实现和演进规范,这些列与 Galdra 联系元数据对齐。galdra keyserver push 提交 POST /api/v1/keys JSON(包括 armored_public_key、email,以及当你传递 CLI 标志时的那些可选字段);galdra keyserver fetch 和 [keyserver] 配置节已在 galdra / 中针对该方向实现。;预计未来会有一个公开运营的服务。更多历史设计说明见 。
本项目的不同部分与不同标准对齐。GnuPG 互操作性仅限于 OpenPGP 卡应用和 CCID 所定义的内容。其他功能在固件中实现(有时也在 Galdra 主机工具中实现),但无法通过标准 gpg 卡工作流调用。
对于日常卡行为,请依赖 docs/OPENPGP_CARD.md。对于仅保险库或令牌独有功能,请使用本仓库的固件和 Galdra 工具 文档。
OpenPGP 卡和 GnuPG 栈不定义用于密钥或磁盘解锁的 Shamir 秘密共享(SSS)。SSS 在正常加密之外仍然有用:它几乎从不替代磁盘上的对称密码——它保护解锁该加密的小秘密(主密钥或口令)。
模式(始终是相同的思路):
1. LUKS(Linux)和外部 SSS
LUKS 使用主密钥加密卷。你可以提取该密钥(或密钥槽秘密,具体取决于你的流程),使用 SSS 工具拆分它,并分别存储共享。解锁时,组合 K 份共享,重建密钥材料,并将其提供给 cryptsetup(请参阅你的发行版文档;处理密钥不当可能导致访问被锁死)。
使用 ssss(“Shamir 秘密共享方案”)实用程序的示例形式(名称和打包因操作系统而异):```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) 使用 Shamir 进行**解封(unseal)**:存储加密密钥在初始化时被拆分(例如 5 名操作员中的 3 名各自持有一份份额)。重启后,必须输入 **K** 份份额才能解封。这与 LUKS 的 **主密钥上的 K-of-N** 模式相同,只是应用于机密引擎而非块设备。
**3. Galdralag 固件(`vsss-rs`)**
此仓库使用 [`vsss-rs`](https://crates.io/crates/vsss-rs)(RustCrypto 生态)进行设备端 Shamir 拆分。若将其与批量加密对齐,同样的**分层**模式同样适用:
- 生成一个随机的 256 位(或适当长度)主密钥。
- 使用该密钥以 **AES-GCM** 或 **ChaCha20-Poly1305** 加密驱动器或批量存储(这与工作区中经过审计的对称加密 crate 相匹配)。
- 使用 `vsss-rs` 将主密钥拆分为 **N** 份份额,阈值为 **K**。
- 将份额存储在保险库槽位、其他设备或密钥持有人处。
- 在启动或恢复时,收集 **K** 份份额,重建主密钥,然后如有需要,使用 **HKDF**(或你的策略)派生域分离的子密钥。
**4. VeraCrypt**
VeraCrypt 并未在内部实现 SSS。同样的**外部**模式适用:使用 SSS 工具拆分**口令或密钥文件材料**;不要尝试对卷的密文进行 Shamir 拆分。
### 混合模式(大数据)
SSS 适用于**小机密**(密钥大小)。**不要**对数 GB 的密文应用 Shamir。通常的分层方式:```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)
这与本项目已有的技术栈一致:aes-gcm / chacha20poly1305 用于静态数据,vsss-rs 用于拆分主密钥,hkdf 用于重建后的派生。
| 决策 | 典型选项 |
|---|---|
| 阈值 | 2-of-3(小团队,有一定冗余);3-of-5(组织中常见) |
| 份额存储 | 硬件令牌、独立机器、纸质、地理分散站点 |
| 份额保护 | 在分发前为每个特定接收者加密每个份额(例如使用其 OpenPGP 密钥) |
LUKS 和全盘加密的操作性密钥处理具有安全敏感性;请遵循您环境中供应商和发行版的指南及威胁模型。
双硬件密钥 / 法定人数授权(要求两个独立的物理令牌或份额持有人才能执行关键操作)是一种受支持的扩展模式,而非固件功能。Galdralag 提供 Shamir K-of-N 原语(vault::shamir、galdra shamir)和单令牌 OpenPGP 认证;下游的 LUKS 封装器、访问面板或自定义守护进程必须强制执行法定人数、会话窗口和安全重建。该边界、参考 2-of-N 工作流以及集成者的安全说明见 docs/DUAL_KEY_QUORUM.md。这目前即可用现有原语实现;编排工作有意留给使用者——并非本仓库的路线图承诺。
一个具体模式是使用 Brainpool 曲线加密驱动器或卷(在您的技术栈需要时,例如围绕主密钥的 ECDH/ECDSA),并结合对解锁该加密的密钥材料进行 Shamir 秘密共享(与上述 小秘密分层 相同:SSS 保护密钥,而非数 GB 的密文)。当且仅当实现该工作流的固件和主机软件经过独立审计后,这种组合对必须同时满足法定人数政策和国家密码配置的组织才有价值。
为何 Brainpool 曲线(例如 BrainpoolP256r1、BrainpoolP384r1)常在此语境中被讨论:
将 SSS 与 Brainpool 类密码学结合以应对机构需求的场景(说明性;非法律或合规建议):
如果 Governikus 式 OpenPGP 签名或类似的芯片支持的国家 eID 认证在您的司法管辖区或工作流中不可用或不切实际,信任网和密钥签名聚会 描述了一种基于面对面验证和证书上第三方签名的替代主机端方法。
Governikus OpenPGP 密钥认证 是代表 BSI(德国联邦信息安全办公室)运营的在线服务。提交者使用支持 德国 eID 的身份证、面向欧盟公民的欧盟 eID 卡或电子居留许可完成认证后,该服务会检查认证的法定姓名是否与上传公钥上的 OpenPGP 用户 ID 匹配。若匹配,Governikus 使用服务签名密钥签署该公钥,以便第三方验证该认证。
使用此固件的实用工作流:在令牌上生成 Brainpool 非对称密钥(照常进行 OpenPGP 卡生成),将公钥或证书导出到主机,完成 Governikus 提交流程(包括 eID 认证,通常通过 AusweisApp 和 NFC 读卡),并使用服务返回的已签名公钥(例如通过电子邮件分发)。私钥全程保留在 Galdralag 上。
两条路径互不替代。eID 和 Governikus 步骤在提交时将公钥绑定到针对芯片验证的身份;它们不提供前向保密、针对长期密钥材料的 Shamir K-of-N 或批量数据的密码配置文件——这些是 固件特定功能,在本 README 其他部分有描述。eID 芯片及周边签发流程本身也不实现令牌的临时 ECDH 和级联行为。相反,在设备上生成的 Brainpool OpenPGP 密钥与已讨论的 Brainpool 机构用途 中的 BSI/欧盟部署背景一致,但若无外部认证步骤,通信方必须依赖其他手段将指纹与法人关联。
| 层 | 角色 |
|---|---|
| OpenPGP 公钥(例如 Galdralag 上的 Brainpool) | 密码结构和令牌上私钥控制;曲线选择遵循 BSI TR-03111 类预期(见 非对称 / 密钥协商 中的 Brainpool 能力行 以及 中的 TR-03111 讨论) |
限制: 验证基于姓名。如果服务比较的字段中两人共享相同法定姓名,认证无法区分他们;它确认的是认证时与该姓名的身份关联,而非全局唯一性。常规 OpenPGP 关注点(电子邮件绑定、密钥轮换、撤销)仍然有效。
政策对齐:定义 Brainpool 相关技术指南的同一 BSI(BSI TR-03111;符合性向量位于 crates/vault/tests/bsi_vectors/)也支持 Governikus eID 签名流程,这在 德国和欧盟 环境中(Brainpool 已被要求或优先)通常很重要——见 Shamir 加 Brainpool:示例与机构适配。
更广范围(研究说明,非完整调查): 将 OpenPGP 公钥绑定到芯片验证身份这一模式原则上适用于任何存在国家 eID 的司法管辖区;哪些提供商提供类似 Governikus 的签名步骤、在何种规则下,是随着部署扩展值得调查的独立问题。其他 欧盟 成员国在 eIDAS 下运行基于卡的 eID 生态系统,可能支持比德国路径更强或相当的信�任锚;本 README 未对其进行编目。
爱沙尼亚和比利时在芯片上均采用 NIST P-384 而非 Brainpool,而德国公共部门 BSI 配置以 Brainpool 为中心(见上文)。Galdralag 已在 OpenPGP 卡上支持 Brainpool 和 NIST P-256/P-384(docs/OPENPGP_CARD.md);本仓库中的 RSA 是 galdr-vault 库辅助函数,而非可用的卡槽(非对称 / 密钥协商)。同一信任锚模式并不依赖于匹配德国的曲线偏好。
在 欧盟/欧洲经济区之外,基于卡的信任锚模式更难应用:美国有芯片卡(PIV),但仅限于联邦人员且位于 X.509/FPKI 中,未与 OpenPGP 集成;加拿大没有上述意义上的国家芯片签名卡。这将该模式主要限制在普遍签发政府芯片凭证的司法管辖区——欧盟 eIDAS 区域是目前该模式最强的地区。
当且仅当硬件达到消费者就绪状态时,希望 Shamir 秘密共享和认证临时密钥交换成为可互操作 OpenPGP / GnuPG 行为(而非仅固件特定功能)的人,需要在其他地方推动标准和实现的变更。本仓库不代表 IETF 或 GnuPG 发言;以下场所是此类修订通常推进的地方。
CESS — Cryptologically Enchanted Shamir's Secret — 是一个开放密码标准,涵盖阈值秘密共享以及密码无关的认证加密、基于密码的份额封装和可选的后量子混合密钥交换。CESS 仓库 保存规范性规范、算法注册表、测试向量和符合性运行器。
此固件对这里实现的构造符合 CESS:规范的互操作份额和封装规则与本 README 其他部分描述的 Shamir、Brainpool 和密码配置文件主题并列。规范性文本独立于本仓库;符合性姿态(哪些与规范匹配、哪些在配置文件中保留 AES 和 SHA-256 等算法的同时存在差异,以及迈向更强互操作性的路线图):docs/CESS_CONFORMANCE.md。
如果此 GitHub 仓库的维护者不回应 issue、拉取请求或邮件,您仍可在更广泛的生态系统中推进新密码、OpenPGP 行为和标准相关工作。Sequoia PGP 是一个独立的、基于 Rust 的 OpenPGP 技术栈(内存安全、库优先设计、积极参与 IETF/生态系统),大量公开开发在此进行。它不是本项目;此处记录它是作为上游沉默时的实用替代路径。
Contribute 页面描述了许可(大多数项目为 LGPL 2.0 或更高版本)、开发者来源证书,以及较大的商业功能可能需要事先协议和长期维护安排——在投入大量精力前请阅读该页面。
也值得关注 https://autocrypt2.org/#/
此代码库和相关应用不会为 macOS 或 Windows 编译。 主机工具(galdra、galdrad、galdra-gtk)和支持工具面向 Linux。这是基于项目威胁模型和本文档中所述可审计性要求的有意决定。
_NSAKEY 变量引发了重大争议。微软称其为备份密钥;这一点从未被完全证实或证伪。疑似但未证实:
main、restricted、universe 和 multiverse 仓库中的所有软件包均由 Canonical 的 GPG 密钥签名。security.ubuntu.com,同样经过签名。软件包管理器通常安全,但第三方 .deb / .rpm / AppImage 安装可能不安全。优先选择来自可信仓库的签名软件包,并在安装任何从外部获取的内容前验证签名。
使用 rust-toolchain.toml 中固定的稳定 Rust 工具链。固件使用 riscv32imac-unknown-none-elf 目标;主机工具使用主机三元组。
test-hal 会泄漏到生产构建中,则失败): ```bash
cargo run -p xtask -- check-fw
目标代码和归档文件位于 target/riscv32imac-unknown-none-elf/release/ 下。针对特定板卡的完整可引导 Xous 系统镜像由更广泛的 Baochip / Xous 集成流程在遵循该产品构建时生成;此处的 xtask 仅为 xtask 中列出的固件库 crate 运行 cargo build(其本身并非一个可直接烧录的文件)。
Xous CCID 守护进程(galdralag-service) — 需要 riscv32imac-unknown-xous-elf Xous 工具链(而非上述裸机 riscv32imac-unknown-none-elf 固件三元组)。
所需的 xous-core 树: 路径依赖通过 Galdralag-firmware/xous-core/ 解析。镜像构建应使用 feature/usb-bao1x-ccid-openpgp 分支(PR #937)上的同级(或 XOUS_CORE=)检出。嵌套树与同级树可能产生分歧;cargo run -p xtask -- check-xous-core 会以非零状态失败,并打印一条可直接复制粘贴的 ln -sfn <sibling> ./xous-core 命令(如果 ./xous-core 还不是符号链接,请先重命名真实的嵌套检出): ```bash
ln -sfn ../xous-core ./xous-core
cargo run -p xtask -- check-xous-core
包含 Galdralag 的 Dabao CCID 镜像(单独的 dabao-ccid 仅支持传输): ```bash
scripts/build_dabao_ccid_image.sh
**BaoSec + PDDB:** **`cargo run -p xtask -- build-and-register release --xous-core /path/to/xous-core`**。详情:[services/galdralag/README.md](https://github.com/supermagnum/galdralag-firmware/blob/main/services/galdralag/README.md)。仅上游存在的缺口:[docs/XOUS_CORE_UPSTREAM_REQUESTS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/XOUS_CORE_UPSTREAM_REQUESTS.md)。
### 烧录
本仓库目前**尚未**提供一键烧录工具。对 **Baochip-1x** 进行编程(JTAG、ROM/USB 启动或厂商工具)需遵循板卡和芯片文档。从 **[Supermagnum/Baochip-1x-firmware](https://github.com/Supermagnum/Baochip-1x-firmware)** 开始;**评估板硬件**位于 **[baochip/dabao](https://github.com/baochip/dabao)** —— 在 Dabao 板上,**SW2** 用于切换**引导加载程序模式**(参见该原理图)。
**无需物理启动按钮即可提交 UF2:** 将 **`loader.uf2`**、**`xous.uf2`** 和 **`apps.uf2`** 复制到 **BAOCHIP** 卷后,您可以按下物理 **boot** 按钮,**或**在 **boot1** USB 串行控制台(1 000 000 波特率,例如 `screen /dev/ttyACM0 1000000`)中输入 **`boot`**。这样仅在此步骤中无需依赖 **boot** 按钮。当您输入 **`boot`** 时,控制台会**断开连接**;这是**预期行为**(系统会重启进入下一阶段)。在 Linux 上,`dmesg --follow` 有助于确认 USB 重新枚举。这与 **PROG**(连接 USB 时按住以进入 **BAOCHIP** 大容量存储引导加载程序)不同。参见 **[baochip/dabao#2](https://github.com/baochip/dabao/issues/2)**(已关闭)。
**Xous / Baochip 流程:** 镜像经过 **Ed25519 签名**,并在执行前由 **boot0** 验证;参见 [签名固件(Ed25519,boot0)](#signed-firmware-ed25519-boot0)。对于 **dabao**,**UF2** 布局、插入 USB 时按住 **PROG** 进入大容量存储模式,以及 **boot1** 更新步骤,请参见 **[Baochip 目标入门](https://github.com/betrusted-io/xous-core/blob/dev/README-baochip.md)**。
### 编译并安装主机工具(`galdra`、`galdrad`、`galdra-gtk`)
主机 crate 位于工作区根目录:`galdra/`、`galdrad/`、`galdra-gtk/`。
**Ubuntu / Debian**(在 `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 满足 默认 galdra PC/SC 链接路径;pcscd 是运行时为智能卡读卡器提供服务的守护进程。libssl-dev 是必需的,以便 openssl-sys 能够链接(sequoia-net 密钥服务器查找和 ldap3 TLS 目前使用 native-tls)。如果你从不构建 galdra-gtk,请省略 libgtk-4-dev。
GTK 4(仅限 galdra-gtk): pkg-config 必须解析 gtk4(工作区 crate gtk 0.9.x,包 gtk4)。在 Fedora 上使用 gtk4-devel;在 Arch 上使用 gtk4。
从仓库根目录构建发布二进制文件:```bash cargo build --release -p galdra -p galdrad -p galdra-gtk
可执行文件:`target/release/galdra`、`target/release/galdrad`、`target/release/galdra-gtk`。
**安装**到 `~/.cargo/bin`(如果你不在仓库根目录,请调整 `--path`):```bash
cargo install --locked --path galdra
cargo install --locked --path galdrad
cargo install --locked --path galdra-gtk
你可以将这三个二进制文件复制到 PATH 中的任意目录。
galdrad 和桌面 GUI(galdra-gtk)galdra-gtk 是 GTK4 桌面二进制文件(Cargo 包 galdra-gtk;不存在 galdra-gui)。它是 galdrad REST API 的前端——请先运行 galdrad。
守护进程 — galdrad 默认监听 127.0.0.1:8742(可通过 --listen 覆盖);参见 galdrad/src/main.rs。```bash
galdrad
快速检查:`curl -s http://127.0.0.1:8742/health`(交互式 API 文档:**`http://127.0.0.1:8742/swagger-ui/`**。)
**桌面 GUI** — **`galdra-gtk`** 默认使用 **`http://127.0.0.1:8742`**(可通过 `--base-url` 或 **`GALDRAD_URL`** 配置);参见 [`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
从一次全新的 cargo build --release 开始,无需安装:在仓库根目录下运行 ./target/release/galdrad,然后运行 ./target/release/galdra-gtk。
主机与令牌: galdra-gtk 镜像 galdrad 通过 HTTP 暴露的任何内容;令牌 unlock、provision 以及其他 CCID 流程保留在 galdra CLI 上(参见 docs/GALDRA-TOOL.md 中的 galdra device 以及第 2c 层)。
联系人目录(galdra contact、galdrad /contacts): 创建联系人需要电子邮件(CLI:--email;HTTP:JSON 字段 email)。可选字段包括显示名称(--name / name)、组织(--org / org)、角色、徽章(--badge / badge)、备注、呼号、Fluxer、Discord 和 IRC ID、电话号码(--phone-number / phone_number),以及邮政提示(、、、)、业余无线电 和 。这些值仅存储在本地 SQLite 元数据中(针对外部服务进行)。联系人(例如 、/ 路径、 、组成员 ID 或 )接受行 、、、完整的 (忽略空格)、这些社交 ID,或当以十进制令牌给出时在 范围内的 。 可以将许多相同的标签镜像到 Fulla 风格的注册表(、、、、、无线电/社交/邮政字段以及名称——参见 )。命令和字段限制在 的 和 部分进行了总结。
如果您如上所述使用了 cargo install --path:```bash
cargo uninstall galdra
cargo uninstall galdrad
cargo uninstall galdra-gtk
如果你手动复制了二进制文件,请移除你添加的文件。固件并非“安装”在主机上;擦除或重新刷写设备属于你的硬件文档范畴。
---
## 关键能力
### 这个令牌的独特之处
以下条目是 **Galdralag 固件能力**,而非 [OpenPGP 卡应用](#标准与固件特定功能) 或 GnuPG 的要求。
- **支持三因素的安全模型** — 目前固件中强制实施对 USB 令牌的**持有**和 PIN 的**知晓**;可选的**生物识别**第三因素**未**在本仓库中实现(占位符:[docs/BIOMETRIC_API.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/BIOMETRIC_API.md))。范围与限制参见 [docs/THREE_FACTOR_AUTH.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREE_FACTOR_AUTH.md)。
- **设备上经过认证的临时 ECDH** — 真正的密码学前向保密。
每个会话都会在令牌的硬件 TRNG 上生成一个新的临时密钥对。长期密钥对临时要约进行签名,但绝不参与密钥协商。即使长期密钥被完全攻破,过去的会话也无法被解密。据项目作者所知,没有商业硬件安全令牌将此作为一等功能提供。
- **设备上的 Shamir K-of-N 秘密共享** — 长期密钥可以被分割成 N 份共享,需要 K 份才能重建,任何单一持有者都无法独自恢复密钥。据项目作者所知,也没有商业令牌将此作为一等功能提供。**双人控制**(开门或挂载卷之前需要两个令牌)**未**在此处强制实施;参见 [双硬件密钥法定人数(集成商模式)](#双硬件密钥法定人数集成商模式)。
- **与密码无关的配置文件系统** — 对称密码、ECDHE 曲线和 Shamir 配置被组合成命名的、可审计的配置文件。对于配置文件下的大批量数据,明文**由内向外**加密:你可以在彼此之上堆叠**最多四个****不同**的对称 AEAD——因此你可以在一个配置文件中使用**三个**独立的密码(例如 ChaCha20-Poly1305,然后是 Serpent-256,再是 Twofish-256),或者在策略允许的情况下使用第四个不同的层——同一配置文件中**不重复使用密码**,每层使用**独立**的 HKDF 派生密钥和随机数材料。内置名称如 `standard`、`conservative` 和 `conservative-shamir` 附带**一层或两层**;更深的堆栈用于高级或自定义配置文件。
完整规则和线缆布局:[docs/CIPHER_PROFILES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILES.md)。
每次配置文件选择都会记录在审计跟踪中。
- **级联层之间的带密钥 BLAKE3(CESS)** — 除了每层自身的 AEAD 标签和 **Mode A** 外部 ChaCha20-Poly1305 信封之外,**CESS** 在内部级联阶段**之间**定义了**带密钥 BLAKE3** 风格的完整性。对于**注册表映射**的配置文件(通过内置名称的 `suite_id`),**`cipher-profile`** 会在下一层加密之前,对每个内层的 AEAD 输出追加一个 **32 字节的 HMAC-BLAKE3**;密钥使用 **HKDF-BLAKE3** 派生,采用 `cess::cess_blake3_integrity_gap_info`([`inner_info.rs`](https://github.com/supermagnum/galdralag-firmware/blob/main/crates/cess/src/inner_info.rs))。**单层**内置配置文件跳过额外标签;**自定义**配置文件(无 `suite_id`)保留无层间 MAC 的旧式级联。参见
[docs/CIPHER_PROFILES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILES.md) 和
[docs/CESS_CONFORMANCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CESS_CONFORMANCE.md)。**组合计数**
在 `cipher-profile` 密码规则下(**五种** AEAD 原语,同一配置文件中**不重复密码**,顺序重要);BLAKE3 列是 CESS **设计空间**计数(每个间隙独立开/关),而非每条消息的主机开关:
| 级联长度 | 有序的不同密码堆栈 | × 在每层之间的 **长度−1** 个间隙处可选 BLAKE3 开/关 |
|:--------------:|--------------------------------:|---------------------------------------------------------------------------:|
| 1 层 | 5 | 5 × 2^0 = **5** |
| 2 层 | 20 | 20 × 2^1 = **40** |
| 3 层 | 60 | 60 × 2^2 = **240** |
| 4 层 | 120 | 120 × 2^3 = **960** |
| **总计** | **205** | **1245** |
**205** 这个数字只统计**密码堆栈**(从 AES-256-GCM、ChaCha20-Poly1305、Twofish-256、Serpent-256、Camellia-256 中选取 1–4 个不同选项的排列)。**1245** 这个数字是相同的堆栈乘以每个**独立**的可选层间 BLAKE3 开/关模式(**k** 层有 **2^(k−1)** 种模式)。**本固件**在内置 **`suite_id`** 配置文件具有 **≥ 2** 层时,对**所有**间隙应用层间 MAC(不是逐间隙开关)。内置配置文件名称只使用 205 中的**一小部分**。
- **可选的 microSD 诱饵卷** — 如果安装了 PSRAM 芯片,解锁后可以出现一个额外的批量诱饵 LUN。**如果未安装 microSD,该设备仍然是一个硬件安全令牌**(保险库、PIN 策略、OpenPGP/CCID 和其他令牌功能不变);只是缺少那个可选的批量卷。对于不知情的主机,设备在配置了相应设置时仍会呈现通常的片上大容量存储诱饵角色。microSD 内容(如果存在)有意保持未加密且平淡无奇。真正的密钥材料位于片上 RRAM 中,受保险库和 PIN 策略保护。
- **完全开放的技术栈** — CERN-OHL-W-2.0 RTL、开放原理图、可复现的引导加载程序、Rust/Xous 操作系统、IRIS 可检查的硅片。
### 双硬件密钥法定人数(集成商模式)
**它是什么:** 一种让组织在**下游系统**解锁关键内容——加密磁盘、**防火墙或服务器管理**会话、**药品保险库**、安全门或其他特权操作——之前要求**两个(或 K-of-N)独立的物理令牌或共享持有者**的方式。
**Galdralag 提供什么:** 每个令牌都是**一个独立的凭据**:OpenPGP 卡认证(令牌 + PIN),以及通过主机工具进行的长期密钥材料的 **Shamir 共享导出**([`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))。稳定的**公共身份**(OpenPGP 指纹、令牌序列号)支持**哪个密钥在何时被使用**的审计记录。
**Galdralag 不提供什么:** 固件和主机工具**不会阻止**签名、解密或解锁,直到两个令牌同时在场。**法定人数强制实施**、会话时间窗口、安全的重建环境以及防篡改的**访问日志**是**集成商**的职责——LUKS 解锁守护进程、特权访问管理(PAM)、门/面板软件或自定义策略网关。
**典型模式:** 将主解锁秘密分割为 **2-of-3**(或类似方式);保管人 A 在令牌 A 上持有共享 1,保管人 B 在令牌 B 上持有共享 2;在解锁时,网关收集 **K** 份共享或 **K** 个令牌签名,**一次性**重建或授权,然后清零该秘密。替代方案:在时间窗口内对挑战执行两次 OpenPGP **SIGN** 操作,无需 Shamir 重建。
这是一个使用现有原语的**受支持的扩展模式**——**不是**已发布的产品功能,也**不是**路线图承诺。设计、责任边界、安全说明和问责日志:[docs/DUAL_KEY_QUORUM.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/DUAL_KEY_QUORUM.md)。
另请参见 [Shamir 秘密共享与驱动器加密](#shamir-秘密共享与驱动器加密) 和 [docs/AUDIT_LOG.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/AUDIT_LOG.md)。
### 密码学能力
所有原语都来自经过独立审计的工作区依赖项。
树内未实现任何内容。
#### 非对称 / 密钥协商
| 算法 | 标准 | 备注 |
|-----------|----------|-------|
| BrainpoolP256r1 ECDH + ECDSA | RFC 5639, BSI TR-03111 | BSI 标准化,无 NSA 参与 |
| BrainpoolP384r1 ECDH + ECDSA | RFC 5639, BSI TR-03111 | 约 192 位安全性 |
| X25519 ECDH | RFC 7748 | |
| Ed25519 签名 / 验证 | RFC 8032 | |
| RSA-2048 / 3072 / 4096 OAEP、PSS、PKCS#1 v1.5 签名/验证 | RFC 8017 | 仅 `galdr-vault` 库(最低 2048 位)。OAEP-SHA256 加密/解密;PSS SHA-256/SHA-512 签名/验证;PKCS#1 v1.5 签名/验证位于源内 `Pkcs1v15` 标记之后(仅用于遗留互操作性,不用于新协议设计)。**无法**通过 OpenPGP 卡应用访问——SIG/DEC/AUT 不操作 RSA;参见 [docs/OPENPGP_CARD.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/OPENPGP_CARD.md)。 |
| P-256、P-384 | NIST | 通过 `p256` / `p384` 工作区依赖项 |
#### 对称 / AEAD
| 算法 | 标准 | 备注 |
|-----------|----------|-------|
| AES-256-GCM | FIPS 197, NIST SP 800-38D | Baochip-1x 上的硬件 AES |
| ChaCha20-Poly1305 | RFC 8439 | 无 NSA 参与 |
| Twofish-256 | Schneier 等人 1998 | AES 决赛入围者,无 NSA 参与 |
| Serpent-256 | Anderson / Biham / Knudsen 1998 | AES 决赛入围者,32 轮,保守余量 |
#### 密钥派生 / MAC / 摘要
| 算法 | 标准 |
|-----------|----------|
| 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 |
| SHA-3 系列 | FIPS 202 |
| BLAKE2b / BLAKE2s | RFC 7693 |
| BLAKE3 | BLAKE3 规范 |
#### 密钥管理
| 功能 | 备注 |
|---------|-------|
| Shamir K-of-N 秘密共享 | `vsss-rs` — 设备上分割与恢复 |
| 认证的临时 ECDH | 前向保密会话协议 — `ephemeral-session` crate |
| 配置文件系统 | 对称**级联**:**最多四个**不同的 AEAD 堆叠(例如**三个**独立层);每层密钥 — `cipher-profile` — [docs/CIPHER_PROFILES.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CIPHER_PROFILES.md) |
### 安全属性
| 属性 | 实现 |
|----------|---------------|
| 前向保密 | 临时 ECDH:长期密钥仅签名,绝不协商 |
| 比较前 PIN 计数器 | 计数器在 `subtle::ConstantTimeEq` 之前刷新到 RRAM — 无例外 |
| 硬件零化 | TRNG 来源的多遍覆写;boot0 在 USB 枚举之前零化 |
| USB 总线上无秘密 | 不知情的主机只看到标准大容量存储;无法留下指纹 |
| 单调防篡改证据 | 常开域中的硬件单向计数器 |
| 三因素认证 | **持有:** USB 令牌;**知晓:** 设备上 PIN(`pin-policy`);可选**生物识别**未实现 — [docs/THREE_FACTOR_AUTH.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/THREE_FACTOR_AUTH.md) |
| RRAM 计数器和审计跟踪 | PIN 的单调 HAL(以及未来的有状态 PQ 签名);配置文件审计记录和内存中 OpenPGP 审计钩子 — 仅追加的 NV 审计日志**未**实现 — [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) |
| 恒定时间操作 | 所有秘密比较均通过 `subtle`;由 dudect 测试平台验证 |
| test-hal 绝不进入生产环境 | 由 `check-fw`(固件)和 `check-host`(发布主机二进制文件)强制实施 |
### PIN 策略
- 最小长度:**5 个字母数字字符** — 在解析器边界强制实施,在调用 `pin-policy` 之前。短输入不会递增计数器。
- 默认尝试阈值:**3**(配置时可在 **3–10** 之间设置)。
符合硬件令牌行业标准(Nitrokey、YubiKey、ISO 7816)。
- 达到阈值时:触发完整硬件零化。
- 挑战/响应口令(USB 知情主机路径):最少 5 个字符,
仅以 `HMAC-SHA256(HostChallengeKey, nonce || passphrase)` 形式传输。
**设置或调整尝试阈值:** 计数器限制在令牌**首次配置**时写入;它**不是**运行时 `gpg` 设置。请在[构建](#编译并安装主机工具-galdra-galdrad-galdra-gtk)后使用 **`galdra`** 主机工具:```bash
galdra device provision --pin-attempts 5
| 标志 | 范围 | 默认值 | 含义 |
|---|---|---|---|
--pin-attempts | 3–10 | 3 | 锁定/归零前允许的 PIN 输入失败次数 |
省略两个标志以保留默认值(3 次尝试,5 个字符最小长度)。同时使用两者的示例:galdra device provision --pin-attempts 7 --min-pin-length 8。
该策略存储在令牌上(保险库策略)。主机工具无法在配置之后提高或降低阈值,除非通过设备自身的认证管理流程;请将配置视为根据您的威胁模型选择 3–10 的时机。理由(默认值 vs 更高限制)在 docs/GALDRA-TOOL.md 的 PIN 策略部分有详细说明。
XMSS(RFC 8391,NIST SP 800-208)和 LMS/HSS(RFC 8554,NIST SP 800-208)
已在 --features pq-signatures 之后实现。底层 Rust crate
尚未经过独立审计。请参阅
docs/PQ_SIGNATURES.md 和
docs/STATEFUL_SIG_STATE.md。
这些算法已获 NIST 标准化。实现受阻于
可用的经独立审计的 no_std Rust crate。
关于 libcrux 的说明: 一篇 2026 年的学术论文指出了 libcrux 形式化验证的 ML-KEM 和 ML-DSA 实现中的规范级缺陷,包括使证明失效的问题。在评估它之前,请检查 libcrux 的变更日志。
BIKE 于 2025 年 3 月被 NIST 标准化淘汰,转而采用 HQC。NTRU 加密于 2022 年 7 月被淘汰。两者均无通往 NIST 标准的路径。
归零实现是软件正确但硬件未验证的。它仅通过 test-hal 模拟进行了测试。在 Baochip-1x 硅片上的物理验证(JTAG 内存检查、断电恢复能力、侧信道确认)尚未执行。请参阅
docs/HARDWARE_VERIFICATION.md。保险库子系统的预期区域顺序和布局锚点总结在
docs/RRAM_LAYOUT.md 中;物理擦除顺序仍是平台和 boot0 集成工作。
权威说明:docs/TEST_RESULTS.md#run-metadata(提交、范围以及各部分的组织方式)。该页面包括流水线摘要表、单元测试总数、向量覆盖率(Wycheproof、RFC、BSI TR-03111 ECDH + ECDSA、NIST CAVP、BLAKE3 哈希/密钥哈希/派生密钥)、dudect 时序表、密钥生命周期检查,以及 第 6 节 — cargo-fuzz(矩阵、chacha_roundtrip、记录的 openpgp_dispatch 长运行)。您自行决定这些结果是否足以尝试构建或运行此项目;虚拟机仍然可选,但降低了主机风险。```
cargo run -p xtask -- test-all
## 工作区布局
面向固件的 crate 位于 `crates/` 下,主机二进制文件位于仓库根目录(权威成员列表请参见根目录 **`Cargo.toml`** 中的 `[workspace]`):
| Crate | 作用 |
|-------|------|
| `galdr-core` | HAL trait(`MonotonicCounter`、`HardwareTrng`、`ZeroiseController`、`VaultStorage`)、共享错误、`test-hal` 模拟实现 |
| `vault` | RRAM 保险库契约、HKDF `KeyPurpose` 标签、密钥材料类型(`zeroize`,无 `Clone`/`Copy`) |
| `pin-policy` | PIN 状态机;在 `subtle::ConstantTimeEq` 之前递增计数器;阈值零化 |
| `usb-personality` | 大容量存储与认证解锁角色(包括诱饵大容量存储角色);挑战/响应;OpenPGP/CCID 卡应用;锁定时断开 USB |
| `ephemeral-session` | 认证的临时 ECDH 会话协议;前向保密 |
| `cipher-profile` | 用户可配置的密码级联配置文件;内置和用户自定义 |
| `cess` | HKDF-BLAKE3 `K_outer`、ChaCha 外部 AEAD、`suite_id \|\| inner_blob`;参见 [CESS_CONFORMANCE.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/CESS_CONFORMANCE.md) |
| `biometric-api` | 生物识别前置门线缆类型(CBOR、`SignedMatchResult`)、会话令牌辅助函数 |
| `biometric-vault` | 模板封装和保险库侧集成组件 |
| `biometric-fingervein` / `biometric-sweet` | 可插拔生物识别后端草图 |
| `security-tests` | 针对加密路径的 dudect 时序测试框架 |
| `host-tools` | 主机清单哈希、更新验证、`psram-unlock`、**`galdralag-provision`**(Xous 两线 CDC PIN 配置) |
| `xtask` | 构建、检查、测试、模糊测试、**`build-and-register`**(Xous `galdralag-service`)、时序测试 |
| `galdra-core-host` | SQLite 模式、联系人/群组/审计/同步、HKP/WKD/LDAP 获取、设备和 OpenPGP 主机辅助函数 |
| `galdra` | 基于 `galdra-core-host` 的 CLI |
| `galdrad` | 本地 REST 守护进程 |
| `galdra-gtk` | GTK4 桌面 UI |
**不在本工作区表中作为独立 crate 列出:** `baochip-openpgp` 和 `services/galdralag` 通过 **`--manifest-path`** 构建(参见根目录 `Cargo.toml` 中的 `exclude` 和 [services/galdralag/README.md](https://github.com/supermagnum/galdralag-firmware/blob/main/services/galdralag/README.md))。可选的 **批量/诱饵块存储**(设计文档中的 `psram-store`)**尚不**是工作区成员;参见 [docs/Psram.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/Psram.md)、[docs/dev-ref.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/dev-ref.md) 和 [docs/SDMMC_STORAGE_INTEGRATION.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/SDMMC_STORAGE_INTEGRATION.md)。
---
## 加密依赖策略
原语**不在树内实现**。所有加密工作均使用来自 RustCrypto 项目的经过审计的工作区依赖(`vsss-rs` 和 dalek 系列除外,它们已接受独立审查):```
aes-gcm chacha20poly1305 ed25519-dalek x25519-dalek
hkdf pbkdf2 hmac sha2 sha3 blake2 blake3
vsss-rs zeroize subtle p256 p384
使用经过审计的 crate 意味着本项目继承了它们的审计历史,而不是引入未经审查的加密代码。
固件构建先决条件和安装路径见上文 构建、安装和卸载。
主机桌面 GUI(galdra-gtk): 在 构建/安装 galdrad 和 galdra-gtk 之后,先启动 galdrad,再启动 galdra-gtk(分步指南)。```bash
rustup target add riscv32imac-unknown-none-elf
cargo test --workspace --exclude xtask
cargo run -p xtask -- check-fw
cargo run -p xtask -- build-fw
cargo run -p xtask -- test-host
cargo run -p xtask -- test-all
cargo run -p xtask -- test-biometric
cargo run -p xtask -- timing-test biometric
cargo run -p xtask -- fuzz biometric_dispatch 60
cargo run -p xtask -- timing-test
**模糊测试(libFuzzer):** 安装 `cargo-fuzz`,使用 nightly 工具链,然后例如 `cargo run -p xtask -- fuzz chacha_roundtrip 60` 或 `cargo run -p xtask -- fuzz openpgp_dispatch 60`(OpenPGP APDU 路径)或 `cargo run -p xtask -- fuzz biometric_dispatch 60`(生物识别 CBOR 路径)。目标名称、xtask 别名以及每个目标的**推荐语料库种子**见 [fuzz/README.md](https://github.com/supermagnum/galdralag-firmware/blob/main/fuzz/README.md)。
仅在测试或主机工具中启用 `galdr-core` 特性 `test-hal`。
切勿在生产固件镜像中启用它——由 `check-fw` 强制执行。
---
## 已知限制 / 待办工作
### CCID 初始 PIN:Dabao CCID 与旧版 CDC
**Persona A / `dabao-ccid`(当前 CCID 分支,[PR #937](https://github.com/betrusted-io/xous-core/pull/937)):** Dabao 上**没有 USB CDC-ACM 配置串口**,也**没有 PDDB**。不带 Galdralag cratespec 的普通 **`cargo xtask dabao-ccid`** 仅为**传输层**(内联 ATR / GetSlotStatus);在 **`galdralag-service`** 注册之前,它**永远不会**到达 `gpg --card-status` APDU——请使用 **`scripts/build_dabao_ccid_image.sh`**。
**当前实验室可用的 PIN 设置途径:**
1. **Dabao 默认值**(PDDB 等待超时后):用户 **`12345`**,管理员 **`12345678`**(请立即通过 `gpg --card-edit` → `passwd` 更改)。
2. **`baosec-ccid` + `ccid-pddb`** 工厂 / 离线 PDDB 种子(`usb.ccid` / `OKV1`),当镜像包含 PDDB 时可用。
3. **开发快捷方式:** 特性 **`dev-provisioning`**,配合进程环境中的 **`CCID_USER_PIN`** / **`CCID_ADMIN_PIN`**(仅限实验室;见 `baochip-openpgp`)。可选的 **`trng-pin-fallback`** 在 **`board-dabao`** 下被 **`compile_error!`** 禁止。
**旧版 / 非 Dabao-CCID(baosec + CDC 时代):** 一些较旧或 baosec 类流程暴露 CDC,并期望 **`galdralag-provision`** 将两行 PIN 写入 PDDB `usb.ccid`(`OKV1`、`user_pin_line`、`admin_pin_line`)。该路径**不是**标准 **`dabao-ccid`** 的主要方案。线格式细节仍保留在 `crates/host-tools/src/provision.rs` 中,供仍使用该类镜像的操作人员参考。
**保险库创建后**,更改 PIN 使用 **GnuPG** / 通过 CCID 的 **OpenPGP CHANGE REFERENCE DATA**(`gpg --card-edit` → `passwd`),而非 CDC。
PIN 上限:32 字节(固件限制;OpenPGP 规范允许 127)。参见
`crates/baochip-openpgp/src/xous_impl.rs` 中的
`CCID_PIN_PROVISION_PAYLOAD_MAX_BYTES`。
**集成:** **`usb-bao1x`** 位于 **xous-core** 中(不从此仓库修补)。启动: [docs/HARDWARE_BRINGUP_TEST_PLAN.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/HARDWARE_BRINGUP_TEST_PLAN.md)。上游请求: [docs/XOUS_CORE_UPSTREAM_REQUESTS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/XOUS_CORE_UPSTREAM_REQUESTS.md)。历史记录: [xous-core#875](https://github.com/betrusted-io/xous-core/issues/875)。
### 主机 `device status`:PC/SC 扫描任何 OpenPGP 卡(厂商过滤待定)
`galdra device status` / `galdrad` `GET /device/status` 始终尝试只读 PC/SC 扫描(OpenPGP SELECT,然后对 C1/C2/C3 执行 GET DATA 以获取过期的 BrainpoolP512r1 属性)。它们**尚未**验证该卡是否为 Galdralag/Baochip 令牌。如果第一个 PC/SC 读卡器持有第三方 OpenPGP 卡,输出可能显示 `card_present: true` 以及针对**该**卡的过期 P512 警告。
**已跟踪的待办事项(仅限 Galdralag;不受 USB/CCID 阻塞):** 获取 **FSFE/GnuPG 注册的 OpenPGP 厂商 ID**,并过滤 AID 字节 7-8(GET DATA `0x004F`)。固件目前将 **`0x20A0`** 传入 `build_aid()`——这是 **USB VID**,被误用作占位厂商代码。参见 [docs/OPENPGP_CARD.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/OPENPGP_CARD.md)、[docs/future-todo.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/future-todo.md) 以及 [docs/XOUS_CORE_UPSTREAM_REQUESTS.md](https://github.com/supermagnum/galdralag-firmware/blob/main/docs/XOUS_CORE_UPSTREAM_REQUESTS.md) 第 6 节。
---
## 许可证
GNU 通用公共许可证 v3.0 — 参见 [LICENSE](https://github.com/supermagnum/galdralag-firmware/blob/main/LICENSE)。
| 字段 | 用途 | 主机(galdra SQLite) | 片上联系人存储 | 格式 / 限制 |
|---|
| 联系人 ID | 稳定的主机主键 | 是 | 否 | 文本(SQLite 中的 id) |
| 显示名称 | 人类可读标签 | 是 | 是 | UTF-8 字符串;片上每个堆字段最大 240 字节 |
| 电子邮件 | 主要邮件地址 | 是 | 是 | UTF-8 字符串;片上按电子邮件扫描查找 |
| 呼号 | 业余无线电呼号 | 是 | 是 | 12 字节,NUL 填充;片上查找 |
| DMR 用户 ID | DMR 无线电 ID | 是 | 是 | 32 位无符号整数(0 = 不存在);片上查找 |
| 徽章编号 | 员工或徽章 ID | 是 | 是 | UTF-8 字符串 |
| 组织 | 机构或雇主 | 是 | 是 | UTF-8 字符串 |
| 部门 | 团队或单位 | 是 | 是 | UTF-8 字符串 |
| 角色 | 职位或职能标签 | 是 | 是 | UTF-8 字符串 |
| 备注 | 自由格式注释 | 是 | 是 | UTF-8 字符串 |
| 无线电隶属关系 | 俱乐部、网络或联盟标签 | 是 | 是 | UTF-8 字符串 |
| 街道 | 街道地址行 | 是 | 是 | UTF-8 字符串 |
| 国家/地区 | 国家/地区名称或代码 | 是 | 是 | UTF-8 字符串 |
| 邮政编码 | ZIP 或邮政编码 | 是 | 是 | UTF-8 字符串 |
| 地区 | 州、县或地区 | 是 | 是 | UTF-8 字符串 |
| Fluxer ID | Fluxer 用户名或 ID | 是 | 是 | UTF-8 字符串 |
| Discord ID | Discord 用户 ID | 是 | 是 | UTF-8 字符串 |
| IRC ID | IRC 昵称或类似标识 | 是 | 是 | UTF-8 字符串 |
| 电话号码 | 语音或短信联系号码 | 是 | 否 | UTF-8 字符串;主机上最大 32 个字符;提交者声明,未验证 |
| 指纹 | 密钥锚点(查找、同步) | 是(pgp_fingerprint) | 是 | 32 字节;线上为 OpenPGP v4 风格;不等同于 G: 设备指纹 |
| 公钥 | 加密 / 验证材料 | 是(pgp_pubkey) | 是(密钥区域) | 算法:Ed25519、X25519、Brainpool P-256/P-384/P-512、NIST P-256/P-384、RSA-2048/3072/4096;片上 blob 最大 768 字节 |
| PIN 保护密钥 | 密钥需要 PIN 解锁 | 主机单独存储 OpenPGP 密钥 | 是 | 片上 PIN 验证器摘要 + AES-GCM 封装元数据 |
| 上次获取时间 | 密钥材料刷新时间 | 是(fetched_at) | 是(last_fetched) | 主机上为 UTC;片上为 32 位时间戳 |
| 过期时间 | 密钥过期时间 | 是 | 否 | 仅 SQLite 中的 UTC 日期时间 |
| 密钥来源 | 主机记录创建方式 | 是(source) | 否 | 例如手动、keyserver、WKD、LDAP、文件、对等 |
| 字段来源 | 每个元数据字段的信任标签 | 否 | 是(source_map) | 每字段两位:SelfAttested、HostVerified、RegistrySync、OobVerified |
| 记录标志 | 活动、过期、自身身份、已撤销 | 部分(主机逻辑) | 是 | 例如片上 STALE、SELF_KEY |
cargo run -p xtask -- timing-testtest-all--no-dudecttest-all-fulldocs/TEST_RESULTS.md。| 元数据字段 | OpenPGP / GnuPG | Galdra 密钥(主机 + 联系存储) |
|---|
| 联系人 / 记录 ID | 无(使用密钥 ID 或指纹) | 有(主机上为 SQLite id;芯片上无) |
| 显示名称 | 仅在 User ID 文本内(名称 <邮箱>) | 有(独立 UTF-8 字段) |
| 电子邮件 | 仅在 User ID 文本内 | 有(独立字段;芯片上可按电子邮件查找) |
| 街道地址 | 无标准字段 | 有 |
| 国家 | 无标准字段 | 有 |
| 邮政编码 | 无标准字段 | 有 |
| 地区 / 州 | 无标准字段 | 有 |
| 组织 | 无标准字段 | 有 |
| 部门 | 无标准字段 | 有 |
| 职位 / 职务 | 无标准字段 | 有 |
| 徽章 / 员工 ID | 无标准字段 | 有 |
| 呼号 | 无标准字段 | 有(12 字节,芯片上 NUL 填充) |
| DMR 用户 ID | 无标准字段 | 有(32 位;芯片上可查找) |
| 无线电隶属关系 | 无标准字段 | 有 |
| Fluxer ID | 无标准字段 | 有 |
| Discord ID | 无标准字段 | 有 |
| IRC ID | 无标准字段 | 有 |
| 电话号码 | 无标准字段 | 有(仅主机 SQLite) |
| 自由格式备注 | 无标准字段 | 有 |
| OpenPGP v4 指纹 | 有(40 个十六进制字符) | 链接证书时主机行上可选(pgp_fingerprint);Galdra 密钥在芯片上为 32 字节 |
G: 设备指纹 | 无 | 有(SIG 公钥上的 BLAKE3-160;主机工具;非 OpenPGP v4 值) |
| OpenPGP 密钥 ID | 有(短 / 长格式) | 无 |
| 信任 / 来源 | User ID 上的 WoT 签名 | 逐字段标签:SelfAttested、HostVerified、RegistrySync、OobVerified(芯片上) |
| 密钥过期 | 有(证书 / 子密钥) | 仅主机(SQLite 中的 expires_at) |
| 上次密钥获取时间 | 取决于主机工具 | 有(fetched_at / last_fetched) |
| 令牌上的私钥 | SIG、DEC、AUT 卡插槽 | 独立的 Galdra 密钥区域(非 User ID 数据包) |
| 使用私钥的 PIN | PW1 / PW3(OpenPGP 卡) | 每个 Galdra 联系记录可选 PIN 包装 |
| OpenPGP 卡对象(不在上表中) | 主机(GnuPG) | 令牌上 |
|---|
| 主密钥 + SIG / DEC / AUT 子密钥 | 密钥环中的公钥 | 密封插槽中的私钥 |
| 认证签名(WoT) | 有 | 无 |
| 吊销证书 | 有 | 无 |
| 算法属性(DO 0xC1 / 0xC2 / 0xC3) | gpg --card-edit | 有 |
galdra-core-host| 范围 | 典型标准 / 文档 | 作为标准 OpenPGP 卡 + GnuPG 暴露? |
|---|
| OpenPGP 卡应用 — APDU、PIN、SIG/DEC/AUT 槽位、卡上生成/签名/解密 | OpenPGP 卡规范(见 docs/OPENPGP_CARD.md) | 是 — 与其他 OpenPGP 智能卡相同的主机栈(gpg、scdaemon、CCID) |
| USB CCID — 将设备作为智能卡读卡器通信 | USB CCID 设备类 | 是 — 类驱动程序 |
| OpenPGP 消息格式 — 加密文件、邮件、密钥包 | RFC 4880(及更新版本) | 在主机上是 — GnuPG 使用此格式;卡不解析邮件 |
| Shamir K-of-N — 在保险库中拆分/恢复长期密钥材料 | 不在 OpenPGP 卡规范中;不在 GnuPG 中 | 否 — 仅限固件和配置工具;不是 gpg --card-edit 操作(见 Shamir 和全盘加密) |
| 双硬件密钥 / 法定人数授权 — 消费者操作前需要两个(或 N 个)令牌(驱动器解锁、门禁释放、特权操作) | 不在 OpenPGP 卡规范中 | 否 — 面向使用 Shamir 和/或多个 OpenPGP 认证的集成商的受支持扩展模式;执行属于下游系统(docs/DUAL_KEY_QUORUM.md) |
| 认证临时 ECDH — 令牌上的前向保密会话协议 | 不在 OpenPGP 卡规范中 | 否 — 令牌特定;不是 GnuPG 卡命令 |
| 密码配置文件系统 — 命名的对称级联(将独立密码堆叠在一起;最多四层,三层是受支持的深度)及相关策略 | 不在 OpenPGP 卡规范中 | 否 — 固件 / 主机令牌工具 |
| microSD 诱饵 / 大容量存储角色 — 不知情主机 USB 行为 | 不在 OpenPGP 卡规范中 | 否 — 独立的 USB 角色代码路径 |
| WebAuthn / FIDO2 | CTAP / WebAuthn | 未实现 — 与 OpenPGP 卡不同的标准 |
| 层 | 角色 |
|---|
| 驱动器 | 使用主密钥加密(例如通过 LUKS、VeraCrypt 或原始块层的 AES-256) |
| 主密钥 | 使用 SSS 拆分为 N 份共享,阈值为 K-of-N |
| 共享 | 由人员、设备或离线存储持有;K 份共享共同重建主密钥 |
| 解锁 | 重建密钥,然后将其传递给 cryptsetup、veracrypt 或你的栈 |
| 重建位置 | 气隙机器、HSM 策略或受控环境——而非不受信任的共享主机 |
| 场景 | 为何 SSS 加符合政策的强曲线很重要 |
|---|
| 员工离职或去世 | 无需该人的专属秘密即可实现恢复 |
| 依法访问(正当程序) | 可要求法定人数——没有任何单一一方持有完整解锁秘密 |
| 企业密钥托管 | 可审计的拆分;没有单一管理员拥有完全访问权 |
| 硬件被扣押 | 媒体可能被捕获,但 N 份中的 K 份份额未被捕获 |
| 监管对齐(欧盟 / BSI) | Brainpool 满足许多德国和欧盟政府密码要求 |
| Governikus 签名 | 确认用户完成流程时证书上的姓名与芯片认证的身份匹配 |
| 司法管辖区 | 本文档中涉及的状态 |
|---|
| 德国 | 上述 Governikus/BSI 流程 |
| 爱沙尼亚 | 芯片式 eID。2017–2018 年因 ROCA 漏洞迫使完全放弃 RSA(芯片无法生成安全的 RSA 密钥且无路径扩展到更大密钥尺寸)后,从 RSA 迁移至 NIST P-384(secp384r1)ECDSA。私钥硬件绑定,无法从卡中读取。未发现已知的 Governikus 式 OpenPGP 签名服务。 |
| 比利时 | 芯片式 eID。较旧卡片使用 RSA 1024 位;较新卡片(applet 1.8 起)使用 NIST P-384 ECDSA。活跃的开源中间件生态系统(eid-mw、OpenSC)。未发现已知的 Governikus 式 OpenPGP 签名服务。 |
| 挪威 | 国家身份证芯片(2020 年起签发)兼容 ICAO 9303,仅实现旅行证件芯片;不携带 eID 签名功能。签名 eID 是独立的:经认证的私营提供商(Buypass、Commfides)在 SEID 下运营,历史上为 RSA 2048 位,正转向 RSA 3072 位,SEID 2.0 中引入 ECC。未发现已知的 Governikus 式 OpenPGP 签名服务。旅行芯片和签名 eID 是分开的——如果有人试图仅直接使用卡芯片,这一点很重要。 |
| 奥地利 | 部分调查。 eID 使用 ECC(已确认);可用来源中未确认具体曲线。采用多令牌 Bürgerkarte 模式而非单卡;大部分已迁移至移动应用。曲线细节和任何 OpenPGP 签名服务需进一步调查。 |
| 美国 | PIV 卡(个人身份验证,FIPS 201 / NIST SP 800-78):仅签发给联邦雇员和承包商——并非通用民用卡。算法:认证密钥强制使用 NIST P-256;签名/密钥管理使用 P-256 或 P-384;也允许 RSA 2048/3072;仅 NIST 曲线,无 Brainpool。信任根为 联邦通用策略 CA(FCPCAG2),不包含在标准商业信任库中。未发现 Governikus 式 OpenPGP 签名服务;FPKI 是独立于 OpenPGP 的 X.509 基础设施。PIV 仅限联邦使用意味着它不像德国 eID 那样是民用信任锚。 |
| 加拿大 | 无带芯片上签名密钥的国家级芯片身份卡。数字身份分散在省级方案(例如 BC Services Card)、移动应用(例如 eID-Me)和不断演进的联邦数字凭证框架中。无与德国、爱沙尼亚或比利时模式相当的单卡。未发现等效卡基础设施——在此意义上不是可行的信任锚。 |
| 其他国家 | 未调查 |
| 目标 | 起点 |
|---|
| 项目概览、新闻、社区 | sequoia-pgp.org |
| 贡献(issue、修复、功能、文档);大型工作前先联系 | Contribute、Contact |
开发者文档 — 扩展实现的 API 表面(sequoia-openpgp 及相关 crate) | Docs — 例如 docs.rs 上的 sequoia-openpgp |
| 源码和跟踪器 | gitlab.com/sequoia-pgp(核心库和工具);github.com/sequoia-pgp(镜像 / 选定仓库);Projects |
| OpenPGP 标准中的新算法 | 仍需通过 IETF OpenPGP 工作组。Sequoia 和其他实现实现草案和 RFC;在那里提出协议变更,并与实现者(包括 Sequoia)协调,使行为与规范匹配。 |
streetcountrypostal_coderegiondmr_idradio_affiliationgaldra contact showPATCHDELETEgaldradGET /contacts/{id}POST /decryptrecipientgaldra keyserver pushorganisationrolenotebadge_numberphone_numbergaldra keyserver push --help--min-pin-length | 5–32 | 5 | 策略中存储的最小用户 PIN 长度(字母数字) |
| 算法 | 标准 | 等待 |
|---|
| ML-KEM | FIPS 203 | 经审计的 no_std Rust crate |
| ML-DSA | FIPS 204 | 经审计的 no_std Rust crate |
| SLH-DSA | FIPS 205 | 经审计的 no_std Rust crate |
| FN-DSA (FALCON) | FIPS 206 草案 | 标准定稿 + 经审计的 crate |
| HQC | 草案 ~2027 | 标准定稿 + 经审计的 crate |