|
@@ -124,7 +124,88 @@ prompt is a set BORG_PASSPHRASE. See issue :issue:`2169` for details.
|
|
|
Encryption
|
|
|
----------
|
|
|
|
|
|
-Encryption is currently based on the Encrypt-then-MAC construction,
|
|
|
+AEAD modes
|
|
|
+~~~~~~~~~~
|
|
|
+
|
|
|
+Modes: --encryption (repokey|keyfile)-[blake2-](aes-ocb|chacha20-poly1305)
|
|
|
+
|
|
|
+Supported: borg 1.3+
|
|
|
+
|
|
|
+Encryption with these modes is based on AEAD ciphers (authenticated encryption
|
|
|
+with associated data) and session keys.
|
|
|
+
|
|
|
+Depending on the chosen mode (see :ref:`borg_init`) different AEAD ciphers are used:
|
|
|
+
|
|
|
+- AES-256-OCB - super fast, single-pass algorithm IF you have hw accelerated AES.
|
|
|
+- chacha20-poly1305 - very fast, purely software based AEAD cipher.
|
|
|
+
|
|
|
+The chunk ID is derived via a MAC over the plaintext (mac key taken from borg key):
|
|
|
+
|
|
|
+- HMAC-SHA256 - super fast IF you have hw accelerated SHA256.
|
|
|
+- Blake2b - very fast, purely software based algorithm.
|
|
|
+
|
|
|
+For each borg invocation, a new session id is generated by `os.urandom`_.
|
|
|
+
|
|
|
+From that session id, the initial key material (ikm, taken from the borg key)
|
|
|
+and an application and cipher specific salt, borg derives a session key via HKDF.
|
|
|
+
|
|
|
+For each session key, IVs (nonces) are generated by a counter which increments for
|
|
|
+each encrypted message.
|
|
|
+
|
|
|
+Session::
|
|
|
+
|
|
|
+ sessionid = os.urandom(24)
|
|
|
+ ikm = enc_key || enc_hmac_key
|
|
|
+ salt = "borg-session-key-CIPHERNAME"
|
|
|
+ sessionkey = HKDF(ikm, sessionid, salt)
|
|
|
+ message_iv = 0
|
|
|
+
|
|
|
+Encryption::
|
|
|
+
|
|
|
+ id = MAC(id_key, data)
|
|
|
+ compressed = compress(data)
|
|
|
+
|
|
|
+ header = type-byte || 00h || message_iv || sessionid
|
|
|
+ aad = id || header
|
|
|
+ message_iv++
|
|
|
+ encrypted, auth_tag = AEAD_encrypt(session_key, message_iv, compressed, aad)
|
|
|
+ authenticated = header || auth_tag || encrypted
|
|
|
+
|
|
|
+Decryption::
|
|
|
+
|
|
|
+ # Given: input *authenticated* data and a *chunk-id* to assert
|
|
|
+ type-byte, past_message_iv, past_sessionid, auth_tag, encrypted = SPLIT(authenticated)
|
|
|
+
|
|
|
+ ASSERT(type-byte is correct)
|
|
|
+
|
|
|
+ past_key = HKDF(ikm, past_sessionid, salt)
|
|
|
+ decrypted = AEAD_decrypt(past_key, past_message_iv, authenticated)
|
|
|
+
|
|
|
+ decompressed = decompress(decrypted)
|
|
|
+
|
|
|
+ ASSERT( CONSTANT-TIME-COMPARISON( chunk-id, MAC(id_key, decompressed) ) )
|
|
|
+
|
|
|
+Notable:
|
|
|
+
|
|
|
+- More modern and often faster AEAD ciphers instead of self-assembled stuff.
|
|
|
+- Due to the usage of session keys, IVs (nonces) do not need special care here as
|
|
|
+ they did for the legacy encryption modes.
|
|
|
+- The id is now also input into the authentication tag computation.
|
|
|
+ This strongly associates the id with the written data (== associates the key with
|
|
|
+ the value). When later reading the data for some id, authentication will only
|
|
|
+ succeed if what we get was really written by us for that id.
|
|
|
+
|
|
|
+
|
|
|
+Legacy modes
|
|
|
+~~~~~~~~~~~~
|
|
|
+
|
|
|
+Modes: --encryption (repokey|keyfile)-[blake2]
|
|
|
+
|
|
|
+Supported: all borg versions, blake2 since 1.1
|
|
|
+
|
|
|
+DEPRECATED. We strongly suggest you use the safer AEAD modes, see above.
|
|
|
+
|
|
|
+Encryption with these modes is based on the Encrypt-then-MAC construction,
|
|
|
which is generally seen as the most robust way to create an authenticated
|
|
|
encryption scheme from encryption and message authentication primitives.
|
|
|
|
|
@@ -253,7 +334,7 @@ Implementations used
|
|
|
We do not implement cryptographic primitives ourselves, but rely
|
|
|
on widely used libraries providing them:
|
|
|
|
|
|
-- AES-CTR and HMAC-SHA-256 from OpenSSL 1.0 / 1.1 are used,
|
|
|
+- AES-CTR, AES-OCB, CHACHA20-POLY1305 and HMAC-SHA-256 from OpenSSL 1.1 are used,
|
|
|
which is also linked into the static binaries we provide.
|
|
|
We think this is not an additional risk, since we don't ever
|
|
|
use OpenSSL's networking, TLS or X.509 code, but only their
|
|
@@ -268,7 +349,8 @@ on widely used libraries providing them:
|
|
|
|
|
|
Implemented cryptographic constructions are:
|
|
|
|
|
|
-- Encrypt-then-MAC based on AES-256-CTR and either HMAC-SHA-256
|
|
|
+- AEAD modes: AES-OCB and CHACHA20-POLY1305 are straight from OpenSSL.
|
|
|
+- Legacy modes: Encrypt-then-MAC based on AES-256-CTR and either HMAC-SHA-256
|
|
|
or keyed BLAKE2b256 as described above under Encryption_.
|
|
|
- Encrypt-and-MAC based on AES-256-CTR and HMAC-SHA-256
|
|
|
as described above under `Offline key security`_.
|