#linux-kernel #merkle-tree #digest #hash #read-file #linux #verity

bin+lib fs-verity

使用纯 Rust 生成 fs-verity 测量值,或通过 Linux 内核 API 使用 fs-verity 冻结文件并获取其摘要

2 个不稳定版本

0.2.0 2023年6月9日
0.1.0 2020年12月20日

467Unix API

每月 35 次下载
2 个crate中使用(通过 puzzlefs-lib

MIT/Apache

40KB
410

fs-verity

此crate实现了与 Linux 内核的 fs-verity 功能交互的实用程序。

fs-verity 是什么?

它允许您永久使文件不可变,并让内核计算并存储文件的一个基于 Merkle 树的哈希值,该哈希值可以从该点开始立即从文件中检索。

内核还会再次验证从文件中读取的所有数据与 Merkle 树数据,如果存在不匹配,则拒绝读取。这意味着(只要您信任正在运行的内核),您可以绝对确信这个立即可检索的哈希值将匹配您从文件中读取的数据。

您应通过其他方式确定哈希值是否为预期的值,例如检查它是否在某个由某个密钥签名的接受哈希列表中。

内核的 fs-verity 代码实现了基本(且可选)的内核签名验证方案。然而,由于您仍然需要手动检查打开的文件是否启用了 fs-verity,它并没有增加太多价值,可能更多的是一个概念证明。此crate目前没有支持此方案。

目前 fs-verity 仅支持 f2fsext4 文件系统,您可能需要在文件系统中启用 fs-verity 选项。有关详细信息,请参阅 Linux 文档

这个crate是什么?

您可以将它视为 fsverity-utils / libfsverity 的纯 Rust 替代品。

它由两部分组成

  • 这是一个实现 sha2::digest::Digest 的示例,可以在用户态 Rust 代码中计算 fs-verity 测量值。这对于例如服务器和构建系统来说很有用,这些系统可能不希望(或无法)为文件启用 fs-verity,但仍然需要知道摘要值,以便创建包含所有摘要值的已签名的清单文件。
  • 在 Linux 系统上,有两个函数允许您为文件启用 fs-verity,并在启用后从内核获取文件的摘要值。这直接使用了 ioctl 接口。

这主要是作为一个编码练习产生的。它运行良好,相当整洁(好吧,在自我设定的 API 约束下尽可能整洁),并且注释详尽,但它的速度略慢于 C 实现,因为后者使用了 libcrypto 的 SHA256 汇编代码,而 RustCrypto 中的 SHA256 实现并不完全那么快。

这个实现的一个巧妙之处在于它以完全流式的方式工作,接受任意大小的任意数量的输入块。

Rust 版本

这个包应该与最新的稳定 Rust 兼容。如果不兼容较旧的 Rust 版本且您需要它,请提交一个问题。

安全性

该包在 linux 模块的两个函数中调用了不安全的 libc::ioctl 函数。没有使用其他不安全的代码。

使用了 Rust Crypto 库中的底层 SHA256 和 SHA512 哈希函数。默认情况下没有启用 Rust Crypto 的 asm 功能。

开发说明

要运行单元测试,首先使用 python3 make_testfiles.py 生成测试文件。

使用来自 fsverity-utils 或 'fsverity' 包的官方 fsverity 工具生成了“已知良好”的哈希值。

sudo apt install fsverity
for f in testfiles/*; do fsverity enable $f; done
fsverity measure testfiles/*

如果不起作用,您的文件系统可能不支持 fs-verity,或者您可能需要在文件系统超级块中打开此功能。请参阅有关 fs-verity 的详细信息的好文档 excellent fs-verity documentation

非常新的 fsverity 工具版本(您可能需要从 source 编译)也支持 digest 子命令,这允许您在不依赖内核或文件系统支持的情况下对文件进行哈希处理。

fsverity digest testfiles/*

许可证

此包根据您的选择在以下许可证下发布:

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义的,您提交的任何有意包含在工作中的贡献,都应按上述方式双重许可,而无需任何附加条款或条件。

依赖关系

~3–4.5MB
~85K SLoC