Skip to content

Repository files navigation

Zff – A Modern Forensic Container Format

crate Docs Apache2/MIT licensed Rust Version codeberg wiki

zff is a modern forensic container format designed for high-performance acquisition, extensibility, scalability, and implementation clarity.

Its modular design enables maintainability and scalability while supporting a wide range of forensic workflows.

It supports both physical and logical evidence, streaming workflows, optional encryption and signing, deduplication, and multiple objects per container.

zff is not intended as a drop-in replacement for all existing forensic exchange formats (such as EWF or AFF4).
Instead, it provides a clean, well-defined, and performant foundation for building forensic tooling.


Design Goals

  • High-throughput acquisition and processing
  • Support for both physical and logical evidence
  • Streamable format design
  • Clear and maintainable implementation
  • Modern compression and cryptographic primitives
  • Extensibility without excessive complexity

Non-Goals

  • Immediate full interoperability with all existing forensic tools
  • Replicating legacy format behavior or constraints

See at the wiki to learn more about the specification.

Features (Zff v3)

  • Physical and logical acquisition support
  • Chunk-based storage model
  • Streamable container format
  • Optional compression (e.g. zstd, lz4)
  • Optional encryption and signing
  • Deduplication support
  • Multiple objects per container
  • Virtual objects (e.g. RAID reconstruction)
  • Cross-platform support

Why zff?

Existing forensic formats each have strengths:

  • EWF (E01/L01): widely used and broadly supported
  • AFF4: flexible and conceptually powerful

However, they also involve trade-offs in areas such as:

  • implementation complexity
  • extensibility
  • consistency across tooling
  • adoption of modern compression and cryptographic primitives

zff explores a different design approach:

  • a simpler and more consistent implementation model
  • modern performance characteristics
  • explicit support for both physical and logical evidence
  • full control over format evolution and tooling

The goal is not to replace existing formats universally,
but to provide a solid foundation for new forensic workflows.

Zff tools and libraries

There are several tools (and this library) to work with zff containers (or acquire them). All tools and libraries are written in pure Rust.

Name Type Description Crates.io
zff library Library to handle the zff format crates.io
zffacquire binary Tool to acquire disk images in zff format crates.io
zffanalyze binary Tool to get information about a zff container crates.io
zffmount binary Tool to mount a zff container with FUSE (similar to xmount) crates.io

Performance Notes

zff is designed for high performance through:

  • chunk-based processing
  • modern compression algorithms (e.g. zstd, lz4)
  • efficient streaming design
  • implementation in Rust

Project Benchmarks

The following benchmarks evaluate the performance of zff tooling compared to selected acquisition tools.

⚠️ These results reflect tool-level performance under specific conditions, not a universal comparison of the underlying formats.

Test Setup

The following benchmarks were all run on a notebook, which has the following specifications:

  • AMD Ryzen 7 7800X3D 8-Core Processor
  • 32GB DDR5 RAM
  • internal Samsung 980 Pro NVMe 1TB The installed operating system was Gentoo Linux.
    Input storage device was the internal NVMe.

The following benchmark was created for a ~20GB prebuilt image, which was generated using the benchmark script.

Results

⚠️ Comparisons reflect specific tool implementations and configurations, not inherent properties of the formats themselves.

---
config:
  xyChart:
    showDataLabel: true
---
xychart horizontal
    title "Benchmark: Acquisition time"
    x-axis "Tool" ["ewfacquire¹", "ewfacquire (Ex01)²", "zffacquire³", "zffacquire (+encryption)⁴", "zffacquire (+data signing)⁵", "zffacquire (lz4)⁶", "Guymager (e01-Image)⁷", "linpmem/aff4 (default settings)⁸", "linpmem/aff4 (default settings with 8 threads)⁹", "linpmem (snappy compression)¹⁰", "linpmem (lz4 compression)¹¹" ]
    y-axis "Time (s) - lower is better" 0 --> 200
    bar [108.44, 110.21, 16.48, 28.81, 19.49, 12.11, 55.33, 133.18, 27.57, 28.38, 15.83, 12.36 ]
