I, Tanveer Salim, am the sole team member of this project.
The eCryptfs project served as the inspiration for this project. (https://www.ecryptfs.org/). eCryptfs is a kernel project that serves as a cryptographic filesystem for Linux. This means eCryptfs will literally encrypt every individual file in each directory throughout the root directory of the user. This will protect machines from malware that may try to steal sensitive information from a computer while the machine is running live in session. Whereas a cryptographic filesystem can protect a machine's sensitive information from being compromised live while it is active and in session, full-disk encryption can only protect a machine's sensitive information while the machine is off. Further information on Cryptographic filesystems can be found at: https://en.wikipedia.org/wiki/Filesystem-level_encryption.
The eCryptfs project is now owned by Canonical, which is the corporation behind Ubuntu. eCryptfs is featured in Ubuntu's Encrypted Home Directory, Google Chrome's OS, and is used in several Network Attached Storage Devices.
I myself use a basic Network Attached Storage Device that hosts my personal sensitive information. This is why eCryptfs caught my interest.
eCryptfs offers symmetric ciphers like AES-256 to encrypt files. However, I am personally interested in using ChaCha20 with eCryptfs instead of AES-256 since ChaCha20 defends against Cache-Collision Timing Attacks (https://www.microsoft.com/en-us/research/publication/cache-collision-timing-attacks-against-aes/?from=http%3A%2F%2Fresearch.microsoft.com%2Fpubs%2F64024%2Faes-timing.pdf). Moreover, the ChaCha20 cipher performs faster than AES-256.
My biggest ambition in implementing ChaCha20 as a Linux Kernel Module is to ultimately have it incorporated as an additional cipher to the eCryptfs project.
What it does
The ChaCha20 Linux Kernel Module encrypts a file using a key and a nonce that the user specifies. If the user wishes, both the key and the nonce may be randomly generated. The demonstration code uses the key and the nonce used in Section 2.4.2 in RFC 8439 (https://tools.ietf.org/html/rfc8439#section-2.4.2) to help judges verify that the cipher really does work. There is a test text file that is almost exactly like the test file featured in Section 2.4.2 (named "test.txt" in my GitHub directory) to also help judges verify that the cipher really works. The cipher in the demonstration code will output the encrypted file as "test.out.txt" and the decrypted file as "test.out.txt.recover".
How I built it
I built this cipher program as a Linux Kernel module and therefore it is written in BASH and the C Programming Language. I followed the guidelines in RFC 8439. The information for designing this cipher in RFC 8439 is found in Chapters 1 and 2.
Challenges I ran into
- The biggest challenge is that the Linux Kernel does not have access to the C Standard Library. This is the reason why I had to write the cipher from scratch. Had Linux Kernel Developers been able to access the C Standard Library from inside the kernel, this project would not need to exist. There are special libraries that the Linux Kernel has access to whose header files are found in the /usr/include/linux directory. Linux Kernel Developers must work with those libraries to build the code they need. This made reading and writing files difficult. Care had to be taken in ensuring not too much RAM memory was used in reading the entire contents of a file. To solve this problem I programmed ChaCha20 to read the contents of a file 64 bytes at a time. This was especially tricky to learn how to do using the kernel_read() and kernel_write() functions used in the chacha20() in this project.
- Dealing with physical RAM memory in a Linux Kernel Module proved to be difficult. The Linux Kernel Module shows no tolerance for code that makes the grave mistake of committing a stack overflow error. When I committed this fatal memory error, every time I switched the screen back to my X server screen, the computer would completely freeze. The only way out was to forcibly shut down my machine and start the machine up all over again.
- I learned you cannot use floating point operations in the Linux Kernel during this project. I was supposed to originally take advantage of that to help calculate how many times I needed to read the input file 64 bytes at a time. I worked around this by using two index variables (i and n) in the chacha20() function instead.
Accomplishments that I'm proud of
- This is my first ever Linux Kernel Module project that really does perform a useful service (an encryption software). I intend to be a Linux Kernel Developer so this is very good training for the job I hope I will one day attain...hopefully at Canonical since they own the eCryptfs project.
What I learned
- This project served as an introduction as to what it is like to be a Linux Kernel Developer. This experience helped me verify that I really would enjoy doing Linux Kernel Development as a professional career.
- Of course, I also learned how the ChaCha20 cipher works. It is amazing how simple the design of ChaCha20 is. The ChaCha20 cipher was designed to be simple in implementation on purpose. The simpler the implementation of a security protocol, the less security bugs will exist in said implementation.
What's next for chacha20_kernel_module
- One of the most straightforward courses of action for this project is to next implement Poly1305 as a Linux Kernel Module. This is also specified in RFC 8439. I began writing this during this hackathon but have still not completed its implementation. Poly1305 is a Message Authentication Code that can be used with ChaCha20 to help verify that a message has not been tampered with.
- Secondly, I should also implement the rest of the ciphers featured in the Networking and Cryptographic Library (NaCl) (https://nacl.cr.yp.to/) as Linux Kernel Modules. The author of ChaCha20, Daniel J Bernstein, is also a head developer of this library that is growing in recognition. eCryptfs actually has a gnupg-like interface to help it encrypt data and it would be nice if the ciphers featured in NaCl were added to eCryptfs to strengthen encryption. Implementing the asymmetric ciphers in NaCl (e.g. crypto_box() ) would be especially important since these are asymmetric ciphers that also defend against Cache-Collision Timing