RFC: pefs - stacked cryptographic filesystem

Gleb Kurtsou gleb.kurtsou at gmail.com
Tue Sep 7 20:28:18 UTC 2010

On (07/09/2010 16:27), Ivan Voras wrote:
> On 09/06/10 20:38, Gleb Kurtsou wrote:
> > Hello,
> >
> > I would like to ask for feedback on a kernel level stacked cryptographic
> > filesystem. It has started as Summer Of Code'2009 project and matured a
> > lot since then. I've recently added support for sparse files and
> > switched to XTS encryption mode.
> I've tried it and so far it works :)
> > 3. Mount pefs filesystem:
> > # pefs mount ~/Private ~/Private
> I see you've used the same example in the man page. Maybe it would be 
> better for educational purposes to use two separate directories, e.g. 
> ~/Private and ~/Decrypted to avoid confusion by new users (of course not 
> all examples need to use this).
Actually I've used the same directory solely for educational purposes --
there is just one directory, it's either encrypted or not.

Users should think of it as of nullfs on steroids, but that doesn't
sound acceptable for man page. Seriously, any help on documentation is
more than welcome. I'm not good at writing it, and there is too much to
document. We could discuss all the details privately to write a
decent man page, if you have time to help.

> > 6. Example how to save your key in keychain database.
> This is probably in line with what rwatson said (and would be covered by 
> the same document): can you describe what keychains actually do?
Yes. I was thinking about 6 and 7 as of feature list, so no
documentation or instructions. Keychains are mentioned in man page, but
once again documentation is far from being good. Help wanted.

Most important fact is that keychains have nothing to do with
filesystem, it's solely userspace utility concept. Chain is a series of
keys (keychain db entries). Each db entry consists of two keys: parent
key and child key. Child key may be zero, i.e. end of chain marker,
(created by addchain -Z).

Keychain database itself is a dictionary of the following form:
db[parent_key] = child_key

Consider the following database:
db[k0] = 0 (zero child key)
db[k1] = k2
db[k2] = k3
db[k3] = 0

k0 is special. Its child key is zero (end of chain). Chain would consist
only of one key: k0

If user enters k1, the following chain can be retrieved from the
database: k1 k2 k3. All three keys are then added to filesystem.

In case of k2 chain is k2 k3.

All entries stored encrypted in a way that child entry can be decrypted
only by parent key.

Using key chains one can emulate access levels.

(Don't miss 'pefs randomchain' command which was invented especially to
make some fun for those trying to look at your data)

> > 7. You can setup pam_pefs (not compiled by default) to add key to home
> > directory and authenticate against keychain database on login, e.g. by
> > adding the following line to /etc/pam.d/system before pam_unix.so:
> >
> > auth	sufficient	pam_pefs.so	try_first_pass
> So, this would bypass passwd and let the user in if his password 
> authenticates against the "keychain database" in his home directory? 
Exactly, that's the way I use it. More detailed description available
here: http://marc.info/?l=freebsd-current&m=128388197901390&w=2

> Will it automagically pefs-mount his home directory?
No, not mounting pefs is intentional. It automagically adds keys to
already mounted pefs filesystem.

> > *   Uses modern cryptographic algorithms: AES and Camellia in XTS mode,
> >      PKCS#5v2 and HKDF for key generation.
> I do have an request: since you are already using kernel crypto support, 
> it would be simple to just throw Blowfish in :) If for nothing else, 
> consider it a gift to those who are fond of Blowfish's large key sizes 
> (upto 448 bits).
XTS requires 128 bit block cipher. One can use Blowfish to encrypt two
64 bit subblocks, but one would need to mix these blocks somehow, that
what XTS does :) A bit tricky to implement.

Adding serpent or twofish should be easy.

> Actually, it would probably be seen as a reflection of consistency to 
> implement the same algorithms that geli(8) implements. geli doesn't 
> implement XTS yet - if your XTS code proves to be stable it would be a 
> good thing to include it as standard and then use it from geli.
The problem is 128 bit block in XTS, in my opinion hacking XTS to add
support for algorithms with other block sizes is a very bad idea. There
are more than enough modern algorithms that can be used instead.

Not sure how far "reflection of consistency" extends but pefs is very
likely not to support modes other then XTS, because for now it's the
only widespread standard mode of operation with arbitrary sector size
and arbitrary offset encryption.

> I see you've copied SHA2 code to the pefs code. What is wrong with just 
> using the kernel's SHA2 implementation?
That was accidental, or there was a reason I've already forgotten about.
Anyway it's just a copy from kernel, my intention was to make it easier
to test by users.

There's hmac which is one-to-one copy from geli. I've extracted it
because now both geli and pefs use same code.

> _______________________________________________
> freebsd-current at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-current
> To unsubscribe, send any mail to "freebsd-current-unsubscribe at freebsd.org"

More information about the freebsd-current mailing list