Git Product home page Git Product logo

fscryptctl's Introduction

fscryptctl

Build Status License

fscryptctl is a low-level tool written in C that handles raw keys and manages policies for Linux filesystem encryption, specifically the "fscrypt" kernel interface which is supported by the ext4, f2fs, UBIFS, and CephFS filesystems.

fscryptctl is mainly intended for embedded systems which can't use the full-featured fscrypt tool, or for testing or experimenting with the kernel interface to Linux filesystem encryption. fscryptctl does not handle key generation, key stretching, key wrapping, or PAM integration. Most users should use the fscrypt tool instead, which supports these features and generally is much easier to use.

As fscryptctl is intended for advanced users, you should read the kernel documentation for filesystem encryption before using fscryptctl.

For the release notes, see the NEWS file.

Table of Contents

Building and Installing

To build, run make. The build dependencies are GNU Make, a C compiler (only C99 is needed), and pandoc.

To install, run sudo make install.

If you don't want to build and install the fscryptctl.1 manual page, you can instead run make fscryptctl and sudo make install-bin. This will build and install the fscryptctl binary only, avoiding the build dependency on pandoc.

See the Makefile for compilation and installation options.

Runtime Dependencies

fscryptctl doesn't link to any libraries (other than libc), so its only runtime dependencies are the kernel and filesystem support for encryption. In most cases that means the kernel must have been built CONFIG_FS_ENCRYPTION=y, and a command like tune2fs -O encrypt must have been run on the filesystem.

Since v1.0, fscryptctl only supports v2 filesystem encryption policies. This means that it must be used with Linux kernel 5.4 or later. If you need support for v1 encryption policies, use an earlier version of fscryptctl. However, be aware that v1 had some significant usability and security limitations.

For more information about the kernel and filesystem prerequisites, see the fscrypt documentation, including the troubleshooting tips.

Features

fscryptctl has the following commands:

  • fscryptctl add_key - add an encryption key to a filesystem
  • fscryptctl remove_key - remove an encryption key from a filesystem
  • fscryptctl key_status - get the status of an encryption key on a filesystem
  • fscryptctl get_policy - get the encryption policy of a file or directory
  • fscryptctl set_policy - set the encryption policy of an empty directory

For full usage details, see the manual page (man fscryptctl), or alternatively run fscryptctl --help.

The add_key command accepts the encryption key in binary on standard input. It is critical that this be a real cryptographic key (and not a passphrase, for example), since fscryptctl doesn't do key stretching itself. Obviously, don't store the raw encryption key alongside the encrypted files. (If you need support for passphrases, use fscrypt instead of fscryptctl.)

After running the add_key command to add an encryption key to a filesystem, you can use the set_policy command to create an encrypted directory on that filesystem. The encryption key is specified by the 32-character hex "key identifier" that was printed by add_key. The directory must be empty.

Example Usage

# Create an ext4 filesystem that supports encryption.
# (Alternatively, use `tune2fs -O encrypt` on an existing ext4 filesystem.)
# (For f2fs, use `mkfs.f2fs -O encrypt` or `fsck.f2fs -O encrypt`.)
> mkfs.ext4 -O encrypt /dev/vdb

# Mount the filesystem.  Optionally add any desired mount options, such as
# `-o inlinecrypt` to make use of inline crypto hardware.
> mount /dev/vdb /mnt

# Generate a random 512-bit key and store it in a file.
> head -c 64 /dev/urandom > /tmp/key

# Add the key to the filesystem.
> fscryptctl add_key /mnt < /tmp/key
f12fccad977328d20a16c79627787a1c

# Get the status of the key on the filesystem.
> fscryptctl key_status f12fccad977328d20a16c79627787a1c /mnt
Present (user_count=1, added_by_self)

# Create an encrypted directory that uses the key.
> fscryptctl set_policy f12fccad977328d20a16c79627787a1c /mnt/dir

# Show the directory's encryption policy that was just set.
> fscryptctl get_policy /mnt/dir
Encryption policy for /mnt/dir:
        Policy version: 2
        Master key identifier: f12fccad977328d20a16c79627787a1c
        Contents encryption mode: AES-256-XTS
        Filenames encryption mode: AES-256-CTS
        Flags: PAD_32

