sha1sum: 55c03bfc83d3b030447f9b6f7a9ddc5dd4f135eb
denyfs-0.1.1.tar.bz2 39Kb (source)
denyfs-0.1.1.ebuild 1Kb (gentoo/funtoo)

I recently came across this news:
http://it.slashdot.org/story/09/08/12/1255241/Encryption-What-Encryption?from=rss

I was expecting it since the first time I dug into steganographic filesystems. This goes back to when I was in university. At that time in UK the RIP Act had been voted in 2000.

From wikipedia:

Especially contentious was Part III of the Act, which requires persons to supply decrypted information (which had been previously encrypted by the owner) and/or the cryptographic key to government representatives. Failure to disclose these items is a criminal offence, with a maximum penalty of two years in jail.

Reading through the post I went back to have a look at denyfs I hosted on tuxfamily that was doing the job so well. I still have that denyfs-cvs.ebuild somewhere I thought. And then I went back to google and saw what had been done since the past few years. Surprisingly only Truecrypt is still supporting this feature. The old and dusty Rubberhose has not moved from an inch I still can’t make it work and deniability filesystems are still not popular. Few know its concept (outside image processing which is lame honestly;) and even fewer actually use this tool in the public domain except paranoid or curious users.

I don’t understand how Truecrypt implements their steganographic feature; it creates a standard Truecrypt volume and using the free space from this same volume it hides data within it says. From a social perspective who would that convince you are not using the steganographic feature? It is too much of a binary concept. You have a steganographic filesystem or not but noone can prove it exists or not so it still sucks because you get prosecuted by part III.

The way I see steganographic filesystems is more nuanced and balanced; a user should be able to have as many passwords as his social deniability scheme requires him to, period.

To create deniability you have to fit the profile that you don’t hold information people want and most of all you gotta prove it. What if now you do provide them data but a convincing flare instead? The purpose of a data flare would be to confuse as to the fact you hold sensitive information. The deniability concept lives by its social application. The system should allow the user to deny as much as he planned to knowing that to deny you have to prove it in the real world. You may hold not valuable information which especially crafted and presented may incline to a plausible and probable deniability. This becomes possible with multiple volumes; and the more volumes the more arguments a user may have.

The idea is to let the software fit the user social scheme and the precious data it hides. A user could create 9 hidden volumes within a single random file each of which would decrypt sensitively increasing data. Depending on the password you provide one of the 9 volumes will open. This scheme would allow a greater ability to adapt on social events and social scenarios may be built and accredited by providing a password that would decrypt a precise volume only.

In theory, the denyfs design should allow an unlimited amount of volumes (given constraints). In practice it is limited to 9 (more will fail – known bug) volumes (with an 80% free space ratio) within a single file or less depending on your password combination (because some hash password combinations will overlap blocks therefore failing during creation, you’ll have to change password of the specific device failure).

denyfs-0.1.1 ships:

  • denyfs – core program
  • dfstouch – will allocate random space for your outer container
  • dfsopen – will open your container and the devices within
  • dfsclose – will close all devices and the container

The ‘/usr/sbin/denyfs’ binary is still available but you don’t have to interact with it anymore for a daily use or if you want to customize stuff then you’d be better wrapping your own scripts around. The good news too is that I made a ‘configure.in’ file and a ‘Makefile.in’; you can use make install’ and ‘make uninstall’ regardless of your package manager. Whatever your Linux distro installing from sources should be easier than using an ebuild or dpkg.

denyfs-0.1.1 requires:

Tutorial:

  1. First create a container in a location of your choice.
  2. aspire 0.1.1 # dfstouch -h
    Usage:
    /usr/sbin/dfstouch [options]

    Options:
    -f, --file [/path/fs] Path to your filesystem
    -c, --count [int] Block iteration (multiple of 512K)
    -h, --help This
    -v, --version Print version

    Example:
    # this creates a 200M file container
    /usr/sbin/dfstouch -f fs -c 400

    aspire 0.1.1 #
    aspire 0.1.1 # dfstouch -f /tmp/fs -c 400
    >>> Creating 204M fs ... OK
    aspire 0.1.1 #

  3. Then open the file and give your secret volume mapping. Assume the stealth volume is the 3rd one. The -m option will create your volume mount points within /mnt/here. The -k option asks to create an Ext2 filesystem an top of the new volumes. Of course -k is required only for the first time.
  4. aspire 0.1.1 # dfsopen -h
    Usage:
    /usr/sbin/dfsopen [options]

    Options:
    -f, --file [/path/fs] Path to your container
    -b, --block [int]K/M Size of a single block
    -c, --count [int] Block iteration (-b X -c = size of file)
    -m, --mount [/path] Path to mountpoint
    -k, --mkfs Initialize the filesystem (run the first time only)
    -h, --help This
    -v, --version Print version

    Example:
    # note the -k option will create a filesystem when first run
    /usr/sbin/dfsopen -f fs -l loop0 -d 1=2,2=2,3=5,4=2,5=6,6=4,7=2,8=3,9=2 -m /mnt/here -k

    # a daily command
    /usr/sbin/dfsopen -f fs -l loop0 -d 1=2,2=2,3=5,4=2,5=6,6=4,7=2,8=3,9=2 -m /mnt/here

    aspire 0.1.1 #
    aspire 0.1.1 # dfsopen -f /tmp/fs -l loop0 -d 1=10,2=3,3=1 -m /mnt/here -k
    >>> Binding to loop0 ... OK
    >>> Mapping cryptsetup block devices ...
    Enter passphrase:
    Enter passphrase:
    Enter passphrase:
    >>> Sizing up block devices ...
    device 1 ...
    Checking device structure ...
    Do you intend to resize? (CTRL-C to abort)
    Enlarging ...
    using empty block 81 becomes block 0 of /dev/mapper/fs1
    using empty block 84 becomes block 1 of /dev/mapper/fs1
    using empty block 5 becomes block 2 of /dev/mapper/fs1
    using empty block 83 becomes block 3 of /dev/mapper/fs1
    using empty block 86 becomes block 4 of /dev/mapper/fs1
    using empty block 95 becomes block 5 of /dev/mapper/fs1
    using empty block 15 becomes block 6 of /dev/mapper/fs1
    using empty block 18 becomes block 7 of /dev/mapper/fs1
    using empty block 64 becomes block 8 of /dev/mapper/fs1
    using empty block 67 becomes block 9 of /dev/mapper/fs1
    device 2 ...
    Checking device structure ...
    Do you intend to resize? (CTRL-C to abort)
    Enlarging ...
    using empty block 4 becomes block 0 of /dev/mapper/fs2
    using empty block 8 becomes block 1 of /dev/mapper/fs2
    device 3 ...
    Checking device structure ...
    Do you intend to resize? (CTRL-C to abort)
    Enlarging ...
    using empty block 90 becomes block 0 of /dev/mapper/fs3
    >>> Mapping to crytpsetup block devices ...
    Checking device structure ...
    Checking device structure ...
    Checking device structure ...
    >>> Creating filesystems ...
    mke2fs 1.41.8 (11-July-2009)
    Étiquette de système de fichiers=
    Type de système d'exploitation : Linux
    Taille de bloc=1024 (log=0)
    Taille de fragment=1024 (log=0)
    5136 i-noeuds, 20480 blocs
    0 blocs (0.00%) réservés pour le super utilisateur
    Premier bloc de données=1
    Nombre maximum de blocs du système de fichiers=20971520
    3 groupes de blocs
    8192 blocs par groupe, 8192 fragments par groupe
    1712 i-noeuds par groupe
    Superblocs de secours stockés sur les blocs :
    8193

    Écriture des tables d'i-noeuds : complété
    Écriture des superblocs et de l'information de comptabilité du système de
    fichiers : complété

    Le système de fichiers sera automatiquement vérifié tous les 20 montages ou
    après 180 jours, selon la première éventualité. Utiliser tune2fs -c ou -i
    pour écraser la valeur.
    mke2fs 1.41.8 (11-July-2009)
    Étiquette de système de fichiers=
    Type de système d'exploitation : Linux
    Taille de bloc=1024 (log=0)
    Taille de fragment=1024 (log=0)
    1024 i-noeuds, 4096 blocs
    0 blocs (0.00%) réservés pour le super utilisateur
    Premier bloc de données=1
    Nombre maximum de blocs du système de fichiers=4194304
    1 groupe de bloc
    8192 blocs par groupe, 8192 fragments par groupe
    1024 i-noeuds par groupe

    Écriture des tables d'i-noeuds : complété
    Écriture des superblocs et de l'information de comptabilité du système de
    fichiers : complété

    Le système de fichiers sera automatiquement vérifié tous les 37 montages ou
    après 180 jours, selon la première éventualité. Utiliser tune2fs -c ou -i
    pour écraser la valeur.
    mke2fs 1.41.8 (11-July-2009)
    Étiquette de système de fichiers=
    Type de système d'exploitation : Linux
    Taille de bloc=1024 (log=0)
    Taille de fragment=1024 (log=0)
    256 i-noeuds, 2048 blocs
    0 blocs (0.00%) réservés pour le super utilisateur
    Premier bloc de données=1
    Nombre maximum de blocs du système de fichiers=2097152
    1 groupe de bloc
    8192 blocs par groupe, 8192 fragments par groupe
    256 i-noeuds par groupe

    Écriture des tables d'i-noeuds : complété
    Écriture des superblocs et de l'information de comptabilité du système de
    fichiers : complété

    Le système de fichiers sera automatiquement vérifié tous les 21 montages ou
    après 180 jours, selon la première éventualité. Utiliser tune2fs -c ou -i
    pour écraser la valeur.
    >>> Mounting filesystems ...
    /mnt/here1 mounted
    /mnt/here2 mounted
    /mnt/here3 mounted
    aspire 0.1.1 #

  5. Check things are as expected. Verify your block table matches your design. The -t option will dump you a view of the space ratio. Dump the block offset per volume using the -o option.
  6. aspire 0.1.1 #
    aspire 0.1.1 # df -h | grep here
    /dev/mapper/fs1_new 20M 172K 20M 1% /mnt/here1
    /dev/mapper/fs2_new 3,9M 29K 3,9M 1% /mnt/here2
    /dev/mapper/fs3_new 2,0M 21K 2,0M 2% /mnt/here3
    aspire 0.1.1 #
    aspire 0.1.1 # mount | grep here
    /dev/mapper/fs1_new on /mnt/here1 type ext2 (rw)
    /dev/mapper/fs2_new on /mnt/here2 type ext2 (rw)
    /dev/mapper/fs3_new on /mnt/here3 type ext2 (rw)
    aspire 0.1.1 #
    aspire 0.1.1 # tree -h /mnt/here?
    /mnt/here1
    `-- [ 12K] lost+found
    /mnt/here2
    `-- [ 12K] lost+found
    /mnt/here3
    `-- [ 12K] lost+found

    3 directories, 0 files
    aspire 0.1.1 #
    aspire 0.1.1 # denyfs -h
    Usage:
    denyfs [option]

    Where [option] is one of the following:
    -t, --table [loop]? display devices block table
    -l, --list-freeblocks [loop]? list free blocks
    -o, --offset [cryptsetup device] print offsets of blocks of a single device
    -s, --setsize [int1],[int2] [loop]? set size of device nb [int1] with [int2] block
    -d, --dmsetup [new device] dmsetup device mount
    -v, --version version
    -h, --help this.

    Example:
    denyfs -o /dev/mapper/fs1
    denyfs -t /dev/mapper/fs?
    denyfs -s 1,12 /dev/mapper/fs?
    denyfs -s 2,2 /dev/mapper/fs?
    denyfs -l /dev/mapper/fs?
    denyfs -d fs1_new /dev/mapper/fs1

    aspire 0.1.1 #
    aspire 0.1.1 # denyfs -t /dev/mapper/fs?
    Checking device structure ...
    Nb of blocks Device Device nb Size
    + 10 /dev/mapper/fs1 1 20Mb
    + 2 /dev/mapper/fs2 2 4Mb
    + 1 /dev/mapper/fs3 3 2Mb
    + 86 < -- Total nb of free blocks
    -----------
    = 99 <-- Total nb of blocks
    space ratio: 86% free
    aspire 0.1.1 #
    aspire 0.1.1 # denyfs -o /dev/mapper/fs1
    Checking device structure ...
    0 4096 linear /dev/mapper/fs1 331882
    4096 4096 linear /dev/mapper/fs1 344170
    8192 4096 linear /dev/mapper/fs1 20586
    12288 4096 linear /dev/mapper/fs1 340074
    16384 4096 linear /dev/mapper/fs1 352362
    20480 4096 linear /dev/mapper/fs1 389226
    24576 4096 linear /dev/mapper/fs1 61546
    28672 4096 linear /dev/mapper/fs1 73834
    32768 4096 linear /dev/mapper/fs1 262250
    36864 4096 linear /dev/mapper/fs1 274538
    aspire 0.1.1 #
    aspire 0.1.1 # denyfs -o /dev/mapper/fs2
    Checking device structure ...
    0 4096 linear /dev/mapper/fs2 16490
    4096 4096 linear /dev/mapper/fs2 32874
    aspire 0.1.1 #
    aspire 0.1.1 # denyfs -o /dev/mapper/fs3
    Checking device structure ...
    0 4096 linear /dev/mapper/fs3 368746
    aspire 0.1.1 #
    aspire 0.1.1 #

  7. Now hide your data. Fill in /mnt/here1 /mnt/here2 and /mnt/here3 the last one being your secret place, here2 a data flare (supposed to be a fake secret place) and here1 just personal garbage. Let’s put 15Mb in here1 3Mb in here2 and 1Mb in here1.
  8. aspire 0.1.1 # ls -lh sizzla*
    -rwxr-xr-x 1 root root 4,0M août 23 14:56 sizzla.mp3
    -rwxr-xr-x 1 root root 691K août 23 15:26 sizzla-small.mp3
    -rw-r--r-- 1 root root 16M août 23 14:57 sizzlax4.mp3
    aspire 0.1.1 # cp sizzlax4.mp3 /mnt/here1
    aspire 0.1.1 # cp sizzla.mp3 /mnt/here2/
    aspire 0.1.1 # cp sizzla-small.mp3 /mnt/here3
    aspire 0.1.1 #
    aspire 0.1.1 # tree -h /mnt/here?
    /mnt/here1
    |-- [ 12K] lost+found
    `-- [ 16M] sizzlax4.mp3
    /mnt/here2
    |-- [ 12K] lost+found
    `-- [4.0M] sizzla.mp3
    /mnt/here3
    |-- [ 12K] lost+found
    `-- [691K] sizzla-small.mp3

    3 directories, 3 files
    aspire 0.1.1 #

  9. Close all volumes.
  10. aspire 0.1.1 # dfsclose -h
    Usage:
    /usr/sbin/dfsclose [options]

    Options:
    -f, --file [/path/fs] Path to your filesystem
    -l, --loop [loop] Loop device
    -n, --numdev [int] Number of sub devices
    -h, --help This
    -v, --version Print version

    Example:
    /usr/sbin/dfsclose -f fs -l loop0 -n 9
    aspire 0.1.1 #
    aspire 0.1.1 # dfsclose -f fs -l loop0 -n 3
    >>> Unmounting filesystems ...
    /dev/mapper/fs1_new OK
    /dev/mapper/fs2_new OK
    /dev/mapper/fs3_new OK
    >>> Unmapping dmsetup block devices ...
    /dev/mapper/fs1_new OK
    /dev/mapper/fs2_new OK
    /dev/mapper/fs3_new OK
    >>> Unmapping cryptsetup devices ...
    /dev/mapper/fs1 OK
    /dev/mapper/fs2 OK
    /dev/mapper/fs3 OK
    >>> Unbinding /dev/loop0 ...
    aspire 0.1.1 #
    aspire 0.1.1 # mount | grep here
    aspire 0.1.1 # ls /dev/mapper/
    control root swap
    aspire 0.1.1 #

  11. Let’s reopen them all and check we still have the files and close again.
  12. aspire 0.1.1 # dfsopen -f /tmp/fs -l loop0 -d 1=10,2=3,3=1 -m /mnt/here
    >>> Binding to loop0 ... OK
    >>> Mapping cryptsetup block devices ...
    Enter passphrase:
    Enter passphrase:
    Enter passphrase:
    >>> Sizing up block devices ...
    device 1 ...
    Checking device structure ...
    device 2 ...
    Checking device structure ...
    device 3 ...
    Checking device structure ...
    >>> Mapping to crytpsetup block devices ...
    Checking device structure ...
    Checking device structure ...
    Checking device structure ...
    >>> Mounting filesystems ...
    /mnt/here1 mounted
    /mnt/here2 mounted
    /mnt/here3 mounted
    aspire 0.1.1 # tree -h /mnt/here?
    /mnt/here1
    |-- [ 12K] lost+found
    `-- [ 16M] sizzlax4.mp3
    /mnt/here2
    |-- [ 12K] lost+found
    `-- [4.0M] sizzla.mp3
    /mnt/here3
    |-- [ 12K] lost+found
    `-- [691K] sizzla-small.mp3

    3 directories, 3 files
    aspire 0.1.1 # dfsclose -f fs -l loop0 -n 3
    >>> Unmounting filesystems ...
    /dev/mapper/fs1_new OK
    /dev/mapper/fs2_new OK
    /dev/mapper/fs3_new OK
    >>> Unmapping dmsetup block devices ...
    /dev/mapper/fs1_new OK
    /dev/mapper/fs2_new OK
    /dev/mapper/fs3_new OK
    >>> Unmapping cryptsetup devices ...
    /dev/mapper/fs1 OK
    /dev/mapper/fs2 OK
    /dev/mapper/fs3 OK
    >>> Unbinding /dev/loop0 ...
    aspire 0.1.1 #

  13. Open the hidden volume only add a file to it and close it.
  14. aspire 0.1.1 # dfsopen -f /tmp/fs -l loop0 -d 3=1 -m /mnt/here
    >>> Binding to loop0 ... OK
    >>> Mapping cryptsetup block devices ...
    Enter passphrase:
    >>> Sizing up block devices ...
    device 1 ...
    Checking device structure ...
    >>> Mapping to crytpsetup block devices ...
    Checking device structure ...
    >>> Mounting filesystems ...
    /mnt/here1 mounted
    aspire 0.1.1 #
    aspire 0.1.1 # tree -h /mnt/here?
    /mnt/here1
    |-- [ 12K] lost+found
    `-- [691K] sizzla-small.mp3
    /mnt/here2
    /mnt/here3

    1 directory, 2 files
    aspire 0.1.1 #
    aspire 0.1.1 # echo pi > /mnt/here1/secret
    aspire 0.1.1 # tree -h /mnt/here?
    /mnt/here1
    |-- [ 12K] lost+found
    |-- [ 3] secret
    `-- [691K] sizzla-small.mp3
    /mnt/here2
    /mnt/here3

    1 directory, 2 files
    aspire 0.1.1 #
    aspire 0.1.1 # dfsclose -f fs -l loop0 -n 1
    >>> Unmounting filesystems ...
    /dev/mapper/fs1_new OK
    >>> Unmapping dmsetup block devices ...
    /dev/mapper/fs1_new OK
    >>> Unmapping cryptsetup devices ...
    /dev/mapper/fs1 OK
    >>> Unbinding /dev/loop0 ...
    aspire 0.1.1 #

  15. Open the hidden volume only with a wrong password.
  16. aspire 0.1.1 # dfsopen -f /tmp/fs -l loop0 -d 3=1 -m /mnt/here
    >>> Binding to loop0 ... OK
    >>> Mapping cryptsetup block devices ...
    Enter passphrase:
    >>> Sizing up block devices ...
    device 1 ...
    Checking device structure ...
    Do you intend to resize? (CTRL-C to abort) ^C
    aspire 0.1.1 #

    At this point you should be _very_ careful. If you do not intend to resize your volume than you must realize that your password is wrong (the password is parameter of the block mapping logic). If you do pursue you will resize the hidden volume. Although in some very lucky and special cases, if you enlarge your volume you may again access your previously hidden data, don’t assume that in general as shrinking the volume will erase it for sure (unless again you free unused blocks but you’d really be lucky and you should play Euromillion).

Finally, as long as you understand that given the password you provide a different block mapping will appear, you should be fine as a user.

To really measure the true power of denyfs you have to “feel”. You have to feel the volume size compared to one another, the free space ratio and the randomness of all your passwords. This is the human parameter to that program. Strange I know, but denyfs is a system which logic on passwords and size mapping shoudn’t be written (it is way more complex than denyfs itself) and won’t work for any given size mapping and passwords.
You are strongly advised to play around and test it (wisely choose your size mapping and passwords) before actually using it for “hurm”… production purposes.

« »