What is sanctum?
Sanctum is a small, reviewable, experimental and fully privilege seperated VPN daemon capable of transporting encrypted network traffic between two peers.
Multi-process
Sanctum is built using a multi-process approach where each process is only doing one thing. This allows for more fine-grained sandboxing in relation to permissions or allowed system calls.
Several different processes exist that all only perform one task:
- bless - The encryption process.
- confess - The decryption process.
- chapel - The key exchange process.
- heaven-rx - The red side receiving process.
- heaven-tx - The red side transmitting process.
- purgatory-rx - The black side receiving process.
- purgatory-tx - The black side transmitting process.
Packets flow between these processes in a well-defined manner making it impossible to move a packet straight from the red side to the black side without passing the encryption process and vice-versa.
Traffic encryption
Traffic is by default encrypted under AES256-GCM with unique keys in both RX and TX directions using a 96-bit nonce consisting of a 32-bit salt and a 64-bit packet counter (see rfc4106).
Using the CIPHER environment variable you can however change traffic encryption to use Agelas, which is an experimental duplex-sponge AEAD cipher based on the Keccak-p[1600,24] permutation.
Key exchange
Sanctum uses strong shared symmetrical secrets from which an encryption key is derived for wrapping a generated session key that is transmitted to its peer. Each sanctum instance is responsible for sending its RX session key to its configured peer periodically.
Keys are expired automatically after a given number of packets have been submitted on them (1 << 34), or after 1-hour.
The underlying algorithm for wrapping the generated session key is the AEAD duplex-sponge stream cipher mentioned earlier. The entire key derivation and offer process is as follows:
Wrapping key (wk) derivation: s = shared secret, 256-bit se = seed selected uniformly at random, 512-bit wk = KMAC256(s, len(se) || se), 512-bit Key offer: now = Seconds since boot, 64-bit salt = The salt for nonce construction, 32-bit id = unique sanctum ID generated at start, 64-bit key = session key selected uniformly at random, 256-bit seed = se from wk derivation above spi = The SPI for this association header = magic || spi || seed encdata = id || now || key || salt encdata = Agelas(wk, aad=header, encdata) send(header || encdata)
While this alone does not provide PFS, the underlying key may be swapped out OOB by other means while sanctum is running. I recommend you rotate this key often via a mechanism of your liking.
Why did you write sanctum?
I wrote it so I can be certain that my packets are blessed correctly according to the scriptures of cryptology.
Huh?
Ok, I wrote sanctum because I wanted something I can trust fully myself. I am a very private person and want to excercise my right to privacy, even online. There are definitely alternatives, but I opted to carve out something for myself.
Plus, it's cool to hack on stuff.
What makes you qualified to build this?
If you are asking yourself that question, that's ok. The people who know, know. I have been building these type of things for many years at high assurance levels. Now, if this makes you nervous and rather not use Sanctum that is fine, there are plenty of alternatives.
But none of them have cool mythology though ;)
Talks
I talked about sanctum at SEC-T 2024.
Source?
Latest release: sanctum 0.9.9
A mirror of the repository is available on github.
How?
A small simple guide is available here.
I want to contribute!
mail diffs to joris snabel-a sanctorum punkt se