mirror of https://github.com/borgbackup/borg.git
docs: removed TAMs, introduce typed repo objects
This commit is contained in:
parent
d1fde11645
commit
bd1d734591
|
@ -365,7 +365,6 @@ or modified. It looks like this:
|
||||||
'time': '2017-05-05T12:42:22.942864',
|
'time': '2017-05-05T12:42:22.942864',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'tam': ...,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
The *version* field can be either 1 or 2. The versions differ in the
|
The *version* field can be either 1 or 2. The versions differ in the
|
||||||
|
@ -379,10 +378,6 @@ the repository. It is used by *borg check*, which verifies that all keys
|
||||||
in all items are a subset of these keys. Thus, an older version of *borg check*
|
in all items are a subset of these keys. Thus, an older version of *borg check*
|
||||||
supporting this mechanism can correctly detect keys introduced in later versions.
|
supporting this mechanism can correctly detect keys introduced in later versions.
|
||||||
|
|
||||||
The *tam* key is part of the :ref:`tertiary authentication mechanism <tam_description>`
|
|
||||||
(formerly known as "tertiary authentication for metadata") and authenticates
|
|
||||||
the manifest, since an ID check is not possible.
|
|
||||||
|
|
||||||
*config* is a general-purpose location for additional metadata. All versions
|
*config* is a general-purpose location for additional metadata. All versions
|
||||||
of Borg preserve its contents.
|
of Borg preserve its contents.
|
||||||
|
|
||||||
|
|
|
@ -67,43 +67,26 @@ in a particular part of its own data structure assigns this meaning.
|
||||||
This results in a directed acyclic graph of authentication from the manifest
|
This results in a directed acyclic graph of authentication from the manifest
|
||||||
to the data chunks of individual files.
|
to the data chunks of individual files.
|
||||||
|
|
||||||
.. _tam_description:
|
Above used to be all for borg 1.x and was the reason why it needed the
|
||||||
|
tertiary authentication mechanism (TAM) for manifest and archives.
|
||||||
|
|
||||||
.. rubric:: Authenticating the manifest
|
borg 2 now stores the ro_type ("meaning") of a repo object's data into that
|
||||||
|
object's metadata (like e.g.: manifest vs. archive vs. user file content data).
|
||||||
|
When loading data from the repo, borg verifies that the type of object it got
|
||||||
|
matches the type it wanted. borg 2 does not use TAMs any more.
|
||||||
|
|
||||||
Since the manifest has a fixed ID (000...000) the aforementioned authentication
|
As both the object's metadata and data are AEAD encrypted and also bound to
|
||||||
does not apply to it, indeed, cannot apply to it; it is impossible to authenticate
|
the object ID (via giving the ID as AAD), there is no way an attacker (without
|
||||||
the root node of a DAG through its edges, since the root node has no incoming edges.
|
access to the borg key) could change the type of the object or move content
|
||||||
|
to a different object ID.
|
||||||
|
|
||||||
With the scheme as described so far an attacker could easily replace the manifest,
|
This effectively 'anchors' the manifest (and also other metadata, like archives)
|
||||||
therefore Borg includes a tertiary authentication mechanism (TAM) that is applied
|
to the key, which is controlled by the client, thereby anchoring the entire DAG,
|
||||||
to the manifest (see :ref:`tam_vuln`).
|
making it impossible for an attacker to add, remove or modify any part of the
|
||||||
|
DAG without Borg being able to detect the tampering.
|
||||||
|
|
||||||
TAM works by deriving a separate key through HKDF_ from the other encryption and
|
Passphrase notes
|
||||||
authentication keys and calculating the HMAC of the metadata to authenticate [#]_::
|
----------------
|
||||||
|
|
||||||
# RANDOM(n) returns n random bytes
|
|
||||||
salt = RANDOM(64)
|
|
||||||
|
|
||||||
ikm = id_key || crypt_key
|
|
||||||
# *context* depends on the operation, for manifest authentication it is
|
|
||||||
# the ASCII string "borg-metadata-authentication-manifest".
|
|
||||||
tam_key = HKDF-SHA-512(ikm, salt, context)
|
|
||||||
|
|
||||||
# *data* is a dict-like structure
|
|
||||||
data[hmac] = zeroes
|
|
||||||
packed = pack(data)
|
|
||||||
data[hmac] = HMAC(tam_key, packed)
|
|
||||||
packed_authenticated = pack(data)
|
|
||||||
|
|
||||||
Since an attacker cannot gain access to this key and also cannot make the
|
|
||||||
client authenticate arbitrary data using this mechanism, the attacker is unable
|
|
||||||
to forge the authentication.
|
|
||||||
|
|
||||||
This effectively 'anchors' the manifest to the key, which is controlled by the
|
|
||||||
client, thereby anchoring the entire DAG, making it impossible for an attacker
|
|
||||||
to add, remove or modify any part of the DAG without Borg being able to detect
|
|
||||||
the tampering.
|
|
||||||
|
|
||||||
Note that when using BORG_PASSPHRASE the attacker cannot swap the *entire*
|
Note that when using BORG_PASSPHRASE the attacker cannot swap the *entire*
|
||||||
repository against a new repository with e.g. repokey mode and no passphrase,
|
repository against a new repository with e.g. repokey mode and no passphrase,
|
||||||
|
@ -113,11 +96,6 @@ However, interactively a user might not notice this kind of attack
|
||||||
immediately, if she assumes that the reason for the absent passphrase
|
immediately, if she assumes that the reason for the absent passphrase
|
||||||
prompt is a set BORG_PASSPHRASE. See issue :issue:`2169` for details.
|
prompt is a set BORG_PASSPHRASE. See issue :issue:`2169` for details.
|
||||||
|
|
||||||
.. [#] The reason why the authentication tag is stored in the packed
|
|
||||||
data itself is that older Borg versions can still read the
|
|
||||||
manifest this way, while a changed layout would have broken
|
|
||||||
compatibility.
|
|
||||||
|
|
||||||
.. _security_encryption:
|
.. _security_encryption:
|
||||||
|
|
||||||
Encryption
|
Encryption
|
||||||
|
|
Loading…
Reference in New Issue