📜 ⬆️ ⬇️

Comparative testing of crypto containers and encrypted file systems

A week ago, a nontrivial task was drawn to determine the possibilities of using encrypted containers or file systems on rendered untrusted hosting.

Main tasks:
- Ability to backup data in any form for disaster recovery.
- Exclusion of access to this data by unauthorized persons.
- The inability to access files during an emergency shutdown of the server and boot from external media.
- Transparent users with files and any content located on the server.
- OS FreeBSD 7.2 and maximum scope for imagination in the choice of implementation options.
After a certain amount of time, the following test configuration has emerged:
GELI - GEOM_ELI (built-in encryption subsystem in FreeBSD using the crypto (9) framework (hardware and software encryption))
GBDE - GEOM_BDE [Geom Based Disk Encryption] (embedded encryption subsystem in FreeBSD)
TrueCrypt - Ported version of TrueCrypt 6.1a (uses fuse)
cryptofs - cryptofs using fuse
encfs - fuse encfs

UPD: A speed comparison table for clean and encrypted file systems.

')
Let's start with the classification of used encryption systems.
The first two systems use any device defined through GEOM. This can be a physical drive (da0), a partition (da0s1), a slice (da0s1a), as well as any other synthetic device created, say, through mdconfig or ggatel .
mdconfig is a utility that uses geom_md and generates a virtual device from the RAM you have, or a file on a disk or any other media.
ggatel is a utility that allows you to transfer any device or file that cannot be assigned to a GEOM class in this class.

TrueCrypt is an autonomous cross-platform encryption system for cryptocontainers.

fuse_cryptofs - password data encryption subsystem on disk that encrypts file names and their contents using algorithms specified in the configuration file.
fuse_encfs - a subsystem of password-key disk encryption encrypting file names and their contents with control of changes in files.

All tests were conducted on a system having the following characteristics: P4 2.8HT / 1GB RAM / 40GB IDE /.
Dd and bonnie were used to estimate the speed of work.
Temporary files of cryptocontainers and file directories were placed on the / var section.
# dmesg | grep ad0 <br/>ad0: 38166MB <Seagate ST340014A 3 . 06 > at ata0-master UDMA100<br/> # mount | grep var <br/>/dev/ad0s1g on /var (ufs, local , soft-updates) <br/>

First of all, it was necessary to estimate the speed of linear recording to the hard disk we can get at the peak.
<br/>testcrypt # /usr/bin/time dd if=/dev/random of=testfile.dump bs=1m count=4096 <br/> 4096 + 0 records in <br/> 4096 + 0 records out<br/> 4294967296 bytes transferred in 151 . 801076 secs ( 28293392 bytes/sec)<br/> 151 . 82 real 0 . 00 user 132 . 96 sys <br/>

Those. as much as we can count on about 27 megabytes / s when streaming.
To analyze the speed of the GEOM providers, a 4GB file was created, which in turn was connected to mdconfig and ggatel (the sector size was specified in 4Kb). Further in the text, I will try to eliminate as much as possible the overhead information from the code inserts.
We checked the linear write speed through the GEOM providers.
testcrypt # mdconfig -a -t vnode -f /var/test/testfile.dump -S 4096 -u 0 <br/>testcrypt # /usr/bin/time dd if=/dev/random of=/dev/md0 bs=1m <br/> 4294967296 bytes transferred in 306 . 514082 secs ( 14012300 bytes/sec)<br/> 306 . 55 real 0 . 02 user 120 . 03 sys<br/>testcrypt # mdconfig -d -u 0 <br/> <br/>testcrypt # ggatel create -s 4096 -u 0 /var/test/testfile.dump <br/>testcrypt # /usr/bin/time dd if=/dev/random of=/dev/ggate0 bs=1m <br/> 4294967296 bytes transferred in 319 . 859650 secs ( 13427662 bytes/sec)<br/> 319 . 91 real 0 . 02 user 133 . 34 sys<br/>testcrypt # ggatel destroy -u 0 <br/>

