Skip to content

Split repo-create --encryption into --mode, --encryption, and --hash (Borg 2 only) #9168

@PhrozenByte

Description

@PhrozenByte

/kind enhancement

Some prior, loosely related discussions can be found in #9103 and #9104.

Following the refactored init --encryption docs for Borg 1.4 (see #9103), we still have to update the docs for Borg 2. However, before doing that, I feel like that there's some room for improvement in regards to Borg 2's CLI of repo-create.

I like to suggest splitting the current --encryption option into separate --mode, --encryption, and --id-hash options (plus --unsafe-unencrypted option if #9104 is disregarded) as follows:

  • With the new -e / --encryption option users solely choose the encryption and authentication algorithm. It accepts none, aes256-ocb, and chacha20-poly1305. This option is required.
  • With the new -m / --mode option users choose where the key(s) shall be stored. It accepts repokey, and keyfile. It defaults to repokey if omitted. If --encryption none is given, --mode keyfile is rejected as invalid.
  • With the new -i / --id-hash option users choose the ID hash. It accepts sha256, and blake2. It defaults to sha256 if omitted.
  • If Consider deprecating init -e none now and removing it with Borg 2 #9104 is disregarded, the --unsafe-unencrypted option (no shorthand) is added to replace the old --encryption none option. --unsafe-unencrypted then is a highlander option for --mode, --encryption, and --id-hash. The name is chosen intentionally to further strengthen that Borg advises against using it.

Here's a translation table of the old and suggested new options in master:

Old --encryption New --mode New --encryption New --id-hash Notes
repokey-blake2-chacha20-poly1305 repokey chacha20-poly1305 blake2
keyfile-blake2-chacha20-poly1305 keyfile chacha20-poly1305 blake2
repokey-chacha20-poly1305 repokey chacha20-poly1305 sha256
keyfile-chacha20-poly1305 keyfile chacha20-poly1305 sha256
repokey-blake2-aes-ocb repokey aes256-ocb blake2
keyfile-blake2-aes-ocb keyfile aes256-ocb blake2
repokey-aes-ocb repokey aes256-ocb sha256
keyfile-aes-ocb keyfile aes256-ocb sha256
authenticated-blake2 repokey none blake2
keyfile none blake2 Not supported
authenticated repokey none sha256
keyfile none sha256 Not supported
none Use --unsafe-unencrypted instead

Reasoning:

Borg's --encryption option has grown over the years: Borg initially started with the none, repokey, and keyfile modes. Users chose the mode depending on whether they wanted encryption, and where to store the key(s). Borg 1.1 later added authenticated as an unencrypted, but authenticated alternative somewhere between none and repokey, but also added *-blake2 counterparts for all modes to use BLAKE2b-256 instead of HMAC-SHA256 for authentication. IMHO and in retrospect, the *-blake2 counterparts probably should have been a separate option instead.

Borg 2 now switches to AES-OCB in favour of AES-CTR and, more critically, adds support for CHACHA20-POLY1305, increasing the number of alternatives from 7 to 11. The docs now have to use a K placeholder to shorten the repokey and keyfile alternatives, because there are simply too many alternatives otherwise.

So, I believe it's better to split the old --encryption option into distinct decisions: The encryption algorithm to use (new --encryption), where to store the key(s) (new --mode), and what ID hash to use (new --id-hash).

Open questions / further considerations:

  • I was initially thinking about splitting the new --encryption option even further into separate --encryption and --authentication options. --encryption would then solely choose the encryption algorithm, and --authentication the authentication algorithm. --mode repokey --id-hash blake2 --encryption aes256 --authentication blake2b would then match --encryption repokey-blake2 with Borg 1.4 (I think?). However, this would allow for non-standardised and never formally analysed combinations like AES256 with POLY1305, or CHACHA20 with BLAKE2b. That's probably a bad idea security-wise… And probably provides no benefit anyway.

    The reason why I'm bringing this up is because I wanted to ask whether there's anything else that might be added in the future that would be more than just adding another value to the suggested --encryption, --mode, and --id-hash options, or that would require changing what these options mean. This includes distant, i.e. not yet decided, but thinkable ideas. I'm thinking about post-quantum crypto or stuff like that (again, I'm no encryption expert, so my question might indeed be a bit silly, I just don't know). WDYT?

  • Why does {repokey,keyfile}-chacha20-poly1305 use HMAC-SHA256 as ID-Hash and not a simple SHA256?

  • The --mode option doesn't have to be limited to repokey and keyfile in the future. I'm thinking about e.g. storing the keys on security devices (loosely related: [RFC] Introduce support for FIDO2 to protect keys #8995), or using 3rd-party APIs to store/read keys (e.g. password managers).

  • Instead of making --id-hash optional, we could also force users to make an informed decision (i.e. run some benchmarks first) by requiring not only --encryption, but also --id-hash.

Changes to suggestion:

  • 2025-11-21: --hash renamed to --id-hash to minimise confusion with the auth part of --encryption

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions