fscryptctl

repository·master·Indexed 41 days ago

https://github.com/google/fscryptctl

A low-level C tool for managing Linux filesystem encryption (fscrypt) policies and raw keys. Designed for embedded systems or testing, it supports v2 encryption policies on Linux kernel 5.4+ and provides CLI commands for adding, removing, and checking key status, as well as managing hardware-wrapped keys for inline encryption on Linux 6.16+.

Tokens
2.3K
Snippets
9
Records
12
Agent score
50%

What's inside fscryptctl

  1. Understand fscryptctl runtime requirements

    master

    fscryptctl is a low-level tool for managing Linux filesystem encryption policies. It does not handle key generation, key stretching, or key wrapping.

    Prerequisites:

    • Kernel: Must support CONFIG_FS_ENCRYPTION=y. Since v1.0, fscryptctl only supports v2 encryption policies, requiring Linux kernel 5.4 or later.
    • Filesystem: Must be configured for encryption.
      • For ext4: Use tune2fs -O encrypt on an existing filesystem or mkfs.ext4 -O encrypt for a new one.
      • For f2fs: Use mkfs.f2fs -O encrypt or fsck.f2fs -O encrypt.
    • Hardware (Optional): For hardware-wrapped inline encryption, you need Linux 6.16+ and compatible hardware (e.g., Qualcomm SM8650 HDK).
  2. Build and install fscryptctl

    master

    To build the project, use make. The build requires GNU Make, a C99 compatible compiler, and pandoc (if you want to build the manual pages).

    To install the full package including manual pages:

    make
    sudo make install

    To build and install only the binary (skipping the pandoc dependency for manual pages):

    make fscryptctl
    sudo make install-bin
    make
    sudo make install
  3. Example: Basic filesystem encryption workflow

    master

    This workflow demonstrates creating an ext4 filesystem, adding a raw 512-bit key, and setting an encryption policy on a directory.

    Note: When using add_key, you must provide a real cryptographic key via stdin. fscryptctl does not perform key stretching (e.g., it won't turn a passphrase into a key).

    # 1. Create an ext4 filesystem with encryption support
    > mkfs.ext4 -O encrypt /dev/vdb
    
    # 2. Mount the filesystem
    > mount /dev/vdb /mnt
    
    # 3. Generate a random 512-bit (64-byte) key
    > head -c 64 /dev/urandom > /tmp/key
    
    # 4. Add the key to the filesystem (returns a 32-char hex identifier)
    > fscryptctl add_key /mnt < /tmp/key
    f12fccad977328d20a16c79627787a1c
    
    # 5. Create an encrypted directory using that key identifier
    > fscryptctl set_policy f12fccad977328d20a16c79627787a1c /mnt/dir
    
    # 6. Verify the policy
    > fscryptctl get_policy /mnt/dir
  4. Example: Using hardware-wrapped keys

    master

    On systems supporting hardware-wrapped inline encryption, you can use hardware-wrapped keys instead of raw keys. This requires Linux 6.16+ and compatible hardware.

    # 1. Create filesystem with encryption and stable inodes
    > mkfs.ext4 -O encrypt,stable_inodes /dev/vdb
    
    # 2. Mount with inlinecrypt support
    > mount /dev/vdb -o inlinecrypt /mnt
    
    # 3. Import a hardware-wrapped key
    > head -c 32 /dev/urandom | fscryptctl import_hw_wrapped_key /dev/vdb > /tmp/lt_key
    
    # 4. Prepare and add the hardware-wrapped key
    > fscryptctl prepare_hw_wrapped_key /dev/vdb < /tmp/lt_key | fscryptctl add_key --hw-wrapped-key /mnt
    
    # 5. Set policy on a directory
    > mkdir /mnt/dir
    > fscryptctl set_policy --iv-ino-lblk-64 f12fccad977328d20a16c79627787a1c /mnt/dir
  5. Reference the fscryptctl CLI commands

    master

    The following commands are available in fscryptctl:

    • add_key: Add an encryption key to a filesystem. Accepts the raw binary key via standard input.
    • remove_key: Remove an encryption key from a filesystem.
    • key_status: Get the status of an encryption key on a filesystem.
    • get_policy: Get the encryption policy of a file or directory.
    • set_policy: Set the encryption policy of an empty directory.
    • import_hw_wrapped_key: Import a hardware-wrapped key.
    • generate_hw_wrapped_key: Generate a hardware-wrapped key.
    • prepare_hw_wrapped_key: Prepare a hardware-wrapped key.
  6. Remove an encryption key with remove_key

    master

    Use fscryptctl remove_key to remove an encryption key from a mounted filesystem, which effectively "locks" the protected files and directories.

    Usage: fscryptctl remove_key [OPTION] KEY_IDENTIFIER MOUNTPOINT

    Options:

    • --all-users: Removes all users' claims to the key rather than just the current user's. This requires root privileges.
    # Remove a specific key for the current user
    fscryptctl remove_key <KEY_IDENTIFIER> /mnt/encrypted_fs
    
    # Remove all users' claims to the key (requires root)
    fscryptctl remove_key --all-users <KEY_IDENTIFIER> /mnt/encrypted_fs
  7. Add an encryption key with add_key

    master

    Use fscryptctl add_key to add a raw cryptographic key to a mounted filesystem. This unlocks files and directories protected by that key.

    Important: The key must be provided via standard input in raw binary format. It must be a real cryptographic key, not a password.

    Upon success, the command prints a 32-character hex string representing the key identifier, which you should save to use with other fscryptctl commands.

    # Example: Adding a raw 512-bit key from a file
    cat my_raw_key.bin | fscryptctl add_key /mnt/encrypted_fs
  8. Manage hardware-wrapped keys

    master

    These commands interact with the kernel's inline encryption interface for hardware-wrapped keys on a block device.

    • generate_hw_wrapped_key BLOCK_DEVICE: Instructs the hardware to generate a new long-term wrapped key. The resulting blob is written to stdout in binary.
    • import_hw_wrapped_key BLOCK_DEVICE: Imports a raw key from stdin and converts it into a long-term wrapped key blob, which is written to stdout in binary.
    • prepare_hw_wrapped_key BLOCK_DEVICE: Converts a long-term wrapped key blob (from stdin) into an ephemerally-wrapped form (to stdout) for use.

    All these commands operate on binary data via stdin/stdout.

    # Generate a new hardware-wrapped key and save it to a file
    fscryptctl generate_hw_wrapped_key /dev/nvme0n1 > wrapped_key.bin
  9. Set encryption policy with set_policy

    master

    Use fscryptctl set_policy to apply an encryption policy to a directory. This command uses version 2 policies.

    Usage: fscryptctl set_policy [OPTION] KEY_IDENTIFIER DIRECTORY

    Options:

    • --contents=MODE: Cipher for file contents. Options: AES-256-XTS (default), AES-128-CBC, SM4-XTS, Adiantum.
    • --filenames=MODE: Cipher for filenames. Options: AES-256-CTS (default), AES-128-CTS, SM4-CTS, Adiantum, AES-256-HCTR2.
    • --padding=BYTES: Alignment for encrypted filename lengths to hide original lengths. Options: 4, 8, 16, 32 (default).
    • --direct-key: Optimize for Adiantum encryption.
    • --iv-ino-lblk-64: Optimize for UFS inline encryption hardware.
    • --iv-ino-lblk-32: Optimize for eMMC inline encryption hardware.
    • --data-unit-size=BYTES: Select the crypto data unit size (granularity of encryption).
    # Example: Set a policy using AES-256-XTS for contents and Adiantum for filenames
    fscryptctl set_policy <KEY_IDENTIFIER> /mnt/encrypted_fs/new_dir --contents=AES-256-XTS --filenames=Adiantum
  10. Check key status with key_status

    master

    Use fscryptctl key_status to check if a specific key is present on a mounted filesystem.

    Usage: fscryptctl key_status KEY_IDENTIFIER MOUNTPOINT

    Possible Statuses:

    • Present: The key is active. If present, the output will also show which users added the key.
    • Absent: The key is not on the filesystem.
    • Incompletely removed: The key is in a transitional state.
    fscryptctl key_status <KEY_IDENTIFIER> /mnt/encrypted_fs
  11. Get encryption policy with get_policy

    master

    Use fscryptctl get_policy to view the encryption policy of a specific file or directory. The policy includes the encryption key used and the specific encryption options (ciphers for contents and filenames).

    fscryptctl get_policy /mnt/encrypted_fs/my_directory