As can be seen from the tests, the write speed dropped almost 2 times and the ggate provider was slightly slower than md , but in principle this is not particularly critical, although ggate loads the system a little more than md .

The next step is to test the load capacity for file systems working through GEOM providers. The first was tested md .

testcrypt # mdconfig -a -t vnode -f /var/test/testfile.dump -S 4096 -u 0 <br/>testcrypt # newfs /dev/md0 <br/>/dev/md0: 4096 .0MB ( 8388608 sectors) block size 16384 , fragment size 4096 <br/> using 13 cylinder groups of 336 .98MB, 21567 blks, 21568 inodes.<br/>super-block backups ( for fsck -b #) at: <br/> 160 , 690304 , 1380448 , 2070592 , 2760736 , 3450880 , 4141024 , 4831168 , 5521312 ,<br/> 6211456 , 6901600 , 7591744 , 8281888 <br/>testcrypt # mount /dev/md0 /mnt <br/>testcrypt # /usr/bin/time dd if=/dev/random of=/mnt/testfile.dump bs=1m <br/> 4220518400 bytes transferred in 235 . 262614 secs ( 17939605 bytes/sec)<br/> 235 . 28 real 0 . 03 user 136 . 49 sys<br/>testcrypt # umount /mnt <br/>testcrypt # mdconfig -d -u 0 <br/>

As we can see, the speed of working with files has increased and amounted to 17.1 megabytes / sec.
The second was ggate tested.
<br/>testcrypt # ggatel create -s 4096 -u 0 /var/test/testfile.dump <br/>testcrypt # newfs /dev/ggate0 <br/>/dev/ggate0: 4096 .0MB ( 8388608 sectors) block size 16384 , fragment size 4096 <br/> using 13 cylinder groups of 336 .98MB, 21567 blks, 21568 inodes.<br/>super-block backups ( for fsck -b #) at: <br/> 160 , 690304 , 1380448 , 2070592 , 2760736 , 3450880 , 4141024 , 4831168 , 5521312 , 6211456 , 6901600 , 7591744 , 8281888 <br/>testcrypt # mount /dev/ggate0 /mnt <br/>testcrypt # /usr/bin/time dd if=/dev/random of=/mnt/testfile.dump bs=1m <br/> 4220518400 bytes transferred in 228 . 256445 secs ( 18490249 bytes/sec)<br/> 228 . 29 real 0 . 00 user 137 . 80 sys<br/>testcrypt # umount /mnt <br/>testcrypt # ggatel destroy -u 0 <br/>

Other things being equal, ggate showed an increase in speed compared to md - 17.6 megabytes / sec.
It is time to test a bunch of crypto and geom providers. To do this, create a random key that will be used in further tests.
testcrypt # dd if=/dev/random of=/var/test/my.key bs=4k count=1

Initialize the cryptocontainer geli
testcrypt # mdconfig -a -t vnode -f /var/test/testfile.dump -S 4096 -u 0 <br/>testcrypt # /usr/bin/time geli init -s 4096 -K my.key /dev/md0 <br/>Enter new passphrase:<br/>Reenter new passphrase:<br/> 13 . 34 real 9 . 61 user 0 . 00 sys<br/>

As can be seen from the time output, geli init takes a long time to figure out a bunch of encryption key with a password and write it to disk.
testcrypt # geli list <br/>Geom name: md0.eli<br/>EncryptionAlgorithm: AES-CBC<br/>KeyLength: 128 <br/>Crypto: software<br/>UsedKey: 0 <br/>Flags: NONE<br/>Providers:<br/> 1 . Name: md0.eli<br/> Mediasize: 4294963200 ( 4 .0G)<br/> Sectorsize: 4096 <br/> Mode: r0w0e0<br/>Consumers:<br/> 1 . Name: md0<br/> Mediasize: 4294967296 ( 4 .0G)<br/> Sectorsize: 4096 <br/> Mode: r1w1e1<br/>

