ScramFS provides a file system interface to a collection of encrypted data, and to answer the question, we consider the differences between encrypting a string, a file and an encrypted file system.
Securing a string
To secure a string, it is encrypted and also authenticated. Authentication allows us to detect changes to stored data. It involves calculating a 128-bit number from the string and a key. The number is stored with the encrypted string. When we decrypt the string, we try to calculate the number again, and if it differs from the stored number we know that the encrypted string has been changed.
Securing file contents
However it is impractical to secure a string of arbitrary length using this approach. To read part of the string we must decrypt and authenticate the entire string, and similarly to change part of it we must re-encrypt and recalculate the tag on the entire string. So it is sensible to partition the string into blocks that are encrypted separately. And by encrypting each block with a different key, we ensure that a single key is not over-used. Also, we can pad the last block to hide the exact length of the string. ScramFS uses this approach to secure file contents.
Securing an entire file
There are further considerations to secure a file. In addition to encrypting and authenticating the file contents, ScramFS hides the file name, which is encrypted and authenticated in a similar manner to encrypting a string. Also, ScramFS hides the file’s modification time and plaintext size, which is encrypted and stored in the file body. To detect if the encrypted file has been renamed, or any contents of the file changed, ScramFS calculates an authentication tag on the file contents and name, and stores the tag in the file.
Securing a complete file system
Lastly, to secure a file system we need to encrypt and authenticate all of the file contents and all of the file and directory names. One principle need is to create a single master key from which all keys used in the file system can be derived or decrypted. This is a core aspect of ScramFS, which has been carefully designed to manage keys in a scalable manner so that the data security is not reduced as more data is added.
Securing against untrusted storage systems
Additionally, ScramFS does not reveal information to an attacker monitoring the file system calls, and will detect when the call return values have been falsified. ScramFS detects any new data that has been written to the file system by an attacker, or any modification to existing data.
Exposing a file system interface
Finally, in addition to securing the data, ScramFS provides a file system interface to the data. The ScramFS API provides the standard file system calls, such as open(), read(), write(), makedir(), listdir(), and remove(). An application using the ScramFS API sees the decrypted paths and file contents and ScramFS performs encryption and decryption needed to secure the stored data. Similarly to an unencrypted file system, ScramFS manages operations from concurrent threads and handles error conditions. In particular, ScramFS must manage the file system limitations imposed by the operating system, such as maximum lengths of names and paths, as well as handling a range of character formats and encodings.