#消息认证 #伽利略 #GNSS #树根 #加密 #OSNMA

无 std 程序+库 galileo-osnma

伽利略 OSNMA(开放服务导航消息认证)

8 个版本 (破坏性更新)

0.8.0 2024 年 1 月 26 日
0.7.0 2024 年 1 月 19 日
0.6.0 2024 年 1 月 5 日
0.5.0 2023 年 10 月 3 日
0.1.0 2022 年 3 月 26 日

#99 in 身份验证

每月 29 次下载

MIT/Apache

265KB
4.5K SLoC

galileo-osnma

Crates.io Docs Rust OSNMA Test Vectors License License: MIT

galileo-osnma 是伽利略 OSNMA(开放服务导航消息认证)协议的 Rust 实现。该协议由伽利略 GNSS 用于对其卫星传输的导航消息数据进行加密签名,以防止欺骗。简而言之,galileo-osnma 可以处理导航消息数据和 OSNMA 加密数据,并检查所有加密签名是否与 ECDSA 公钥和/或 Merkle 树相匹配,以检查导航数据的真实性。

galileo-osnma 不需要 Rust 标准库(可以使用 no_std 构建),在栈上静态分配所有数据,并具有相对较小的内存占用(如果使用 Slow MAC,则约为 76 KiB,并存储 36 个卫星的并行数据,如果不使用 Slow MAC,则约为 8.5 KiB,并存储 12 个卫星的并行数据)。这使得可以在某些嵌入式微控制器中使用该库。在 Longan nano GD32VF103 板上运行的 galileo-osnma 的演示程序位于 osnma-longan-nano crate 中。这是一个类似流行的 STM32F103 ARM Cortex-M3 微控制器的 RISC-V 微控制器,具有 128 KiB 的闪存和 32 KiB 的 RAM。

文档

galileo-osnma 的文档托管在 docs.rs

以下来自伽利略系统的参考文档相关

使用 Galmon 快速入门

galileo-osnma 附带一个二进制应用程序,可以使用 Galmon 传输协议 读取伽利略 INAV 页面。它位于 galmon-osnma 文件夹中。

快速查看此功能的工作方式是使用Galmon Galileo导航数据源,数据从86.82.68.237的TCP端口10000流式传输。在galmon-osnma文件夹中,我们可以运行

nc 86.82.68.237 10000 | \
    RUST_LOG=info cargo run --release -- --pubkey osnma-pubkey.pem --pkid N

来查看galileo-osnma处理由Galmon流式传输的OSNMA和导航数据。关于如何配置该应用程序产生的日志信息,请参阅env_logger文档。

文件osnma-pubkey.pem应包含Galileo OSNMA公钥,而数字N应为其关联的公钥ID(PKID)。请参阅下文了解如何获取这些数据。

请注意,Galmon从世界各地的多个接收器汇总数据,数据包偶尔会在流中到达顺序错误。这不是galileo-osnma的主要预期用途。因此,运行时可能会出现一些数据或时间戳不一致的小问题。

或者,您可以使用Galmon的工具之一与您自己的GNSS接收器一起使用。例如,uBlox接收器可以用作

ubxtool --wait --port /dev/ttyACM0 --station 1 --stdout --galileo \
    | RUST_LOG=info cargo run --release -- --pubkey osnma-pubkey.pem --pkid N

获取Galileo OSNMA公钥和Merkle树根

为了运行galmon-osnma和其他示例应用程序,以及充分利用该库,需要获取OSNMA ECDSA公钥和/或Merkle树根。当前ECDSA公钥用于验证信号空间中传输的OSNMA加密数据(更确切地说,TESLA根密钥)。Merkle树根用于验证在信号空间中广播的ECDSA公钥。这些密钥每6小时(在00:00、06:00、12:00和18:00 GST)传输一次。

galmon-osnma应用程序可以使用ECDSA公钥(使用--pubkey--pkid参数),Merkle树根(使用--merkle-root参数),或两者都使用。如果只提供了ECDSA公钥,则应用程序将无法使用在信号空间中广播的新公钥进行公钥更新或撤销。如果只提供了Merkle树根,则必须等待当前ECDSA公钥在信号空间中广播。

可以从欧洲GNSS服务中心下载公钥和Merkle树根,在GSC产品 > OSNMA_PUBLICKEY下。获取这些文件需要注册账户。

公钥以x509证书的形式下载。公钥ID包含在文件名中,并在GSC产品网站上其他地方列出。当前的证书文件是OSNMA_PublicKey_20240115100000_newPKID_1.crt,相应的公钥ID是1。符合galmon-osnma要求的PEM格式密钥可以通过以下命令提取

openssl x509 -in OSNMA_PublicKey_20240115100000_newPKID_1.crt -noout -pubkey > osnma-pubkey.pem