A cryptocontainer created and formed a new device with the suffix .eli , which can be used as a regular block device. Mark it, create partitions and file systems.
Create a new file system on the cryptocontainer and test the speed.
testcrypt # newfs /dev/md0.eli <br/>/dev/md0.eli: 4096 .0MB ( 8388600 sectors) block size 16384 , fragment size 4096 <br/> using 13 cylinder groups of 336 .98MB, 21567 blks, 21568 inodes.<br/>super-block backups ( for fsck -b #) at: <br/> 160 , 690304 , 1380448 , 2070592 , 2760736 , 3450880 , 4141024 , 4831168 , 5521312 , 6211456 , 6901600 , 7591744 , 8281888 <br/>testcrypt # /usr/bin/time dd if=/dev/random of=/mnt/testfile.dump bs=1m <br/> 4220518400 bytes transferred in 277 . 940331 secs ( 15184980 bytes/sec)<br/> 277 . 96 real 0 . 03 user 145 . 50 sys<br/>

As we can see, the speed dropped to 14.5 megabytes / sec. I’ll skip the ggate + geli bundle markup and speed test since it’s identical to the geli + md block. Since we cannot estimate the speed of work only by the write cycle, we run bonnie for additional analysis.
Summary bonnie results on all bundles will be given at the end of the article.
testcrypt # bonnie -s 1024 <br/> File './Bonnie.1145' , size: 1073741824 <br/>
Sequential outputSequential inputRandom
Per charBlockReritePer charBlockSeeks
MachineMBK / sec% CPUK / sec% CPUK / sec% CPUK / sec% CPUK / sec% CPU/ sec% CPU
geli + md10241717825.7183248.456842.21449215.1151852.3139.80.7
geli + ggate10241385520.6120185.263882.71902121.8224734.2136.50.7

As we can see, ggate works slower on write cycles, but it works much faster on read cycles. Perhaps this is due to write buffering and various methods of flushing buffers to md and ggate . If you try to enter the wrong key file or password, then geli does not create a device to access the file system, and since the container file inside resembles the contents of / dev / random , it is simply impossible to decrypt it. Neither file, nor entirely. One of the advantages of geli is the ability to use several encryption keys, say a master key and a user key.

Initialize the GBDE container.
testcrypt # mdconfig -a -t vnode -f /var/test/testfile.dump -S 4096 -u 0 <br/>testcrypt # gbde init /dev/md0 -i -K my.key -L /var/tmp/md0.lock -P testcrypt <br/>testcrypt # ll /var/tmp/md* <br/>md0.lock<br/>testcrypt # gbde attach /dev/md0 -l /var/tmp/md0.lock -k my.key -p testcrypt <br/>testcrypt # ll /dev/md* <br/>crw-r----- 1 root operator 0 , 98 Apr 21 13 : 25 /dev/md0<br/>crw-r----- 1 root operator 0 , 100 Apr 21 10 : 15 /dev/md0.bde<br/>crw------- 1 root wheel 0 , 78 Apr 21 10 : 15 /dev/mdctl

gbde when creating a device uses a lock file in which the current keys are located to initialize the cryptocontainer. The system of initialization of the cryptocontainer does not have a reverse data recovery procedure, so if you have forgotten the password or lost the lock file, then you have lost all the data that was in the cryptocontainer. After initialization of the cryptocontainer, gbde creates a device with the suffix .bde which can be handled in the same way as c .eli .
Detailed guidance on the use of both systems can be found here . Run bonnie to test the gbde + md and gbde + ggate bundles .
testcrypt # bonnie -s 1024 <br/> File './Bonnie.1145' , size: 1073741824 <br/>
Sequential outputSequential inputRandom
Per charBlockReritePer charBlockSeeks
MachineMBK / sec% CPUK / sec% CPUK / sec% CPUK / sec% CPUK / sec% CPU/ sec% CPU
gbde + md102444365.343491.726951.21292013.7170782.9130.10.7
gbde + ggate102419712.219700.814800.61381215.2172063.0120.30.6

The gbde subsystem showed rather poor performance values, although, as can be seen from the table, the processor time was practically not used in contrast to geli . What is the reason for this I did not find out to the end.

