Add a README
authorSimon McVittie <http://smcv.pseudorandom.co.uk/>
Thu, 3 Sep 2009 11:20:39 +0000 (12:20 +0100)
committerSimon McVittie <http://smcv.pseudorandom.co.uk/>
Thu, 3 Sep 2009 11:20:39 +0000 (12:20 +0100)
README [new file with mode: 0644]

diff --git a/README b/README
new file mode 100644 (file)
index 0000000..fc16a0b
--- /dev/null
+++ b/README
@@ -0,0 +1,188 @@
+gfcombinefs - filesystem for n-of-m secret sharing
+==================================================
+
+    ######################### WARNING ################################
+    # So far, gfcombinefs is experimental and mostly untested.       #
+    # No real release has been made yet. I suggest not trusting it.  #
+    ##################################################################
+
+gfcombinefs combines several "shares" of a secret file previously split using
+Shamir secret sharing, to produce the original secret, and presents it as
+a file in a FUSE filesystem.
+
+The idea is that the secret file (probably a GnuPG secret keyring, i.e.
+secring.gpg) is split into (say) 6 shares (of the same length in bytes
+as the secret), of which 4 are needed to reconstitute the original secret
+(that would be a "4-of-6" share). Thanks to the algorithm used, having fewer
+than the required number of shares gives no information whatsoever about the
+secret's contents.
+
+For the actual mathematics, gfcombinefs uses libgfshare, written by Daniel
+Silverstone - see libgfshare's documentation for more about the algorithm.
+
+gfcombinefs is primarily designed for use with GnuPG secret keyrings, which
+has various consequences:
+
+* it locks itself into memory to stop the secret from being paged out
+* the secret can be removed, which should be done prior to suspend-to-disk
+  (hibernate), again to prevent it from being paged out
+* when not enough parts have been provided, the file exists but has zero
+  length (this stops gpg from complaining about it)
+
+Requirements
+------------
+
+At runtime:
+* FUSE library, tools and kernel module <http://fuse.sourceforge.net/>
+* libgfshare <http://www.digital-scurf.org/software/libgfshare>
+
+For compilation:
+* pkg-config <http://pkg-config.freedesktop.org/>
+* GNU make <http://www.gnu.org/software/make/>
+
+Usage
+-----
+
+The filesystem currently has one file in the root directory, called "secret".
+There's only one secret per mountpoint so far.
+
+The only normal operations supported are:
+
+* list the root directory (it contains "secret", "." and "..")
+* read from "secret"
+* get the attributes of "secret" (its permissions are 0400, i.e. r--------)
+* unlink "secret", e.g. with `rm -f $mountpoint/secret` - this doesn't actually
+  remove it, but it discards all its data (by clearing the relevant memory),
+  then truncates it to be an empty file
+
+In addition, you can provide shares. This is done by setting an XFS-style
+extended attribute on the secret, whose name is "user." plus the share number
+in ASCII, for instance:
+
+    rm -f $mountpoint/secret
+    attr -q -s user.023 $mountpoint/secret < secring.gpg.023
+    attr -q -s user.042 $mountpoint/secret < secring.gpg.042
+    attr -q -s user.111 $mountpoint/secret < /media/usbdisk/secring.gpg.111
+    attr -q -s user.123 $mountpoint/secret < /media/usbdisk/secring.gpg.123
+
+When enough shares have been provided (currently the filesystem is hard-coded
+to expect exactly 4 shares), the secret file's size will change from 0 to the
+real size (which is equal to the size of each share), and its contents will
+change from empty to the real secret.
+
+Example
+-------
+
+For instance, you could do a 4-of-6 share and put two shares on your laptop,
+two on a USB stick in your pocket, and two backup shares kept in safe
+places.
+
+If you have both the laptop and the USB stick, you can get your secret keyring
+and do GnuPG things, but if either your laptop or your USB stick are lost
+or stolen (but not both devices at the same time!) you don't need to revoke
+your key: just take the remaining device and the two backup shares, combine
+them to get the secret, re-split the secret into a new set of shares, and
+securely destroy the old shares (to guarantee that they cannot be obtained by
+the same person as the lost device, and used to recover the secret).
+
+The lost device contains only two shares, which isn't enough to recover the
+secret (you can make sure they're entirely useless by destroying the other
+shares in that set).
+
+Many other sharing schemes are possible; the author of libgfshare suggests
+a 3-of-5 share, with two shares on a USB stick and one each on three
+computers. You can adjust the number of shares, and their distribution
+between various locations, as necessary, but at the moment the number of shares
+expected is hard-coded in gfcombinefs.
+
+For shares stored on large storage devices (like the laptop's hard disk), I
+recommend making a small partition (or LVM logical volume) to contain them -
+that way, you can wipe the whole partition with wipe(1) without it taking too
+long, and be reasonably sure that the old shares are unrecoverable.
+
+Limitations
+-----------
+
+gfcombinefs is a read-only filesystem - you'll have to split the secret
+yourself, probably using gfsplit(1). Supporting writing would be problematic -
+splitting the new secret wouldn't be a problem, but it wouldn't be possible
+to copy the new shares from gfcombinefs to their various locations
+automatically (the backup shares shouldn't even be present most of the time).
+
+Luckily, gpg can usually operate well with a read-only secret keyring; you'll
+usually only have to alter the secret keyring (and hence re-split) if you add
+uids or subkeys to a key, or create a whole new key.
+
+In particular, you can encrypt data, sign data, certify (sign keys), and so on
+with the secret keyring on a read-only filesystem like gfcombinefs.
+
+gfcombinefs doesn't help you to do the actual splitting. This is probably
+best done with a temporary GNUPGHOME in a tmpfs, with swap disabled (so the
+pages of the tmpfs don't get paged out either); copy in the secret and public
+keyrings, make the changes, split the secret keyring, copy the shares
+to appropriate places, and copy the public keyring back to the normal
+GNUPGHOME.
+
+You can only have one secret per filesystem at the moment.
+
+There is no detection of corruption, perhaps from incorrect shares. This could
+be solved by supplying a hash of the complete secret, perhaps as another
+extended attribute or as the secret's filename.
+
+The filesystem currently assumes that exactly 4 shares are needed. This could
+also be solved by supplying a hash of the complete secret - attempting to
+assemble an incomplete or inconsistent set of shares will yield meaningless
+contents for the secret, so the filesystem could just try to reassemble the
+secret after each share is added, then make it available for reading only when
+the hash matches what was expected.
+
+The unlink() implementation should really be truncate() instead (or perhaps
+both should work).
+
+There should be scripts for pm-utils (and perhaps other suspend-to-disk
+implementations) to discard the secret before hibernating.
+
+The executable needs to be setuid root to set a larger mlock limit, and
+the mlock logic could probably be improved. The Linux default of 64KB is not
+necessarily sufficient, even if only the security-sensitive parts (the shares,
+the secret, and any buffers used by libfuse) are mlocked; for the moment it
+uses root privileges to set a limit of 10MB, drops privileges, and locks the
+entire process (including libraries) into memory.
+
+Other notes
+-----------
+
+The access() implementation is necessary to prevent gpg from trying to
+create lockfiles on the gfcombinefs filesystem (which won't work, and if
+gpg tries and fails to do so, it will consider this to be an error).
+
+Related links
+-------------
+
+Web page: <http://www.pseudorandom.co.uk/src/gfcombinefs/>
+Version browser: <http://git.pseudorandom.co.uk/gfcombinefs.git>
+Version control: `git clone git://git.pseudorandom.co.uk/git/gfcombinefs.git`
+Author's e-mail: closely resembles smcv#pseudorandom#co#uk
+
+Copyright/licensing
+-------------------
+
+Copyright © 2009 Simon McVittie <http://smcv.pseudorandom.co.uk/>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+IABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.