Loading

¹using ewfacquire example01.dd -t example01_ewf -b 64 -c fast -S 7.9EiB -u, using ewfacquire 20240506 (example01_ewf.E01 was a symlink to /dev/null to provide equivalent write speed).
²using ewfacquire example01.dd -t example01_ewf -f encase7-v2 -b 64 -c fast -S 7.9EiB -u, using ewfacquire 20240506 (example01_ewf.E01 was a symlink to /dev/null to provide equivalent write speed) ³using zffacquire physical -i raw/example01.dd > /dev/null ⁴using zffacquire physical -i raw/example01.dd -p > /dev/null
⁵using zffacquire physical -i raw/example01.dd -S > /dev/null
⁶using zffacquire physical -i raw/example01.dd -z lz4 > /dev/null
⁷Using Guymager 0.8.12, with the default guymager.cfg, MD5 hash calculation, without "HashVerifyDest".
⁸using linpmem-3.3-rc1 -i example01.dd -o /dev/null
⁹using linpmem-3.3-rc1 -i example01.dd -o /dev/null --threads 8
¹⁰using linpmem-3.3-rc1 -i example01.dd -o /dev/null -c snappy
¹¹using linpmem-3.3-rc1 -i example01.dd -o /dev/null -c lz4

---
config:
  xyChart:
    showDataLabel: true
---
xychart horizontal
    title "Benchmark: Read speed"
    x-axis "Tool" ["zffacquire (Zffv3, zstd-Image)¹", "zffacquire (Zffv2, zstd-Image)²", "xmount (ewfacquire Ex01-Image)³", "xmount (guymager e01-Image)⁴" ]
    y-axis "GB/s - higher is better" 0.0 --> 4.5
    bar [4.24, 1.98, 1.13, 1.05]
Loading


¹The following commands were used:

zffmount -i zff.z01 -m /tmp/zffmount -c in-memory
dd if=/tmp/zffmount/zff_image.dd of=/dev/null bs=1M

²The following commands were used:

zffmount-v2 -i zff.z01 -m /tmp/zffmount
dd if=/tmp/zffmount/zff_image.dd of=/dev/null bs=1M

³The following commands were used:

xmount --in ewf ewfacquired.Ex01 /tmp/ewfmount
dd if=/tmp/ewfmount/ewfacquired.dd of=/dev/null bs=1M

⁴The following commands were used:

xmount --in ewf guymager.e01 /tmp/ewfmount
dd if=/tmp/ewfmount/guymager.dd of=/dev/null b=1M

Interpretation

The results indicate that zff-based tooling can achieve competitive throughput in this specific setup.

However, performance depends heavily on:

  • dataset characteristics
  • compression configuration
  • hardware (CPU vs I/O bound)
  • implementation details of the compared tools

In particular, comparisons involving AFF4 should be interpreted carefully, as publicly available implementations differ significantly in feature coverage and performance behavior.


Limitations

  • Benchmarks were conducted on a single system and dataset
  • Different tools expose different defaults and feature sets
  • Not all formats have equally mature or comparable tooling
  • Results should be considered indicative, not definitive

Project Scope

zff is both:

  • a file format specification
  • a reference implementation and tooling ecosystem

The current implementation aims to:

  • provide a complete and consistent reference
  • validate format design decisions in practice
  • enable real-world forensic workflows

Future development will focus on:

  • improving tooling and usability
  • expanding format features where necessary
  • maintaining backward compatibility where possible

Zff layout

See at the wiki for further information.

License

Zff is open source and Apache 2.0 and MIT licensed. This should ensure compliance to use with both open source and commercial software.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

Library to handle the files in zff format (file format to store and handle forensic acquisitions).

Topics

Resources

Security policy

Stars

22 stars

Watchers

4 watching

Forks

Releases

Packages

Used by

Contributors

Languages