Having found the unofficial TrueCrypt 6.1a port on FreeBSD, it was decided to try it out.
TrueCrypt should work on FreeBSD through fuse, but in fact it turned out to be not quite like that.
Attempting to compile this port resulted in xorg, glib, gtk, gnome, wxWidgets and a bunch of other junk being dragged into the system. A detailed analysis revealed that the GUI interface is based on wxWidgets. The GUI was unnecessary for us and therefore, through trial and error, magic sequences were found for gmake who did assemble TrueCrypt on our test system.
gmake NOGUI= 1 WX_ROOT=/usr/ local /tmp/wx wxbuild<br/> gmake NOGUI= 1 WXSTATIC= 1 PKCS11_INC=/usr/ local /include/pkcs11/<br/>

TrueCrypt started cheerfully saying:
testcrypt # truecrypt <br/> 13 : 35 : 34 : Error: Cannot convert from the charset 'US-ASCII' !

Swearing related to the fact that TrueCrypt was unable to convert help from LANG = C to en_US.UTF-8 , which is hard-wired in the source code.
testcrypt # /usr/bin/time truecrypt -c --filesystem=ufs -k /var/test/my.key --random-source=/dev/random /var/test/truecrypt.dump /mnt <br/>Volume type :<br/> 1 ) Normal<br/> 2 ) Hidden<br/> Select [ 1 ]:<br/> <br/>Enter volume size (sizeK/size[M]/sizeG): 4G<br/> <br/>Encryption algorithm:<br/> 1 ) AES<br/> 2 ) Serpent<br/> 3 ) Twofish<br/> 4 ) AES-Twofish<br/> 5 ) AES-Twofish-Serpent<br/> 6 ) Serpent-AES<br/> 7 ) Serpent-Twofish-AES<br/> 8 ) Twofish-Serpent<br/> Select [ 1 ]:<br/> <br/> Hash algorithm:<br/> 1 ) RIPEMD- 160 <br/> 2 ) SHA- 512 <br/> 3 ) Whirlpool<br/> Select [ 1 ]:<br/> <br/>Filesystem:<br/> 1 ) FAT<br/> 2 ) None<br/> Select [ 1 ]:<br/> <br/>Enter password:<br/>WARNING: Short passwords are easy to crack using brute force techniques!<br/>We recommend choosing a password consisting of more than 20 characters. Are you sure you want to use a short password? (y=Yes/n=No) [No]: y<br/>Re-enter password:<br/> Done : 100 , 000 % Speed: 31 MB/s Left: 0 s<br/>The TrueCrypt volume has been successfully created.<br/> 139 , 42 real 204 , 75 user 13 , 80 sys

The created partition was mounted without any problems.
testcrypt # truecrypt -k /var/test/my.key --mount /var/test/truecrypt.dump /mnt <br/>Enter password for /var/ test /truecrypt.dump:<br/>Protect hidden volume? (y=Yes/n=No) [No]:<br/> <br/>testcrypt # mount <br/>...<br/>/dev/fuse0 on /var/tmp/.truecrypt_aux_mnt1 (fusefs, local , synchronous)<br/>/dev/md0 on /mnt (msdosfs, local )<br/> <br/>testcrypt # mdconfig -l -v <br/>md0 vnode 4 .0G /var/tmp/.truecrypt_aux_mnt1/volume<br/>testcrypt # ll /var/tmp/.truecrypt_aux_mnt1/ <br/>total 0 <br/>-rw------- 1 root wheel 1522 21 15 : 51 control<br/>-rw------- 1 root wheel 4294705152 21 15 : 51 volume

