Re: signing a filesystem

Olaf Kirch (okir@monad.swb.de)
Tue, 31 Dec 1996 02:00:16 +0100 (MET)


To: linux-kernel@vger.rutgers.edu
Subject: Re: signing a filesystem
X-Newsreader: TIN [UNIX 1.3 950515BETA PL0]

Andrew Morgan wrote:
: I've been wondering about the following scheme for making a filesystem
: tamper-resistant. Would it be possible to digitally sign each inode?

This begs the question whom you want to keep from tampering with
the file system. If, as you suggest, a keyed hash using a single key
would be employed, the implementation's security would hinge on you
being able to keep users from gaining root privs. This doesn't very
much improve on the current situation.

A more promising scheme would be to implement per-user security
mechanisms, where the user can provide a key at login time, and revoke
the key before logout. Take a look at the way CFS does it.

Someone else suggested implementing this in a new file system. This is
not a particularly good idea. Rather, one would want to be able to
enhance existing file systems to support things like encryption or
signatures (or any other type of transformation, for that matter). Doing
so would probably be easier than implementing a new file system,
particularly if you're concerned about performance.

One way to do it might be to implement some sort of `encapsulating FS'
that offers a different access method to an FS that has already been
mounted on a different directory. The encapsulating FS might use
a private inode part like this:

struct encap_inode_info {
struct pipe_inode_info pipeinfo;
struct inode * shadowed_inode;
struct encap_info * encaps;
};

The inode->i_op and file->f_op structs would contain pointers to functions
that remap most operations to those of the underlying FS, except for
a few that implement your security added value. When implementing an
encrypting FS, you might use a file->f_op->write function like this,
for instance:

long
cryptfs_write(struct inode *inode, struct file *file, char *buf, long len)
{
keyinfo = get_user_key(inode->u.cryptfs_i.encaps);
encrypt(buf, len, keyinfo);
fops = (struct file_operations *) file->private_data;
inode = inode->u.cryptfs_i.shadowed_inode;
return fops->write(inode, file, buf, len);
}

That's just a rough sketch, of course, with lots of blank spots to be
filled in. Any decent implementation would also want to do the crypto-
graphic operations at the page cache level, allowing for block ciphers
rather than character-based CFB ciphers as the one above would require.

If you really want to write such a thing, you should definitely ask
Stephen Tweedie. I am sure he has thought this through a lot more
thoroughly than I have.

Cheers
Olaf

-- 
Olaf Kirch        | XmToggleButton resource set; class Set; values set/unset
okir@monad.swb.de |                                  Motif for Quiche Eaters