Merkle树信息下载为一个XML文件。当前文件是OSNMA_MerkleTree_20240115100000_newPKID_1.xml。树根以256位十六进制数表示,可以从XML文件中提取

./utils/extract_merkle_tree_root.py OSNMA_MerkleTree_20240115100000_newPKID_1.xml

此256位十六进制格式是galmon-osnma --merkle-root参数直接使用的格式。树根也列在GSC产品网站的其他部分。

公钥也以十六进制形式给出,为264位压缩点,在包含公钥的XML文件、默克尔树XML文件以及其他GSC产品网站的部分中均有提及。位于utils文件夹中的脚本extract_public_key.pyextract_merkle_tree_key.py可以用于从这些XML文件中提取十六进制格式的密钥。位于utils文件夹中的脚本sec1_to_pem.py可以用于将这种十六进制表示形式转换为PEM格式。

开发状态

galileo-osnma自公开测试阶段的第一次发布以来就可以使用了,并在服务阶段对OSNMA ICD更改进行了更新。目前它与OSNMA SIS ICD v1.1保持一致。galileo-osnma可以使用ECDSA公钥和默克尔树对OSNMA目前支持的所有类型的导航数据进行身份验证。OSNMA协议的一些功能和路线图功能尚未实现。以下列出这些功能。

支持的功能

  • 使用ECDSA P-256验证DSM-KROOT。
  • 使用ECDSA P-521验证DSM-KROOT,有一些注意事项:有一个p521功能用于启用或禁用P-521支持。默认情况下,此功能已启用。在osnma-longan-nano演示中已禁用,否则固件大小对于目标微控制器来说太大。应用galmon-osnma只能加载PEM格式的P-256密钥。可以使用--pubkey-p521参数加载十六进制格式的P-521密钥。
  • 针对默克尔树根验证DSM-PKR。
  • 使用TESLA根密钥或链中先前验证的密钥验证TESLA密钥。
  • 使用MAC查找表验证MACK消息中的MACSEQ和ADKD字段。这包括检查灵活的ADKDs。
  • 使用MACK消息中的所有标签验证ADKD=0、ADKD=4和ADKD=12的导航数据。
  • 使用OSNMA数据检索DSM消息。
  • 使用OSNMA数据检索MACK消息。
  • 使用INAV字检索导航数据。
  • 存储当前ECDSA公钥和可能下一个ECDSA公钥,以便无缝支持密钥更新或撤销场景。
  • 存储当前TESLA密钥和可能下一个链的TESLA密钥,以便无缝支持链更新或撤销场景。
  • 存储和分类MACK消息和导航数据。
  • 标签累积。需要40位标签才能将导航数据视为已验证。
  • 非标准场景(更新、撤销、警报),根据NMA报头中的NMA状态和CPKS字段的值。

不支持的功能

  • 通过加载先前验证的TESLA密钥进行暖启动。

路线图功能。这些不是OSNMA自身的功能,但将增加galileo-osnma的功能和可用性。

  • C API
  • Python API

OSNMA测试向量

有一个名为run_test_vectors.sh的脚本,用于运行作为OSNMA测试向量附件提供的OSNMA接收器指南v1.3的脚本。该脚本使用位于osnma-test-vectors-to-galmon文件夹中的小应用程序将CSV测试向量转换为Galmon传输格式,并将此数据通过管道传递给galmon-osnma应用程序。

当脚本运行时,它会打印出每个测试应该发生的情况的描述,但没有自动的通过/失败标准。每个测试的日志输出需要手动检查。该脚本按以下方式运行

./utils/run_test_vectors.sh Test_vectors

其中 Test_vectors 是包含测试向量的文件夹路径。建议如下运行,以便将所有输出以彩色形式捕获到 less

RUST_LOG_STYLE=always ./utils/run_test_vectors.sh Test_vectors 2>&1 | less -R

默认情况下,日志级别设置为仅显示错误和警告,以及与新导航数据成功认证对应的信息消息。可以通过通常的方式使用环境变量 RUST_LOG 来覆盖日志级别。

存在一个 CI 工作流程,该工作流程从 GSC 网站下载测试向量并运行 run_test_vectors.sh 脚本。此工作流程的输出可以作为 galileo-osnma 功能演示。

最低支持的 Rust 版本

Rust 1.70 或更高版本。

最低支持的 Rust 版本未来可能会更改,但将以小版本号的升级来完成。

许可证

以下任一许可证下授权:

任选其一。

贡献

除非您明确表示,否则根据 Apache-2.0 许可证定义,您提交给包含在工作中的任何有意贡献,都将如上双授权,不附加任何额外条款或条件。

依赖项

~6MB
~104K SLoC