But we suffered a cruel disappointment. Contrary to the expected use of fusefs, TrueCrypt began to use the translation of its endpoint file via md . In this way, we got another superfluous junction in the cryptocontainer transformation. The disappointment became even greater when, when we tried to write data to the mounted TrueCrypt Volume, we received a deadlock after the write buffers for vfs were exhausted. Dancing with a tambourine around TrueCrypt, vfs settings and much more did not lead to anything and we abandoned the idea of ​​normal testing TrueCrypt. Unfortunately, the current assembly of TrueCrypt can create only two file systems, regardless of OS, FAT and NTFS, it is hard-coded in source codes. Creating a file system on an unmounted Volume solves the problem of using msdosfs, but does not solve the problem of deadlock.

Since we have run out of testing crypto containers, we tried to implement some kind of backup scheme for these containers. In general, we were expected by a no less sad circumstance than the problems with TrueCrypt. We tried to make a snapshot on the file system on which the mounted cryptocontainer is located and after extracting the container file from there to look at its contents. But then they caught the problem. With active file operations with a cryptocontainer, an attempt to make a snapshot results in a deadlock. The system seems to be alive, but at the same time it is impossible to access the mounted container, and subsequently access to all system partitions dies: (
In the absence of operations with a cryptocontainer, the snapshot occurs normally, but the probability of a subsequent deadlock is also not excluded. And with md devices, the problem manifests itself earlier than with ggate . After the deadlock and subsequent forced dirty (reboot -qn) reload, the cryptocontainer must first be checked via fsck, otherwise it will not be mounted. The pulled-out crypto-container from snapshot is turned out to be broken, with the missing file system and without our data. Which is very, very sad. Well, okay, you can not use online backup, then 100% can be used offline backup. On this with cryptocontainers and stop.

The second part of the test is using fusefs.
Cryptofs and encfs were chosen for testing. The difference between the systems is small and the main difference is that encfs supports paranoid security checking the integrity of files.
testcrypt # cryptofs -r /var/crypto/ <br/>Enter password:<br/>testcrypt # mount_fusefs /dev/fuse0 /mnt <br/>testcrypt # df -h | grep mnt <br/>Filesystem Size Used Avail Capacity Mounted on<br/>/dev/fuse0 18G 5 .1G 12G 30 % /mnt

cryptofs creates a gateway that encrypts the data passing through it with a password specified by the user using a regular file system on the machine. For the system to work, you need to place in the directory that will be home, the file with the settings .cryptofs
# See README for details on each parameter <br/> <br/>[CryptoFS]<br/>cipher=AES256<br/>md=MD5<br/>blocksize=2048<br/>salts=256

Settings is a list of encryption algorithms that will be used in the work. Unfortunately, the location of the file can not be changed :(
testcrypt # cp /etc/defaults/* /mnt <br/>testcrypt # ls /mnt/ <br/>bluetooth.device.conf devfs.rules pccard.conf periodic.conf rc.conf<br/>testcrypt # ls /var/crypto/ <br/>.cryptofs JuSxlpX8BzEtClI= MuKkkZS2WycuAUc= IO2ylZK9GjApQUWQR697gAD3Valf MOLpk4m8Ew== MuS1mYm2HCdvDE6bVw==

The system is very easy to use, but it has one drawback. If you accidentally make a mistake with a letter or number when entering a password, the system will encrypt the data with exactly the password you typed. Chances are that you will not notice this immediately, and users will already upload files that will be encrypted with a new password. The file system after entering the wrong password looks like this.
testcrypt # cryptofs -r /var/crypto <br/>Enter password:<br/>testcrypt # mount_fusefs /dev/fuse0 /mnt <br/>testcrypt # ls /mnt/ <br/>i+???F9&??tg? i-???F~&T?} k-???L6 {"???M?1SA?l?????y??? }+????"0W?h<br/> <br/>

The encfs is deprived of this problem, but it already has much broader encryption settings, and also creates a unique key in the configuration file. Using this key, the encfs determines the correctness of entering a password, the correctness of file encryption, and also determines which files to show or not to show (meaning it is encrypted with this particular key). If you have forgotten your password, you can safely delete all data, they are not subject to recovery. The work process is as follows.
testcrypt # encfs /var/crypto /mnt <br/>Creating new encrypted volume.<br/>Please choose from one of the following options:<br/> enter "x" for expert configuration mode,<br/> enter "p" for pre-configured paranoia mode,<br/> anything else , or an empty line will select standard mode.<br/>?><br/> <br/>Standard configuration selected.<br/> <br/>Configuration finished. The filesystem to be created has<br/>the following properties:<br/>Filesystem cipher: "ssl/aes" , version 2 : 1 : 1 <br/>Filename encoding: "nameio/block" , version 3 : 0 : 1 <br/>Key Size: 192 bits<br/>Block Size: 1024 bytes<br/>Each file contains 8 byte header with unique IV data.<br/>Filenames encoded using IV chaining mode.<br/> <br/>Now you will need to enter a password for your filesystem.<br/>You will need to remember this password, as there is absolutely<br/>no recovery mechanism. However, the password can be changed<br/>later using encfsctl.<br/> <br/>New Encfs Password:<br/>Verify Encfs Password:<br/>testcrypt # mount | grep mnt <br/>/dev/fuse0 on /mnt (fusefs, local , synchronous)<br/>testcrypt # cp /etc/defaults/* /mnt <br/>testcrypt # ls /mnt <br/>bluetooth.device.conf devfs.rules pccard.conf periodic.conf rc.conf<br/> <br/>testcrypt # ls /var/crypto/ <br/>.cryptofs Nq2IBppvuCpNNHuYS1k5dn-q wiNUtxqXvJqCLs3s-u1qwJrA<br/>.encfs6.xml gNsHASsB,5N2H1TZlWTJjldR<br/>B7rx58O9WjTGrjeTaiFXjREamAQzW7u3oK3NOK1KuN4Rp- sTZaWdYP4B-oXrW1d1COMMNV


Backing up data can be done using the usual removal of snapshots from the section, as well as direct copying of files to the desired location, the main thing is to keep the keys for the possibility of reverse decryption;)

Conclusions: All methods of data encryption on disks investigated in this article have the right to use in everyday life. Depending on the encryption systems used, you can get the functionality you need in a short period of time. Of the systems I test, I would still choose geli and encfs . The first system is very attractive from the point of view of using hardware encryption modules, the use of which will not waste processor time on data encryption, as well as the ability to encrypt entire partitions. The second system is interesting for the integrity control modes of encrypted files and the ability to change a variety of parameters. With all due respect to encfs, I would like to note the dependence of the system on several external libraries that you have to carry with you. Again, geli may have problems with backing up large volumes of arrays. Well, in general, that's all. Thank you for taking the time to read this material.

Comparative table of bonnie tests for all systems.
Sequential outputSequential inputRandom
Per charBlockReritePer charBlockSeeks
MachineMBK / sec% CPUK / sec% CPUK / sec% CPUK / sec% CPUK / sec% CPU/ sec% CPU
geli + md10241717825.7183248.456842.21449215.1151852.3139.80.7
geli + ggate10241385520.6120185.263882.71902121.8224734.2136.50.7
gbde + md102444365.343491.726951.21292013.7170782.9130.10.7
gbde + ggate102419712.219700.814800.61381215.2172063.0120.30.6
fusefs + cryptofs10241720723.82101510.764943.51620217.1168293.270.11.2
fusefs + encfs10241907325.32325011.476763.91640218.4191873.570.31.2


UPD: A table comparing the speeds of clean file system and encrypted. With softupdates turned on and off.
Sequential outputSequential inputRandom
Per charBlockReritePer charBlockSeeks
MachineMBK / sec% CPUK / sec% CPUK / sec% CPUK / sec% CPUK / sec% CPU/ sec% CPU
fusefs + cryptofs10241720723.82101510.764943.51620217.1168293.270.11.2
fusefs + encfs10241907325.32325011.476763.91640218.4191873.570.31.2
cleanfs + su_on40963374533.53251712.8106814.43491135.9390357.780.10.5
cleanfs + su_off40963491833.43510812.9111884.53726838.3395137.684.60.5


(C) Aborche 2009

Source: https://habr.com/ru/post/57884/


All Articles