# Create some files in the encrypted directory.
> echo foo > /mnt/dir/foo
> mkdir /mnt/dir/bar

# Remove the encryption key from the filesystem.
# (Alternatively, unmounting the filesystem will remove the key too.)
> fscryptctl remove_key f12fccad977328d20a16c79627787a1c /mnt

# Get the status of the key on the filesystem.
> fscryptctl key_status f12fccad977328d20a16c79627787a1c /mnt
Absent

# The directory is now locked.  So the filenames are shown in encrypted form,
# and files can't be opened or created.
> ls /mnt/dir
AcbnATV97HZzxlmWNoErWS8QkdgTzMzbPU5hjs7XwvyralC5fQCtQA
qXT50ks2,3RzC8kqJ5FvnHgxS6oL2UDa8nsVkCFmoUQQygA3nWzxfA
> cat /mnt/dir/qXT50ks2,3RzC8kqJ5FvnHgxS6oL2UDa8nsVkCFmoUQQygA3nWzxfA
cat: /mnt/dir/qXT50ks2,3RzC8kqJ5FvnHgxS6oL2UDa8nsVkCFmoUQQygA3nWzxfA: Required key not available
> mkdir /mnt/dir/foobar
mkdir: cannot create directory ‘/mnt/dir/foobar’: Required key not available

# Re-adding the key restores access to the files.
> fscryptctl add_key /mnt < /tmp/key
f12fccad977328d20a16c79627787a1c
> ls /mnt/dir
bar foo
> cat /mnt/dir/foo
foo

Contributing

We would love to accept your contributions to fscryptctl. See the CONTRIBUTING.md file for more information.

Legal

Copyright 2017, 2020 Google LLC. Licensed under the Apache 2.0 License; see the LICENSE file for more information.

Authors: Joe Richey ([email protected]), Eric Biggers ([email protected])

This is not an official Google product.

fscryptctl's People

Contributors

andred avatar ebiggers avatar iokill avatar jacmet avatar josephlr avatar uudiin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fscryptctl's Issues

Error when unlocking filesystem.

I tested fscrypt with ext4, but I got this error:

root@pc1:/home/hamiltonp/Temp# fscrypt unlock mount/blah/
Enter custom passphrase for protector "test":
fscrypt unlock: permission denied: system error: could not insert key into the keyring

It persisted with password and keyfile method.

fscryptctl insert_key does not persist during switch_root

I would like to encrypt my root partition using fscrypt.
I insert the key in initramfs:

fscryptctl insert_key < /tmp/key.data

then mount my rootfs:

mount -t ubifs ubi0:rootfs /mnt

Finally excuting switch_root:

exec switch_root /mnt /sbin/init

The last command fails since the key does not survive the switch_root probably because /proc & /sys are remounted.

Is there anyway to persist the key during this stage ?

Execution

How to run this code exactly, any help please with some instruction

In fscryptctl user space, after removing the key from key ring, the encrypted directories file names continues to be in clear form.

I am using fscrypt kernel space and fscryptctl at user space to make use of the fscrypt encryption tool.
I have encrypted a directory using add_key -> set_policy->created valid data files under the encryption directory.
Before I remove the key, I have confirmed the open files of the directory is closed properly.
Now, if I remove the key from the key ring, the file names of the encrypted directory continues to be in clear form. The file names are change to encrypted form only if I reboot the system or if I dorp the cache/inode using the system echo 2 >/proc/sys/vm/drop_caches.

fscryptctl version: v1.0.0-6-gab54426

Is there a way to handle this neatly and make the file names as encrypted name upon removing the key from kernel key ring? I do not wish to drop the entire system caches
I have tried this on both Ubuntu machine and my customised embedded system as well. The observation is same.

Release time?

Hello @josephlr, I'd like to package fscryptctl for Debian, but normally only released (tagged) versions are packaged. Do you plan to tag a release anytime soon? Thank you.

remove policy

How can I remove policy or re-set policy when one of policy already set?

fscryptctl compatibilty with mkfs.ubifs

hello I'm using fscryptctl v1.0.0 with an UBIFS on a RAW Nand Flash with a 5.10 kernel and mtd-utils 2.1.4:

  1. Create an encrypted ubifs using mkfs.ubifs as follow:
