A Portable Encrypted Blob Filesystem for Pi

Well, this bit was easier than I expected.

Yes, you can make an encrypted partition and mount it in the usual way. But folks know to look for those. Any partition that looks encrypted is likely to be subjected to a decryption attack.

But if you have a file named “coredump_from_virus_attack” or “Failed_stats_analysis” or even just “What_Is_This”; folks then tend to think that spending days in a crypto attack is a waste of their time as it is just junk. Which is also why naming it “junk_file” or “garbage_collection” also work…

In this example, I’m going to use names that just scream “hack me and attack me with crypto tools”, but this is not what you would do in real life.

I don’t know if these first steps are really needed. Some pages said to do it, but it might be irrelevant if the modules are already in use. Having done it, I can’t really undo it to test until the next boot (or maybe next install?) In any case, these modules need to be available to do the process, so if it fails, check to see if you skipped the load modules part.

pi@RaPiM2 / $ sudo bash
root@RaPiM2:/# modprobe loop
root@RaPiM2:/# modprobe cryptoloop
root@RaPiM2:/# modprobe aes

Then you make the blob file and the mount point. These can be anywhere in the name space you like. As I had free space in the /Temps file system, I did it there, but you can choose anywhere you like. This can even be on a USB drive or stick that is only plugged in when needed.

root@RaPiM2:/#  cd /Temps
root@RaPiM2:/Temps# mkdir Testing
root@RaPiM2:/Temps# cd Testing

Now we’re going to fill the future file system space with junk. Anyone digging around in it will find your encrypted stuff along with a lot of trash. Figuring out which is trash and which is encryption is, er, “hard”. I’ve bolded the “dd” command as it is the working bit. It says to take in random stuff from /dev/urandom and put 102400 blocks of it into the file Crypto_Filesys. By default, these are 512 byte blocks, but you can change that if desired.

root@RaPiM2:/Temps/Testing# pwd
/Temps/Testing
root@RaPiM2:/Temps/Testing# dd if=/dev/urandom of=Crypto_filesys count=102400
102400+0 records in
102400+0 records out
52428800 bytes (52 MB) copied, 28.3419 s, 1.8 MB/s
root@RaPiM2:/Temps/Testing# ls -l
total 51256
-rw-r--r-- 1 root root 52428800 Sep 10 22:14 Crypto_filesys

Now I have a 52 MB “bag of trash” where I’m going to slip in my filesystem.

We set up a particular loopback device for this. I chose #2 as I usually use 0 and 1 for non-encrypted stuff already. “losetup” sets up that loopback device. We’re using the AES encryption method, but there are others. There are endless arguments about which is best. AES is well vetted, but folks know to look for it. Others are less well known, but also less vetted. Blowfish is supposed to be good too. I used the “./” method of saying “From my working directory right here”, but could just as easily have typed out /Temps/Testing/Crypto_filesys. It asks you for a password. Long and simple is better than short and hard to remember. “4 score and twenty years ago I ate a clam that made me sick!” is better than “%55$RfRTG(&*” and much easier to remember.

root@RaPiM2:/Temps/Testing# losetup -e aes /dev/loop2 ./Crypto_filesys
Password:

Gee… that was easy. Now we make the file system. I’m using an EXT4 type as it is journaled and very safe. You want safe in something that is already complicated and pot-stirred. But any file system type can be used.

root@RaPiM2:/Temps/Testing# mkfs -t ext4 /dev/loop2
mke2fs 1.42.5 (29-Jul-2012)
Discarding device blocks: done
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
12824 inodes, 51200 blocks
2560 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=52428800
7 block groups
8192 blocks per group, 8192 fragments per group
1832 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961

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

At that point, you are basically done. Time to mount it and take it for a test drive. I’ve removed the long prompt from in front of the command so you can see it better. Basically, it is of the form:
mount -o loop,encryption=aes /filesysfile /mountpoint
It asks for your password and you type in your phrase. (Don’t forget it!)

mount -o loop,encryption=aes /Temps/Testing/Crypto_filesys /Temps/Testing/MountCrypto/
Password:

And here it is showing up like any other file system:

root@RaPiM2:/Temps/Testing# df
Filesystem     1K-blocks      Used Available Use% Mounted on
rootfs          59805812  55517140   1227632  98% /
[...]
/dev/loop0      63381404  38648480  21506608  65% /NOAA
/dev/sdd3      140745608 100499088  33090400  76% /Temps
/dev/mmcblk0p5    499656       676    462284   1% /media/data
/dev/mmcblk0p3     27633       444     24896   2% /media/SETTINGS
/dev/loop1         45478       810     41084   2% /Temps/Testing/MountCrypto
root@RaPiM2:/Temps/Testing#

