Reboot's personal page
Menu
Index

English:
CryptoFS
BitTorrent
NetDraw
Contributions

German:
Anime

Contact
 
 
freshmeat.net

CryptoFS

B.Sc. Christoph Hohmann


1. What's CryptoFS

CryptoFS is a encrypted filesystem for Filesystem in Userspace (FUSE) and the Linux Userland FileSystem (LUFS). Visit http://fuse.sourceforge.net/ for more information on FUSE or http://lufs.sourceforge.net/lufs/ for more information on LUFS.

CryptoFS will use a normal directory to store files encrypted. The mountpoint will contain the decrypted files. Every file stored in this mountpoint will be written encrypted (data and filename) to the directory that was mounted. If you unmount the directory the encrypted data can only be access by mounting the directory with the correct key again. Like other FUSE/LUFS filesystems it does not need root access or any complicated setup like creating a filesystem on a encrypted disk using the loop device.

CryptoFS can be build for FUSE and LUFS. When you build for FUSE you get a program to mount the filesystem. For LUFS a shared library will be built that can be used by LUFS's lufsd. Both methods can use the same encrypted directory.


2. Why CryptoFS?

I first used the evfs kernel patch that does nearly the same thing as CryptoFS. But it seems that it has been abandoned. The last patch was available for kernel 2.4.20 and has not been updated for newer kernels since then. When I found LUFS I thought I could be a good base for a crypto filesystem that works like evfs and allows a user to mount any directory as an encrypted storage without having root access and creating a crypto filesystem using the loop device. So when I found no other program that offers this posibilities I started to write my own filesystem for LUFS. Unfortunately LUFS seems to be dead too, so CryptoFS can now be build for FUSE too which has already made it into the official Linux kernel package.


3. Requirements

You either need FUSE or LUFS to use CryptoFS. For FUSE you need the FUSE tools, library and kernel module. You also need the FUSE development files to build the FUSE filesystem. See http://fuse.sourceforge.net/ for more information and downloads. If you don't want to build CryptoFS for FUSE you can use the --disable-fuse configure switch. Otherwise it will be build when the development files are found on the system. For LUFS you only have to install the LUFS tools and load the LUFS kernel module. See http://lufs.sourceforge.net/lufs/ on how to do this and downloads for LUFS. If you want to disable building CryptoFS for LUFS you can use the --disable-lufs configure switch. As the LUFS module has no requirements it will be build by default. Installing and setting up LUFS and FUSE will not be covered by this document.

CryptoFS uses Libgcrypt from ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/ (version >= 1.1.44) and GLib from http://www.gtk.org (version >= 2.6). You must have installed these packages correctly before running CryptoFS's "configure" script.

Optionally CryptoFS can use the PIN Entry utility by GnuPG to ask the user for the filesystem's password. If the pinentry program is found on the system CryptoFS will be automatically built with PIN Entry support. Otherwise it will fall back to the old console input method.


4. Usage

First you have to set up the source directory by copying the file cryptofs.conf to <source>/.cryptofs. Where <source> is the directory where you want to store the encryted files. You can adjust the values in the file, but the default should work fine.

For FUSE you have to run cryptofs that should be in an executeable path after "make install". The required options are

     cryptofs --root=<source> <dest> 
<dest> is the directory where the filesystem containing the decrypted files will be mounted.

For LUFS put the shared library into a directory where the system linker can find it (this will usually be done by "make install") or add the directory to the search path by setting the LD_LIBRARY_PATH environment varibale.

After that you can mount the source directory with

     lufsmount cryptofs://<source> <dest> 

You will be asked for the password you want to use for this filesystem. It will be used to generate the cipher key.

After that you should be able to use the <dest> directory like any other directory, but all data will be read and written to the <source> directory in an encrypted form.


5. How does it work?

5.1. The .cryptofs config file

The CryptoFS config file in each encryted directory contains 4 options. These are

cipher

The cipher algorithm used to encrypt files and filenames. This has to be a cipher name known by libgcrypt.

md

The message digest algorithm used to generate the cipher key. This has to be a message digest name known by libgcrypt.

blocksize

An encrypted file can not be randomly accessed like a normal file and CryptoFS always reads and writes blocks of this size.

salts

This is the number of subkeys CryptoFS will generate to encrypt blocks.

NOTE: Before 0.4.0 CryptoFS used a different config file format. The LUFS module can still read this format. The FUSE program only supports the new format. If you want to switch from LUFS to FUSE you have to replace .cryptofs with a file in the new format.


5.2. Encryption

When a filesystem is mounted CryptoFS first generates a key for the requested cipher algorithm (cipher option) using the message digest function (md option). Every algorithm has a specific key size and every message digest function has a specific length of the generated message digest. If the message digest size is smaller then the keysize the message digest will be repeated until the key size is reached.

After they primary key has been generated n (= salts option= subkeys (initialization vectors) will be generated by encrypting 0 bytes with a 0 initialization vector. These will later be used to encrypt blocks with different subkeys to make sure the cipher text will first repeat after (salts * blocksize) bytes (If the same data is encrypted).

When files or links are created or renamed the name will be encoded with the selected cipher, the primary key and the first subkey. The result will then be encoded using a modified Base64 algorithm because the encrypted filename could contain characters that are not allowed by the target filesystem. (The original Base64 algorithm uses '/' for encoding. This is the directory delimiter so it was replaced by '_')

When files are written the data will be encrypted. CryptoFS always has to write full blocks. So if only a part of a block should be written the original block will first be read, decrypted, the part replaced and then the result then written encrypted back to disk. To keep this performant that block size must not be too large. But to make sure the cipher text does not repeat to early, CryptoFS uses salts to encrypt blocks. Every block will be encoded with the (blocknumber module salts)th salt. (NOTE: Linux always reads or writes "pages" of size 4096 bytes, these writes will be forwarded by lufsd to CryptoFS. So if you use a blocksize of 4096 bytes reading the old block before writing can be omitted and writing should be faster)