crates/veilvoice-crypto/src/container.rs
veilvoice-crypto · 618 lines · read the source here · or on GitHub
The .veil encrypted container format.
A single self-describing blob: everything needed to decrypt except the password or private key travels with the ciphertext, so a file stays readable after the default KDF costs are raised.
offset size field
0 8 magic "VEILVOX1"
8 1 format version (1)
9 1 mode: 1 = password, 2 = hybrid public key
10 2 reserved, must be zero
12 4 Argon2id m_cost (KiB, little-endian) password mode only
16 4 Argon2id t_cost password mode only
20 4 Argon2id p_cost password mode only
24 16 Argon2id salt password mode only
40 24 XChaCha20 nonce
64 4 encapsulation length (little-endian)
68 N encapsulation hybrid mode only
68+N … ciphertext ‖ Poly1305 tag
The entire header is the AEAD's associated data. Editing any byte of it by downgrading the KDF cost, swapping the mode or corrupting the salt, makes decryption fail rather than silently changing behaviour. Unused fields are written as zero and are still authenticated, so they cannot be used as a covert channel or a downgrade vector.
In plain words
The shape of an encrypted .veil file.
Everything needed to open it travels inside it, apart from the passphrase or the key. That means a file made today still opens years later, even after VeilVoice has changed how hard it makes the encryption by default: the file remembers what it was made with.
The part at the front that describes the file is itself covered by the tamper check, so it cannot be edited to make the rest open more easily.
WHAT THIS FILE CONTAINS
618 lines defining 9 functions (8 public), 2 types and 5 constants. Everything below is read out of the source, so it cannot disagree with the code.
The types it owns.
enum Modeline 56 · How a container is locked.struct Headerline 65 · A parsed container header.
What happens when it runs. These are the ways in: public, and nothing else in this file calls them, so they are what an outside caller reaches first.
Header::to_bytesline 81 · Serialise exactly as it appears on disk.veil_pathline 180 · The conventional path of the sealed form of path.seal_with_passwordline 193 · Encrypt plaintext under a password.
reachesfinishseal_to_public_keyline 210 · Encrypt plaintext to a recipient's hybrid public key.
reachesfinishopen_with_passwordline 244 · Decrypt a password-locked container.
reachesopen_with_password_within,parseopen_with_secret_keyline 276 · Decrypt a container addressed to recipient.
reachesparse
WHAT CALLS WHAT
The functions this file defines, and the calls between them. An edge means the callee's name appears, called, inside the caller's body. This is a syntactic reading, not a type-resolved one.
The same graph as Mermaid source
%%{init: {"theme":"base","themeVariables":{"background":"#1a1b26","primaryColor":"#1f2335","primaryTextColor":"#c0caf5","primaryBorderColor":"#7aa2f7","secondaryColor":"#16161e","tertiaryColor":"#16161e","lineColor":"#737aa2","textColor":"#c0caf5","mainBkg":"#1f2335","nodeBorder":"#7aa2f7","clusterBkg":"#16161e","clusterBorder":"#2f3549","fontFamily":"ui-monospace, SFMono-Regular, Consolas, monospace","fontSize":"14px"}}}%%
flowchart TD
n_to_bytes(["Header::to_bytes<br/>line 81"])
n_parse["Header::parse<br/>line 101"]
n_veil_path(["veil_path<br/>line 180"])
n_seal_with_password(["seal_with_password<br/>line 193"])
n_seal_to_public_key(["seal_to_public_key<br/>line 210"])
n_finish["finish<br/>line 235"]
n_open_with_password(["open_with_password<br/>line 244"])
n_open_with_password_within["open_with_password_within<br/>line 260"]
n_open_with_secret_key(["open_with_secret_key<br/>line 276"])
n_open_with_password --> n_open_with_password_within
n_open_with_password_within --> n_parse
n_open_with_secret_key --> n_parse
n_seal_to_public_key --> n_finish
n_seal_with_password --> n_finish
click n_to_bytes href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/container.rs#L81" "open the source"
click n_parse href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/container.rs#L101" "open the source"
click n_veil_path href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/container.rs#L180" "open the source"
click n_seal_with_password href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/container.rs#L193" "open the source"
click n_seal_to_public_key href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/container.rs#L210" "open the source"
click n_finish href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/container.rs#L235" "open the source"
click n_open_with_password href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/container.rs#L244" "open the source"
click n_open_with_password_within href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/container.rs#L260" "open the source"
click n_open_with_secret_key href "https://github.com/tilas01/veilvoice/blob/main/crates/veilvoice-crypto/src/container.rs#L276" "open the source"
classDef entry fill:#1f2335,stroke:#7aa2f7,color:#c0caf5
class n_to_bytes,n_veil_path,n_seal_with_password,n_seal_to_public_key,n_open_with_password,n_open_with_secret_key entry
classDef api fill:#1f2335,stroke:#7dcfff,color:#c0caf5
class n_parse,n_open_with_password_within api
classDef helper fill:#1f2335,stroke:#bb9af7,color:#c0caf5
class n_finish helper
This site loads no third-party script, so it cannot run Mermaid; the diagram above is the same nodes and edges drawn by the generator instead. GitHub renders the source below directly.
ITEMS
| Item | Line | Documentation |
|---|---|---|
MAGIC pub const | 45 | Magic bytes at the start of every container. |
FORMAT_VERSION pub const | 47 | Format version this build writes. |
HEADER_LEN pub const | 49 | Fixed header length in bytes, before any encapsulation. |
MODE_PASSWORD const | 51 | |
MODE_HYBRID const | 52 | |
Mode pub enum | 56 | How a container is locked. |
Header pub struct | 65 | A parsed container header. |
Header::to_bytes pub fn | 81 | Serialise exactly as it appears on disk. |
Header::parse pub fn | 101 | Parse a header, returning it with the offset at which ciphertext starts. |
veil_path pub fn | 180 | The conventional path of the sealed form of path. |
seal_with_password pub fn | 193 | Encrypt plaintext under a password. |
seal_to_public_key pub fn | 210 | Encrypt plaintext to a recipient's hybrid public key. |
finish fn | 235 | Seal plaintext under header and return the whole file. |
open_with_password pub fn | 244 | Decrypt a password-locked container. |
open_with_password_within pub fn | 260 | Decrypt a password-locked container, refusing one that declares a memory cost above max_m_cost. |
open_with_secret_key pub fn | 276 | Decrypt a container addressed to recipient. |