# dd if=/dev/urandom of=key.data count=64 bs=1
# mkdir -p rootfs/somedir
# echo "somedata" > rootfs/somedir/somefile
# mkfs.ubifs -m 4096 -e 253952 -c 4068  --cipher AES-256-XTS --key key.data -r rootfs  rootfs.ubifs                                                                    
mkfs.ubifs: fscrypt master key descriptor: 0x0dbfd8a3ba6c7e60 
  1. Update ubifs volume:
# ubiupdatevol /dev/ubi0_2 -t                                                                                       
# ubiupdatevol /dev/ubi0_2 rootfs.ubifs  
  1. Mount volume:
# mount -t ubifs  /dev/ubi0_2 /mnt 
# ls -l /mnt/                                                                                                       
drwxr-xr-x    2 root     root           232 Oct 29 17:44 9r,9Ko40w3Qg8kg9l3457CjT40nHIhWD 
  1. Decrypt volume:
# fscryptctl add_key /mnt < key.data                                                                                
77120bc70608b4aec343dc803a9a695c                                                                                                            
# ls -l /mnt/                                                                                                       
drwxr-xr-x    2 root     root           232 Oct 29 17:44 9r,9Ko40w3Qg8kg9l3457CjT40nHIhWD  

It doesn't look that the decryption is working !!

Incorrect file name

Hi,

I am using fscrypt with UBIFS and kernel 4.13 on an ARM CortexA7 monocore.

It appears that with a 32 padding, the filenames are incorrect when the names size is in between 16 and 31 inclusive. The error occurs on different ranges when the padding is different. Longer names or shorter names work fine.

I added logs in fname.c and it clearly indicates that the decoded name in fname_decrypt is padded to 32 when the expected decoded size is in between 16 and 31 while it is correct with other sizes.

On a Linux 4.10 (64bits laptop) I dont see the issue when running a ubi/ubifs/fscrypt in nandsim.

FAILED test.py::test_set_get_policy_aes_256_xts - Failed: DID NOT RAISE <class 'OSError'>

We starting to get such error on our tests:

root@i586:~/RPM/BUILD/fscryptctl-1.0.0# make test-all
make test-setup
make[1]: Entering directory '/usr/src/RPM/BUILD/fscryptctl-1.0.0'
if mountpoint -q "/tmp/fscryptctl-test-dir"; then \
        sudo umount "/tmp/fscryptctl-test-dir"; \
fi
0.00user 0.00system 0:00.01elapsed 10%CPU (0avgtext+0avgdata 2060maxresident)k
0inputs+8outputs (0major+107minor)pagefaults 0swaps
rm -rf "/tmp/fscryptctl-test-dir"
rm -f "/tmp/fscryptctl-test-image"
dd if=/dev/zero of="/tmp/fscryptctl-test-image" bs=1M count=32
32+0 records in
32+0 records out
33554432 bytes (34 MB, 32 MiB) copied, 0.00999589 s, 3.4 GB/s
mkfs.ext4 -b 4096 -O encrypt -F "/tmp/fscryptctl-test-image"
mke2fs 1.46.4 (18-Aug-2021)
Discarding device blocks: done
Creating filesystem with 8192 4k blocks and 8192 inodes

Allocating group tables: done
Writing inode tables: done
Creating journal (1024 blocks): done
Writing superblocks and filesystem accounting information: done

mkdir -p "/tmp/fscryptctl-test-dir"
sudo mount -o rw,loop "/tmp/fscryptctl-test-image" "/tmp/fscryptctl-test-dir"
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 2400maxresident)k
706inputs+8outputs (0major+186minor)pagefaults 0swaps
sudo sh -c 'chown $SUDO_UID:$SUDO_GID "/tmp/fscryptctl-test-dir"'
0.00user 0.00system 0:00.00elapsed 50%CPU (0avgtext+0avgdata 2328maxresident)k
0inputs+0outputs (0major+155minor)pagefaults 0swaps

/tmp/fscryptctl-test-dir is now set up.
make[1]: Leaving directory '/usr/src/RPM/BUILD/fscryptctl-1.0.0'
make test
make[1]: Entering directory '/usr/src/RPM/BUILD/fscryptctl-1.0.0'
TEST_DIR="/tmp/fscryptctl-test-dir" PATH="$PWD:$PATH" \
         ENABLE_VALGRIND="" \
         python3 -m pytest test.py -s -q
