Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-deb.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ jobs:
strategy:
fail-fast: false
matrix:
distro: ["ubuntu:24.04"]
arch: [x86_64, aarch64]
distro: ["ubuntu:24.04", "debian:trixie"]
include:
- arch: x86_64
runner: ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
yum update -y

# install development tools
yum install -y autoconf automake binutils bison flex gcc gcc-c++ gdb glibc-devel libtool make pkgconf pkgconf-m4 pkgconf-pkg-config rpm-build rpm-sign strace asciidoc byacc ctags diffstat elfutils-libelf-devel git intltool patchutils perl-Fedora-VSP perl-Sys-Syslog perl-generators pesign source-highlight systemtap valgrind valgrind-devel cmake expect rpmdevtools rpmlint perl clang
yum install -y autoconf automake binutils bison flex gcc gcc-c++ gdb glibc-devel libtool make pkgconf pkgconf-m4 pkgconf-pkg-config rpm-build rpm-sign strace asciidoc byacc ctags diffstat elfutils-libelf-devel git intltool patchutils perl-Fedora-VSP perl-Sys-Syslog perl-generators pesign source-highlight systemtap valgrind valgrind-devel cmake expect rpmdevtools rpmlint perl clang python3

# install rpmdevtools
yum install -y git yum-utils
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ cryptpilot-verity/benchmark/cachefs_mount/
cryptpilot-verity/benchmark/cachefs_verity_mount/
cryptpilot-verity/benchmark/verity_on_cachefs_mount/
cryptpilot-verity/benchmark/verity_source_data/

# Superpowers design docs
docs/superpowers/
8 changes: 6 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,14 @@ deb-install: deb-build
dpkg -i ../cryptpilot-verity_*.deb ../cryptpilot-fde_*.deb ../cryptpilot-crypt_*.deb ../cryptpilot_*.deb
apt-get install -f -y

.PHONE: run-test
run-test: install-test-depend
.PHONY: run-test
run-test: install-test-depend verity-testfiles
cargo test -- --nocapture

.PHONY: verity-testfiles
verity-testfiles:
@cd verity-core && python3 make_testfiles.py

