Expand description
Sealing for the lacodda line: bytes sealed under a key, and a key locked under a passphrase.
Two formats, each a few bytes of header in front of an XChaCha20-Poly1305 ciphertext. The header says which format and which version it is, and everything a reader needs to open it except the secret - so a blob written today opens with a later release of this crate, and a blob from a newer format is refused by name instead of misread.
- A
Keyis 32 random bytes.Key::sealturns bytes into a sealed blob,Key::openturns it back - or fails, if the blob was sealed under another key, for another context, or changed on the way. - A
LockedKeyis a key wrapped under a passphrase: Argon2id stretches the passphrase into a key-encryption key, which seals the key. The Argon2id parameters and the salt travel in the header, so the lock can be stored anywhere - next to the data it protects, on a server that must not read it - and opened on any device that knows the passphrase.
Every blob is bound to a context chosen by the caller - a few bytes that say what the blob is for. Opening it under any other context fails, so a blob cannot be moved from one use to another and accepted there.
use lacodda_seal::{Key, LockedKey};
let key = Key::generate()?;
let sealed = key.seal(b"notes/v1", b"the plan for Tuesday")?;
assert_eq!(key.open(b"notes/v1", &sealed)?.as_slice(), b"the plan for Tuesday");
assert!(key.open(b"photos/v1", &sealed).is_err());
// The key itself, locked under a passphrase, can be stored in the open.
let lock = LockedKey::lock(&key, b"correct horse battery staple", b"notes/key")?;
let again = LockedKey::from_bytes(&lock.to_bytes())?.unlock(b"correct horse battery staple", b"notes/key")?;
assert_eq!(again.id(), key.id());The byte layouts are on the efema documentation site: https://lacodda.github.io/efema/concepts/sealing/.
Structs§
- KdfParams
- How hard Argon2id works to turn a passphrase into a key.
- Key
- A symmetric key: 32 bytes, wiped from memory when dropped.
- KeyId
- The identity of a key: eight bytes of a hash over it.
- Locked
Key - A key locked under a passphrase.
Enums§
- Error
- What can go wrong sealing, opening, locking or unlocking.
Constants§
- KEY_
ID_ LEN - Length of a key’s identity, in bytes.
- KEY_LEN
- Length of a key, in bytes.
- LOCKED_
LEN - Length of a locked key, in bytes: the header, the wrapped key and its tag.
- NONCE_
LEN - Length of an XChaCha20-Poly1305 nonce, in bytes.
- SALT_
LEN - Length of an Argon2id salt, in bytes.
- SEALED_
OVERHEAD - How many bytes sealing adds to the plaintext: the header and the tag.
- TAG_LEN
- Length of a Poly1305 tag, in bytes.
Functions§
- is_
locked_ key - Whether
bytesstart as a locked key does, whatever its version. - is_
sealed - Whether
bytesstart as a sealed blob does - the first byte of the format, whatever its version. For telling the two kinds apart when they travel side by side;Key::openstill decides whether one opens. - sealed_
key_ id - The identity of the key a sealed blob was sealed under, read from its header without opening it.