............F......................
========================================================================== FAILURES ===========================================================================
_______________________________________________________________ test_set_get_policy_aes_256_xts _______________________________________________________________

directory = '/tmp/fscryptctl-test-dir/test'

    def test_set_get_policy_aes_256_xts(directory):
        """Tests getting and setting an encryption policy that uses AES-256-XTS
        contents encryption and AES-256-CTS filenames encryption.  (Note that this
        is also the default setting, but this test tries it explicitly.)"""
        prepare_encrypted_dir(directory, "--contents=AES-256-XTS",
                              "--filenames=AES-256-CTS")
        check_policy(directory, contents="AES-256-XTS", filenames="AES-256-CTS")
        # AES-256-XTS expects a 64-byte key.  Shorter keys shouldn't work.
        for key in [TEST_KEY_16B, TEST_KEY_32B]:
            with pytest.raises(OSError):
>               prepare_encrypted_dir(directory, "--contents=AES-256-XTS",
                                      "--filenames=AES-256-CTS", key=key)
E               Failed: DID NOT RAISE <class 'OSError'>

test.py:319: Failed
=================================================================== short test summary info ===================================================================
FAILED test.py::test_set_get_policy_aes_256_xts - Failed: DID NOT RAISE <class 'OSError'>
1 failed, 34 passed in 0.49s
make[1]: *** [Makefile:93: test] Error 1
make[1]: Leaving directory '/usr/src/RPM/BUILD/fscryptctl-1.0.0'
make: *** [Makefile:119: test-all] Error 2

UBIFS symlink encryption bug

hello I'm using fscryptctl v1.0.0 with an UBIFS on a RAW Nand Flash with a 5.10 kernel version as follow:

  1. wipe out ubi0_1 volume:
# ubiupdatevol /dev/ubi0_1 -t  
  1. mount volume:
# mount -t ubifs /dev/ubi0_1 /mnt/                                                                              
  1. create an encryption key:
# dd if=/dev/urandom of=key.data count=64 bs=1 
  1. encrypt the volume:
# fscryptctl add_key /mnt/ < key.data                                                                                                                                                                                            
# fscryptctl set_policy 5f7c86c2c8ff2b4997282355429c65ac /mnt/ 
  1. populate /mnt:
# cd /mnt                                                                                                                       
# mkdir -p bin usr/bin                                                                                                          
# echo "something" > bin/somefile                                                                                               
# ln -s bin/somefile bin/file-symlink                                                                                           
# ls -l bin/                                                                                            
lrwxrwxrwx    1 root     root        34 Oct 29 10:57 file-symlink -> bin/somefile                                              
-rw-r--r--    1 root     root            10 Oct 29 10:57 somefile                                                                                                                       
# cd -                                                                                                                          
# umount /mnt/
  1. remount
# mount -t ubifs /dev/ubi0_1 /mnt/
# ls -l /mnt/                                                                                              
drwxr-xr-x    2 root     root           352 Oct 29 10:57 G9,XDkQsQuNHrLit3x0YkbRc9ZigDrvREyWw+bwZ4I8LuNMi35u,aB                    
drwxr-xr-x    3 root     root           256 Oct 29 10:57 ehRYWcZe9dFYscuAMJdbTFUyfDLdBBdnsqoWpNgi+2qmCH7rczEk3C
  1. enable the decryption:
# fscryptctl add_key /mnt/ < key.data                                                                      
5f7c86c2c8ff2b4997282355429c65ac
  1. check the files:
# cat /mnt/bin/somefile                                                                                    
something

# ls -l /mnt/bin/                                                                                          
lrwxrwxrwx    1 root     root         34 Oct 29 10:57 file-symlink -> 4???i?.N??????U?????U????:z?5"??                          
-rw-r--r--    1 root     root            10 Oct 29 10:57 somefile

Files are ok, symlinks are broken !

is this a known issue ?

Usage example incomplete

I found the usage example in README.md very helpful in illustrating the usage. But when I came to umount I was lost, as there wasn't an earlier corresponding mount nor an explanation of its role. I am guessing this is a workaround for doing drop_cache without privilege escalation. What would the earlier missing mount command look like in the given usage example?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.