An opinionated and modular toolchain for generating and managing a wide range of cryptographic keys offline and on smartcards from a shared bip39 mnemonic phrase.
Go to file
Ryan Heywood c6f3eac727
README: add instructions for storing entropy
2024-01-09 20:41:57 -05:00
keyfork keyfork-entropy: split off from keyfork-plumbing, ensure_safe() always 2024-01-09 19:59:58 -05:00
keyfork-derive-key add licenses 2023-11-16 21:56:57 -05:00
keyfork-derive-openpgp keyfork: impl `derive openpgp` 2024-01-07 03:20:17 -05:00
keyfork-derive-path-data keyfork-derive-path-data: make clippy happy 2024-01-06 23:19:47 -05:00
keyfork-derive-util keyfork: impl `derive openpgp` 2024-01-07 03:20:17 -05:00
keyfork-entropy keyfork-entropy: split off from keyfork-plumbing, ensure_safe() always 2024-01-09 19:59:58 -05:00
keyfork-frame add licenses 2023-11-16 21:56:57 -05:00
keyfork-mnemonic-util keyfork-mnemonic-util: make clippy happy 2024-01-06 23:20:19 -05:00
keyfork-plumbing keyfork-entropy: split off from keyfork-plumbing, ensure_safe() always 2024-01-09 19:59:58 -05:00
keyfork-prompt keyfork-prompt: add validator system 2024-01-09 02:21:46 -05:00
keyfork-shard keyfork-shard: add prompt for loading any smartcard 2024-01-09 19:28:02 -05:00
keyfork-slip10-test-data add licenses 2023-11-16 21:56:57 -05:00
keyfork-user-guide keyfork-user-guide: add shard commands guide 2024-01-08 19:17:49 -05:00
keyforkd keyfork: start tracing for `recover` 2024-01-07 00:36:23 -05:00
keyforkd-client keyforkd-client: fixup error message 2024-01-08 14:06:03 -05:00
keyforkd-models add licenses 2023-11-16 21:56:57 -05:00
smex add licenses 2023-11-16 21:56:57 -05:00
.gitignore keyfork-user-guide: more additions 2023-10-19 08:53:59 -05:00
Cargo.lock keyfork-entropy: split off from keyfork-plumbing, ensure_safe() always 2024-01-09 19:59:58 -05:00
Cargo.toml keyfork-entropy: split off from keyfork-plumbing, ensure_safe() always 2024-01-09 19:59:58 -05:00
LICENSE-AGPL-3.0.txt add licenses 2023-11-16 21:56:57 -05:00
LICENSE-MIT.txt add licenses 2023-11-16 21:56:57 -05:00
README.md README: add instructions for storing entropy 2024-01-09 20:41:57 -05:00
deny.toml deny.toml: add more license permissions and override for Boost license for xxhash-rust 2023-10-06 16:21:24 -05:00

README.md

keyfork

An opinionated and modular toolchain for generating and managing a wide range of cryptographic keys offline and on smartcards from a shared bip39 mnemonic phrase.

This toolchain uses a bip32 seed loaded into an agent to generate deterministic and unique keypairs. This ensures only the agent has control over the mnemonic itself, and other components can simply request deterministic data.

This repository must not be managed by cargo-hakari, to ensure each plumbing binary can be built with as few dependencies and SLOC to review as possible.

Dependency Policy

Dependencies must not be added to core utilities such as seed generation and path derivation without a really good reason we can't implement it ourselves, such as cryptography libraries. For instance, keyfork-derive-util only utilizes cryptography libraries, serde, and thiserror, with the latter two being audited dependencies. Utilities such as forklets (applications that use derived data, such as an OpenPGP keychain generator) and the kitchen-sink keyfork utility may pull in additional dependencies as needed, but should strive to use the standard library as much as possible. To avoid code reuse, additional crates (such as the smex crate) may be used to share functionality across several crates.

Keyfork Top-Level Binary

The keyfork binary is the most user-friendly interface for interacting with the Keyfork toolchain. It offers commands that should not take any scriptable input and should not produce any script-readable output. Such operations that require script compatibility should be made into their own utilities, with the higher level interface of interacting with them left solely to keyfork.

For instance, the program to generate system entropy is keyfork-entropy. It accepts an arbitrary length and spits out a hex-encoded chunk of data. The program to convert that entropy into a seed is keyfork-mnemonic-from-seed. It takes entropy from input and converts it into a seed. The combination of the two, generating entropy and converting it to a mnemonic, is managed through Keyfork: keyfork mnemonic generate, which can also be used to offer more options down the line, such as generating a mnemonic from tarot or playing cards, or dice.


Note: The following document is all proposed, and not yet implemented.

Features

  • Modular
    • Standalone binaries can derive/manage keys/config from bip32 root
    • Modules handle use cases like ssh, pgp, webauthn, crypto-assets, etc
    • Module contract is dead simple and can be written in any language
  • Recoverable
    • Config file and 24 word mnemonic phrase to recover -all- keys
  • Unpredictable
    • Generate a BIP39 phrase from OS entropy
    • Take BIP39 passphrase from user supplied entropy
    • Read up on https://milksad.info to understand why this matters!
  • Offline
    • Will exit if network access is detected to force you to keep keys offline
    • Helps limit the risk of supply chain attacks
    • Intended for use with QubesOS Vault VM, AirgapOS, etc
    • Private keys are installed to HSMs/TEEs for use by online machines

Install

These steps will allow you to prove that at least two Distrust engineers signed off on the produced binaries, signaling that they reproduced them from source code and got identical results, in addition to our usual two-party code review processes.

This minimizes a single point of trust (and failure) in our binary release process.

See the Reproducible Builds project for more information on these practices.

We use git for all development, releases, and signing. Unfortunately git has no native method for large file storage or multi-signature workflows so some git add-ons are required.

To follow these steps please install git-lfs and git-sig.

  1. Clone repo

    git clone https://git.distrust.co/public/keyfork
    cd keyfork
    
  2. Review binary signatures

    git sig verify
    

    Note: See Trust section below for expected keys/signers

  3. Install binary

    make install
    

Basic Usage

Personal Setup

On an airgapped system, run the following command to generate a BIP-0039 mnemonic encoding a generated seed:

keyfork mnemonic generate

Once generated, the mnemonic should be written down and stored in a secure location such as a safe.

The Keyfork server can be started by running the following command:

keyfork recover mnemonic

Group Setup

This guide assumes you are sharding to an N-of-M system with I smart cards per shardholder. The variables will be used in the following commands as $N, $M, and $I. The smart cards will be factory reset during the process.

On an airgapped system, run the following command to generate a file containing encrypted shards of a generated seed:

keyfork wizard generate-shard-secret --threshold $N --max $M --keys-per-shard $I > shards.pgp

Once generated, the shards file can be safely stored in any location, as the only information that can be obtained from the shard file is the $N value.

If all shardholders are physically present, the Keyfork server can be started by running the following command:

keyfork recover shard

Otherwise, the Keyfork server can be started by transporting the shards to the machine using the following command:

keyfork recover remote-shard

Each shard can be transported by running the following command:

keyfork shard transport shard.pgp

Deriving Keys

Keys can be derived from Keyfork using the keyfork derive command, such as the following command for an OpenPGP certificate with one of each subkey:

keyfork derive openpgp "Ryan Heywood (RyanSquared) <ryan@distrust.co>"

Usage

Detailed usage instructions can be found in the keyfork-user-guide mdBook, which can be opened in-browser by running mdbook serve --open keyfork-user-guide.