Now the sharp eyed will notice that it is mounted as /dev/loop1 but I used /dev/loop2 in the setup. You can specify a particular loop device to the mount, but I wanted to see what happened if I didn’t, and it worked fine… so that might need a bit more exploring to see what the limits are.

OK, lets test it a bit.

root@RaPiM2:/Temps/Testing# cd /Temps/Testing/MountCrypto/
root@RaPiM2:/Temps/Testing/MountCrypto# ls
lost+found

So it looks like a real file system including the “lost+found” directory where a disk check will puts bits of broken files if it has to try repairing the file system and fails.

Let’s edit a file. I’m going to use the “vi” visual editor since my fingers known how to use it without my brain being bothered… I just opened the editor, typed in some text, and exited. Then I used the “cat” command to print out the contents. “This file is full of my secrets.”

root@RaPiM2:/Temps/Testing/MountCrypto# vi MySecrets
root@RaPiM2:/Temps/Testing/MountCrypto# cat MySecrets
This file is full of my secrets.

Now we’ll go up one directory and look things over:

root@RaPiM2:/Temps/Testing/MountCrypto# cd ..
root@RaPiM2:/Temps/Testing# ls
Crypto_filesys  MountCrypto
root@RaPiM2:/Temps/Testing# df /Temps/Testing/MountCrypto/
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/loop1         45478   811     41083   2% /Temps/Testing/MountCrypto

There is one more block used. 811 instead of 810. Let’s unmount it and see if anything is visible.

root@RaPiM2:/Temps/Testing# umount /Temps/Testing/MountCrypto/
root@RaPiM2:/Temps/Testing# ls -l
total 51260
-rw-r--r-- 1 root root 52428800 Sep 10 22:43 Crypto_filesys
drwxr-xr-x 2 root root     4096 Sep 10 22:17 MountCrypto

root@RaPiM2:/Temps/Testing# ls MountCrypto/
root@RaPiM2:/Temps/Testing# 

The mount point is now just an empty directory again. The Crypto_filesys file just looks like a regular file now. How about a couple of file inspection methods:

root@RaPiM2:/Temps/Testing# file Crypto_filesys
Crypto_filesys: data

root@RaPiM2:/Temps/Testing#
root@RaPiM2:/Temps/Testing# grep "secrets" Crypto_filesys
root@RaPiM2:/Temps/Testing#

The “file” command looks at the “magic number” of a file to tell you what is in it. For random stuff, it assumes just data and not any particular format. Here it is saying “just random data”. Named with “_filesys”, we have given a clue to an attacker to “apply decryption here”, but if named “core_dump_VAX_1984”, well… But for now, named with _filesys will remind us not to delete that “junk”… and that we need to mount it as a file system.

“Grep” is “Global Regular Expression Print” and lets you apply all sorts of search test ‘regular expressions’ to searching files. The simplest is just “look for this quoted text” which we used here. It did not find the word “secrets” anywhere in the Crypto_filesys file. Because it is encrypted and looks a lot like the surrounding trash and the encrypted binary inodes, and file structure blocks.

I would advise against just dumping some of the file to look at it. I used “head” that gives you the top 10 lines of the file ( “tail” gives you the last 10. And stop snickering… ) and the binary trash it dumps caused my terminal window to “do very strange things”. Typical for a raw data dump to a screen. This bit stayed on my screen so is likely safe. We’ll see:

root@RaPiM2:/Temps/Testing# head Crypto_filesys

f       ��?�;���^P���0ך ���@6�A��J������=���'�h��1�H��,�|ryb^Z�{u������X��}��5��^B�f����28<8    �!
ڗ+q�^X��������#���h�g�Bk�f���T��j��=�b̸�nX�0�-(�ȡ
g

So that’s what stuff looks like inside the file.

All in all, a fairly easy process. Still a few loose ends to polish, like specifying a particular loop device and trying other encryption methods. I’d also like to try some performance and speed tests, but those can wait.

For now, this is “good enough” for daily use. Oh, and do realize that for Mil Spec or NSA proof, you need the entire OS hardened and locked down. They have some fairly exotic tools like things that can read your screen from across the street (don’t know if they still work on LCDs…) and replacement keyboard wires that capture keystrokes. So control of the hardware 100% of the time and a tinfoil lined room are needed… (or at least bronze window screen lined and grounded.) But if you need that level of security, you are in the wrong line of work to be taking advice from a blog. Ask your section chief for a security set up and site sweep…

