Encrypted container, some kind of analogue to
=> CMS
=> LibrePGP
=> age
* Ability to use multiple recipients
* Either passphrase- or public-key based KEMs
* Hybrid PQ/T KEMs
* Ability to authenticate the sender
* Optionally anonymous recipients and sender
* Streaming friendly
* Ability to parallelise encryption/decryption procedures
* Current DEM schemes do explicit key commitment
* Current DEM schemes use key ratcheting and rotation
* Ability to safely encrypt to multiple recipients
Stored in a file, it should begin with "cm/enc/v0" [encoding/MAGIC].
magic {{field . {magic} =cm/enc/v0}}
encrypted {
{field . {map} len=~}
{field id {bin} >0 optional} {# UUID is preferable}
{field dem {with dem}}
{field kem {list} {of kem} >0}
{field pubs {list} {of type map} optional >0} {# attached public keys}
{field payload {bin} optional}
}
dem {
{field . {choice}}
{field xchapoly-krkc {nil}}
{field xchacha-krmr {nil}}
{field kuznechik-ctr-hmac-kr {nil}}
}
kem {
{field . {choice}}
{field sntrup761-x25519-hkdf-blake2b {with kem-with-encap}}
{field mceliece6960119-x25519-hkdf-shake256 {with kem-with-encap}}
{field gost3410-hkdf {with kem-gost3410-hkdf}}
{field balloon-blake2b-hkdf {with kem-balloon-blake2b-hkdf}}
{field pbkdf2-blake2b {with kem-pbkdf2}}
{field pbkdf2-streebog256 {with kem-pbkdf2}}
}
schema-include fpr.tcl
kem-with-encap {
{field . {map}}
{field to {with fpr} optional}
{field auth {bool} optional}
{field from {with fpr} optional}
{field encap {bin} >0}
{field cek-wrap {bin} >0}
}
kem-gost3410-hkdf {
{field . {map}}
{field to {with fpr} optional}
{field auth {bool} optional}
{field from {with fpr} optional}
{field ukm {bin} len=16} {# additional keying material}
{field pub {bin} >0} {# sender's ephemeral public key}
{field cek-wrap {bin} >0}
}
kem-balloon-blake2b-hkdf {
{field . {map}}
{field s {int} >0} {# space cost}
{field t {int} >0} {# time cost}
{field p {int} >0} {# parallel cost}
{field salt {bin} >0}
{field cek-wrap {bin} >0}
}
kem-pbkdf2 {
{field . {map}}
{field iter {int} >0}
{field salt {bin} >0}
{field cek-wrap {bin} >0}
}
"/payload" contains the ciphertext. It is encrypted with random "content
encryption key" (CEK) with an algorithm specified in "/dem" (data
encapsulation mechanism). "/dem" may contain additional fields
supplementing the decryption process, like initialisation vector.
If "/payload" is absent, then ciphertext is provided by other means, for
example just by following the "cm/encrypted" structure. It is recommended
to encode it as a BLOB, which chunk's length depends on DEM algorithm.
CEK is encapsulated in "/kem/*/cek-wrap" entries (key encapsulation
mechanisms).
If KEM uses public-key based cryptography, then recipient's
[cm/pub/]lic key(s) must be provided. Optional "/kem/*/to", public key's
fingerprint, may provide a hint to quickly search for the key on the
recipient's side.
Optional "/id" is used in KEMs for domain separation and envelope
identification. UUIDv4 is recommended. If absent, then empty string is
used in KDF.
It is *highly* recommended to use multi-recipient safe DEM when
encrypting to multiple recipients. For example [cm/dem/xchacha-krmr]
instead of [cm/dem/xchapoly-krkc], but unfortunately with the price of
more expensive double pass authentication scheme.
[cm/encrypted/authcrypt] -- authenticated public-key encryption
[cm/keywrap/] | key wrapping mechanisms
[cm/dem/] | data encapsulation mechanisms
[cm/kem/] | key encapsulation mechanisms