.PHONE: install-test-depend
install-test-depend:
[[ -e /tmp/pjdfstest/pjdfstest ]] || { cd /tmp/ && git clone https://github.com/pjd/pjdfstest.git && cd /tmp/pjdfstest && autoreconf -ifs && ./configure && make pjdfstest ; }
Expand Down
59 changes: 51 additions & 8 deletions cryptpilot-verity/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,56 @@ test: clean-test
@cargo run -- dump $(TEST_DATA_DIR) --print-metadata
@echo ""

@echo "Step 5: Running verify command..."
@echo "Step 4b: Testing format with labels..."
@cargo run -- format $(TEST_DATA_DIR) --hash-output $(TEST_HASH_FILE) --force --label env=test --label version=1.0
@echo "✓ Format with labels completed"
@echo ""

@echo "Step 4c: Testing dump --print-labels..."
@cargo run -- dump $(TEST_DATA_DIR) --print-labels
@echo ""

@echo "Step 4d: Testing dump --print-label for specific key..."
@ENV_VAL=$$(cargo run -- dump $(TEST_DATA_DIR) --print-label env 2>/dev/null); \
if [ "$$ENV_VAL" = "test" ]; then \
echo "✓ Label 'env' value correct: $$ENV_VAL"; \
else \
echo "✗ Label 'env' value mismatch! Expected 'test', got '$$ENV_VAL'"; \
exit 1; \
fi
@echo ""

@echo "Step 4e: Testing dump --print-label for nonexistent key..."
@if cargo run -- dump $(TEST_DATA_DIR) --print-label nonexistent 2>/dev/null; then \
echo "✗ Should have failed for nonexistent label key"; \
exit 1; \
else \
echo "✓ Nonexistent label key correctly rejected"; \
fi
@echo ""

@echo "Step 4f: Verifying labels do not affect root hash..."
@cargo run -- format $(TEST_DATA_DIR) --hash-output $(TEST_HASH_FILE) --force
@HASH_NO_LABEL=$$(cat $(TEST_HASH_FILE)); \
cargo run -- format $(TEST_DATA_DIR) --hash-output $(TEST_DIR)/hash_with_labels.txt --force --label env=test --label version=1.0 2>/dev/null; \
HASH_WITH_LABEL=$$(cat $(TEST_DIR)/hash_with_labels.txt); \
if [ "$$HASH_NO_LABEL" = "$$HASH_WITH_LABEL" ]; then \
echo "✓ Root hash is identical with and without labels"; \
else \
echo "✗ Root hash differs! Labels should not affect hash."; \
echo " Without labels: $$HASH_NO_LABEL"; \
echo " With labels: $$HASH_WITH_LABEL"; \
exit 1; \
fi
@echo ""

@echo "Step 9: Running verify command..."
@HASH=$$(cat $(TEST_HASH_FILE)); \
cargo run -- verify $(TEST_DATA_DIR) $$HASH
@echo "✓ Verification passed!"
@echo ""

@echo "Step 6: Testing verification failure (modified file)..."
@echo "Step 10: Testing verification failure (modified file)..."
@echo "modified content" > $(TEST_DATA_DIR)/file1.txt
@HASH=$$(cat $(TEST_HASH_FILE)); \
if cargo run -- verify $(TEST_DATA_DIR) $$HASH 2>&1; then \
Expand All @@ -56,12 +99,12 @@ test: clean-test
fi
@echo ""

@echo "Step 7: Restoring original file for mount test..."
@echo "Step 11: Restoring original file for mount test..."
@echo "test file 1 content" > $(TEST_DATA_DIR)/file1.txt
@echo "✓ File restored"
@echo ""

@echo "Step 8: Creating bind mount for tampering test later..."
@echo "Step 12: Creating bind mount for tampering test later..."
@echo " → Creating bind mount to access underlying data during verity mount..."
@mkdir -p $(TEST_BIND_DIR)
@mount --bind $(TEST_DATA_DIR) $(TEST_BIND_DIR) 2>/dev/null || { echo "✗ Failed to create bind mount (may need sudo)"; exit 1; }
Expand All @@ -71,7 +114,7 @@ test: clean-test



@echo "Step 9: Testing open command (in-place mount with built-in FUSE)..."
@echo "Step 13: Testing open command (in-place mount with built-in FUSE)..."
@HASH=$$(cat $(TEST_HASH_FILE)); \
echo " → Mounting verity-fuse in-place on $(TEST_DATA_DIR)..."; \
cargo run -- open $(TEST_DATA_DIR) $(TEST_DATA_DIR) $$HASH 2>&1 & \
Expand Down Expand Up @@ -110,15 +153,15 @@ test: clean-test
fi
@echo ""

@echo "Step 10: Unmounting for tampering detection test..."
@echo "Step 14: Unmounting for tampering detection test..."
@if mountpoint -q $(TEST_DATA_DIR) 2>/dev/null; then \
echo " → Unmounting in-place mount for tamper test..."; \
fusermount -u $(TEST_DATA_DIR) 2>/dev/null || umount $(TEST_DATA_DIR) 2>/dev/null || true; \
sleep 1; \
fi
@echo ""

@echo "Step 11: Testing tampering detection (cache disabled, using bind mount)..."
@echo "Step 15: Testing tampering detection (cache disabled, using bind mount)..."
@echo " → Tampering with underlying data via bind mount..."
@echo "TAMPERED DATA" > $(TEST_BIND_DIR)/file1.txt
@echo " → Opening with --block-cache-capacity 0 to disable cache for tamper detection..."
Expand Down Expand Up @@ -166,7 +209,7 @@ test: clean-test
@rmdir $(TEST_BIND_DIR) 2>/dev/null || true
@echo ""

@echo "Step 12: Unmounting after tampering test..."
@echo "Step 16: Unmounting after tampering test..."
@if mountpoint -q $(TEST_DATA_DIR) 2>/dev/null; then \
echo " → Unmounting..."; \
fusermount -u $(TEST_DATA_DIR) 2>/dev/null || cargo run -- close $(TEST_DATA_DIR) 2>/dev/null || true; \
Expand Down
8 changes: 7 additions & 1 deletion cryptpilot-verity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The CLI interface and subcommand design are intentionally similar to the `verity
- POSIX metadata such as permissions bits, ownership (`uid`, `gid`), and timestamps.
- Mount options, kernel-side permission checks, or higher-level application logic.
- Integrity of files or directories that were never included in the formatted metadata; in practice such paths are ignored and do not appear in the exposed filesystem view. Likewise, if a file that was included in the metadata is later removed from the underlying filesystem, this is treated as absence rather than active tampering and does not by itself trigger an integrity failure.
- Labels (key-value metadata attached during format). Labels are stored in the metadata file but are not integrity-protected by the root hash.

## Security Notes

Expand Down Expand Up @@ -73,7 +74,7 @@ All commands are subcommands of the `cryptpilot-verity` binary. Run `cryptpilot-
### `format`

```bash
cryptpilot-verity format <DATA_DIR> [--metadata <METADATA_PATH>] [--force] --hash-output <HASH_OUTPUT>
cryptpilot-verity format <DATA_DIR> [--metadata <METADATA_PATH>] [--force] [--label key=value]... --hash-output <HASH_OUTPUT>
```

- **Purpose**: Generate fs-verity metadata and the root hash for a given data directory.
Expand All @@ -82,6 +83,7 @@ cryptpilot-verity format <DATA_DIR> [--metadata <METADATA_PATH>] [--force] --has
- `--metadata, -m` **[optional]**: Path to the output metadata file (FlatBuffers-encoded). If not specified, defaults to `<DATA_DIR>/cryptpilot-verity.metadata.fb`.
- `--hash-output`: Path to write the root hash (use `-` for stdout).
- `--force` **[optional]**: Overwrite an existing metadata file at the target path. Intended for re-formatting or third-party auditing of an already formatted directory.
- `--label key=value` **[optional, repeatable]**: Attach a label to the metadata. Labels are key-value pairs (Docker-style) stored in the metadata file. Can be specified multiple times. Labels are NOT included in the root hash calculation.

### `verify`

Expand All @@ -101,6 +103,8 @@ cryptpilot-verity verify <DATA_DIR> <HASH> [--metadata <METADATA_PATH>] [--metad
```bash
cryptpilot-verity dump <DATA_DIR> --print-metadata
cryptpilot-verity dump --metadata <METADATA_PATH> --print-root-hash
cryptpilot-verity dump <DATA_DIR> --print-label <KEY>
cryptpilot-verity dump <DATA_DIR> --print-labels
```

- **Purpose**: Inspect metadata and/or print only the root hash.
Expand All @@ -109,6 +113,8 @@ cryptpilot-verity dump --metadata <METADATA_PATH> --print-root-hash
- `--metadata` **[optional]**: Path to the metadata file to read directly. Either `--metadata` or `<DATA_DIR>` must be specified (not both required).
- `--print-metadata`: Print the full decoded metadata (must specify either this or `--print-root-hash`).
- `--print-root-hash`: Print only the root hash (must specify either this or `--print-metadata`).
- `--print-label <KEY>`: Print the value of a specific label key. Exits with an error if the key is not found.
- `--print-labels`: Print all labels (one `key=value` per line). Prints `(no labels)` if no labels were set during format.

### `open`

Expand Down
8 changes: 7 additions & 1 deletion cryptpilot-verity/README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ CLI 接口和子命令设计有意与 `veritysetup` 工具类似,以便熟悉
- POSIX 元数据,如权限位、所有权(`uid`、`gid`)和时间戳。
- 挂载选项、内核端权限检查或更高级别的应用程序逻辑。
- 从未包含在格式化元数据中的文件或目录的完整性;实际上,此类路径会被忽略,并且不会出现在公开的文件系统视图中。同样,如果元数据中包含的文件后来从底层文件系统中删除,这将被视为不存在而不是主动篡改,本身不会触发完整性失败。
- 标签(格式时附加的键值元数据)。标签存储在元数据文件中但不受 root hash 完整性保护。

## 安全注意事项

Expand Down Expand Up @@ -72,7 +73,7 @@ CLI 接口和子命令设计有意与 `veritysetup` 工具类似,以便熟悉
### `format`

```bash
cryptpilot-verity format <DATA_DIR> [--metadata <METADATA_PATH>] [--force] --hash-output <HASH_OUTPUT>
cryptpilot-verity format <DATA_DIR> [--metadata <METADATA_PATH>] [--force] [--label key=value]... --hash-output <HASH_OUTPUT>
```

- **目的**:为给定的数据目录生成 fs-verity 元数据和根哈希。
Expand All @@ -81,6 +82,7 @@ cryptpilot-verity format <DATA_DIR> [--metadata <METADATA_PATH>] [--force] --has
- `--metadata, -m` **[可选]**:输出元数据文件(FlatBuffers 编码)的路径。如果未指定,默认为 `<DATA_DIR>/cryptpilot-verity.metadata.fb`。
- `--hash-output`:写入根哈希的路径(使用 `-` 表示标准输出)。
- `--force` **[可选]**:覆盖目标路径上的现有元数据文件。用于重新格式化或对已格式化目录进行第三方审计。
- `--label key=value` **[可选,可重复]**:为元数据附加标签。标签是键值对(Docker 风格),存储在元数据文件中但不参与 root hash 计算。

### `verify`

Expand All @@ -100,6 +102,8 @@ cryptpilot-verity verify <DATA_DIR> <HASH> [--metadata <METADATA_PATH>] [--metad
```bash
cryptpilot-verity dump <DATA_DIR> --print-metadata
cryptpilot-verity dump --metadata <METADATA_PATH> --print-root-hash
cryptpilot-verity dump <DATA_DIR> --print-label <KEY>
cryptpilot-verity dump <DATA_DIR> --print-labels
```

- **目的**:检查元数据和/或仅打印根哈希。
Expand All @@ -108,6 +112,8 @@ cryptpilot-verity dump --metadata <METADATA_PATH> --print-root-hash
- `--metadata` **[可选]**:直接读取的元数据文件路径。必须指定 `--metadata` 或 `<DATA_DIR>` 之一(不需要同时指定两者)。
- `--print-metadata`:打印完整的解码元数据(必须指定此项或 `--print-root-hash`)。
- `--print-root-hash`:仅打印根哈希(必须指定此项或 `--print-metadata`)。
- `--print-label <KEY>`:输出指定标签键的值。如果键不存在则报错退出。
- `--print-labels`:输出所有标签(每行一个 `key=value`)。如果未设置标签则输出 `(no labels)`。

### `open`

Expand Down
Loading
Loading