Enjoy playing with encrypted file systems in a file, and DO remember that if the pass phrase is lost, you are toast. Get konked on the head in a car wreck and forget it? Just do something else for 6 months and forget it? All Gone. So make it easy to remember, or have a ‘keyring’ that can not be found or broken to hold it. “!and” typed 40 times in a row is harder to crack than “@#$faa” so when in doubt, go for a long simple sentence and with one each of number and special char. Things like “I always hated the song 2 for tea!”

Subscribe to feed

About E.M.Smith

A technical managerial sort interested in things from Stonehenge to computer science. My present "hot buttons' are the mythology of Climate Change and ancient metrology; but things change...
This entry was posted in Tech Bits and tagged , , , , . Bookmark the permalink.

11 Responses to A Portable Encrypted Blob Filesystem for Pi

  1. E.M.Smith says:

    Oh, and while it is sort of obvious, it is worth making explicit that the encrypted blob can be stored on things like “the cloud” without the holder of the blob being able to mine it for information about you and without much usable being ‘shared’ with other agencies.

    You can also have a remote NFS or FTP server that holds the blob and ships it to you (perhaps even over a VPN encrypted pipe – so once someone breaks the VPN encryption they get a further encryption challenge in the data stream…) so that it is encrypted ‘end to end’ and only decrypts at the point of filesystem mount on your local machine. In that way you can have all your data stored “somewhere else”. This is a very important part of the “take all my stuff you get nothing” as it is all encrypted, but also an important part of “the next day I am back up” as the data blobs were stored offsite somewhere else… There are a variety of ‘distributed file systems’ that can be used by a cooperating pool of folks, so it doesn’t have to be the Google Cloud… (but distributed file systems are for another day).

    There is even a filesystem that lets you mount an ftp:// address as a file system, so you don’t need to ship the whole blob back and forth to do the “mount and decrypt” and use it.

    Don’t know if it is still around, but at one time there was the TCFS Transparent Cryptographic File System… Here’s an article from 1997 about it:
    http://www.linuxjournal.com/article/2174

    Looks like Sourceforge has a newer version:

    http://sourceforge.net/projects/tcfs4/

    It lets you have a ‘quorum’ of users share an encrypted file set over a network. No one person can decrypt it, so capture one guy, you get his password, you get nothing. Must have a quorum after all… Comes from Italy (which makes me wonder who would need this in Italy …. ;-)

    So for distributed groups, it’s the better solution.

  2. E.M.Smith says:

    In playijng with this, the ‘losetup’ step does not permanently match that loopback device to that file system, it is just used for the configuring (thus the mount on /dev/loop1). BUT, it does hang around, so you need to do a “losetup -d /dev/loop2” to ‘detach’ it from that file for reuse in other contexts… (like to ‘set up’ the next file / file system).

  3. E.M.Smith says:

    I’ve made a convenient little script to set one of these up on my “Pink Monster” USB drive. It is normally mounted as /Pink for the FAT32 file system and /Pinkntfs for the NTFS file system (and yes, there is a /Pinkext and a swap partition on it. I’m playing with the different file systems for timing and ‘wear’ on the device). Here’s what it looks like:

    This is after making the blobs on each:

    /dev/sda1        2043984   2000024     43960  98% /Pink
    /dev/sda3        5119996   2026252   3093744  40% /Pinkntfs
    [...]
    /dev/loop2       1935760      2952   1816424   1% /Pinkntfs/junk
    /dev/loop3       1935760      2952   1816424   1% /Pink/junk
    

    It did a nice job of making a 2 GB blob file on each of the USB drive partitions, doing the encryption set up, making the file system inside of them, and releasing the loop device.

    Here is what the script looks like. I’ve named it ‘pinkblob’. Note that I’m set up to pass parameters (those things with a $ in them) for the particular real mount point name ($1). The {} let it use a default. So ${1-/Pink} says “use the first parameter I passed, or default to /Pink. That way I can say “pinkblob” to make one in /Pink or I can say “pinkblob /Pinkntfs” to make one in the /Pinkntfs mount point instead.

    dd if=/dev/urandom of=${1-/Pink}/blob_filesys bs=8K count=250000
    
    losetup -e aes /dev/loop4 ${1-/Pink}/blob_filesys
    
    mkfs -t ext4 /dev/loop4
    
    losetup -d /dev/loop4
    

    For you own version, you will want to swap “/Pink” for your mount point default.

    It pauses and asks for the password after the ‘losetup -e’ command, then continues on. Execution times on FAT32 vs NTFS were inside 1 second of each other, so not much different. (No journal overhead in the set up…)

    Here’s the NTFS time:

    2048000000 bytes (2.0 GB) copied, 1248.38 s, 1.6 MB/s
    Password: 
    
    real	21m48.655s
    user	0m1.540s
    sys	17m21.500s
    

    and the FAT32 time:

    real	19m36.225s
    user	0m0.970s
    sys	17m11.290s
    root@RaPiM2:/Pink# 
    

    But I was doing some accesses to other parts of the USB drive during the FAT32 build, so it might have slowed things a little ( i.e. FAT32 might be even faster than NTFS than this shows).

    Finally, here is the /etc/fstab entry to mount them:

    /Pink/blob_filesys	/Pink/junk	ext4	loop,encryption=aes,defaults	0 0
    /Pinkntfs/blob_filesys	/Pinkntfs/junk	ext4	loop,encryption=aes,defaults	0 0
    

    At this point I don’t know what happens if you try to boot with these active, so I un-mount and put a “#” in the first character to make it a comment prior to rebooting. “Someday” I’ll find out if it just politely asks for a password or hangs at boot ;-) I expect it to ask… If it hangs, rebooting without the USB in place ought to cause it to be skipped. We’ll see in a few days when the wgets are done and I feel like rebooting…

    So at this point making an encrypted blob is one command, and mounting it is one line in the /etc/fstab file. Easy… (Hardest part is just typing the password right each time… ;-)

  4. E.M.Smith says:

    And, what I hope is “finally”, time trials. I made a command named “timecrypt” that just prints out the dd command it is going to run, then runs it (with ‘time’ in front of it to get timing stats):

    root@RaPiM2:/home/pi# timecrypt
    
    Doing the EXT file system on a USB hard disk:
    
    time dd if=/dev/zero of=/Temps/Testing/junk bs=16k count=1000
    1000+0 records in
    1000+0 records out
    16384000 bytes (16 MB) copied, 0.281524 s, 58.2 MB/s
    
    real	0m0.321s
    user	0m0.010s
    sys	0m0.270s
    
    Doing the encrypted EXT file system on the same USB hard disk:
    
    time dd if=/dev/zero of=/Temps/Testing/MountCrypto/junk bs=16k count=1000
    1000+0 records in
    1000+0 records out
    16384000 bytes (16 MB) copied, 0.22099 s, 74.1 MB/s
    
    real	0m0.241s
    user	0m0.010s
    sys	0m0.220s
    
    Doing the FAT32 file system on a fast USB disk
    
    time dd if=/dev/zero of=/Pink/junk/junk bs=16k count=1000
    1000+0 records in
    1000+0 records out
    16384000 bytes (16 MB) copied, 0.461797 s, 35.5 MB/s
    
    real	0m0.496s
    user	0m0.000s
    sys	0m0.200s
    
    Doing the NTFS file system on the same fast USB disk
    
    time dd if=/dev/zero of=/Pinkntfs/junk/junk bs=16k count=1000
    1000+0 records in
    1000+0 records out
    16384000 bytes (16 MB) copied, 1.31867 s, 12.4 MB/s
    
    real	0m1.366s
    user	0m0.010s
    sys	0m0.240s
    root@RaPiM2:/home/pi# 
    

    No surprise, NTFS is the really sucky one. Oddly, the encrypted EXT was faster than the non-encrypted. I suspect disk contention from the wget that is running to the same disk. Re-running it gave:

    root@RaPiM2:/home/pi# !!
    timecrypt
    
    Doing the EXT file system on a USB hard disk:
    
    time dd if=/dev/zero of=/Temps/Testing/junk bs=16k count=1000
    1000+0 records in
    1000+0 records out
    16384000 bytes (16 MB) copied, 0.2452 s, 66.8 MB/s
    
    real	0m0.288s
    user	0m0.000s
    sys	0m0.250s
    
    Doing the encrypted EXT file system on the same USB hard disk:
    
    time dd if=/dev/zero of=/Temps/Testing/MountCrypto/junk bs=16k count=1000
    1000+0 records in
    1000+0 records out
    16384000 bytes (16 MB) copied, 0.502824 s, 32.6 MB/s
    
    real	0m0.514s
    user	0m0.010s
    sys	0m0.240s
    
    Doing the FAT32 file system on a fast USB disk
    
    time dd if=/dev/zero of=/Pink/junk/junk bs=16k count=1000
    1000+0 records in
    1000+0 records out
    16384000 bytes (16 MB) copied, 0.417131 s, 39.3 MB/s
    
    real	0m0.439s
    user	0m0.020s
    sys	0m0.160s
    
    Doing the NTFS file system on the same fast USB disk
    
    time dd if=/dev/zero of=/Pinkntfs/junk/junk bs=16k count=1000
    1000+0 records in
    1000+0 records out
    16384000 bytes (16 MB) copied, 0.791675 s, 20.7 MB/s
    
    real	0m0.866s
    user	0m0.030s
    sys	0m0.210s
    root@RaPiM2:/home/pi# 
    

    So it looks like I need a less busy system to get a really clean test. OTOH, on a fairly busy system ( I/O wise) writing 16 MB in under a second ‘real time’ in almost all cases, and that’s just dandy for me. “Someday” I’ll re-run this on an idle system with a GB each and see what shows up. For now, it’s tea time… and maybe look at politics or something non-tech. I’m about at my coming up for air point on encryption…

  5. vukcevic says:

    This note is totally unrelated to the subject discussed, but it may be of some interest to Mr. Smith; a high degree of caution is required.
    North Atlantic SST oscillation (the AMO), the strongest natural variability component in the global temperatures, appears to be ‘synchronised’ (with some minor exceptions) by the lunar synodic month, whereby the moon takes 29.531 days to return to the same point on the celestial sphere as referenced to the Sun (solar + lunar tide ?)
    ‘Synchronisation’ lasted at least 125 years (two AMO cycles) up to around 1995. In the last 20 years relationship appears to break down; alternatively the N. Atlantic SST could be inflated by 0.3C (some other factors at work). However, if the post 1995 temperatures are commensurate to those seen throughout the 1940/50s, then the relationship as observed during previous 125 years would be restored.
    I might eventually write a bit more, but it is unlikely that the method used would be considered satisfactory.

  6. E.M.Smith says:

    @Vukcevic:

    Yes, that is of some interest… Looking at the AMO graph, one gets the sense of 3 cycles of 6 years each culminating in an 18.x year lunar pattern, then repeated 3 times for the 54-60 ish year pattern. IIRC, the Southern Annular Mode has a similar “multiples of 3” pattern in the southern wave of about 9? years, something like that… I think I’ll look for some kind of lunar status graph (showing major lunations so things like perigee moon) and see if I can line up any particular state of the lunar cycle with the minor peaks of the AMO (then try to sync the whole thing with when that state returns to over a particular ocean…).

    Might make a fun posting …. Something to do today ;-)

  7. vukcevic says:

    Hi Mr. Smith
    Tanks for the reply.
    Demonstration (but miles away from a proof) is relatively simple, arrived at it by calculations and found that the critical number is somewhere 29.5 to 29.6 days. Only reasonable forcing in that range that I know of, could be either the high latitude coronal holes or the lunar synodic month; I am inclined to opt for the lunar tide. However, understanding physics behind very simple math’s process borders on the irrational, regardless of what the ultimate driving force may be. I’ve been ‘wrecking’ my brain to understand it for about a year now but I am no closer to it.
    Calculation shows millennial cycle (between 970 and 1000 years), while the 60 year periodicity appears only between alternative peaks occurring every 30 years; this would suggest some orbital (angle, nodal point or something else) difference between subsequent synodic months, which I am not aware of.

  8. E.M.Smith says:

    https://chiefio.wordpress.com/2013/01/24/why-weather-has-a-60-year-lunar-beat/

    Has the mention of circumpolar cycle being about 1/2 Saros. It takes 3 of the 18.x year cycles for the moon to be back over the same ocean at apogee or perigee, so cycle repeats the same tides.

    Basically, you need to track not just lunar orbit, but earth rotation alignment to it. Hope that helps.

  9. E.M.Smith says:

    Well, after a reboot I could not get the encrypted file systems to mount:

    root@RaPiM2:/SG# mount /Temps/Testing/MountCrypto/
    Password: 
    ioctl: LOOP_SET_STATUS: Invalid argument
    

    until I did the “modprobe” commands again. So one must make sure those modules are loaded after each reboot.

    modprobe aes
    modprobe cryptoloop

    Then the mount / password worked. I suppose I could add them to the boot script. OTOH, not having them autoloaded is just one more small hurdle for someone trying to see what’s in them.

    FWIW, mis-typing my password gave this unhelpful message (so maybe a good thing as it isn’t admitting there IS a password that works…)

    root@RaPiM2:/Temps/Testing# mount /Pinkntfs/junk
    Password: 
    mount: wrong fs type, bad option, bad superblock on /dev/loop3,
           missing codepage or helper program, or other error
           In some cases useful info is found in syslog - try
           dmesg | tail  or so
    
  10. vukcevic says:

    Mr. Smith
    Here you can see 63 year and millennial cycles derived from lunar synodic month. I will have to sit down and eventually write some notes on this.

  11. Pingback: RaTails – Draft High Level Steps | Musings from the Chiefio

Comments are closed.