diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e6c4628 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,141 @@ +# Keyfork v0.2.0 + +Some of the changes in this release are based on feedback from audits +(publications coming soon!). The previous version of Keyfork, in almost every +configuration, is safe to use. The most significant change in this version +affects Keyfork Shard, which has an incompatible difference between this +version and the previous version. Information about shards, such as the length +of the shard, could be leaked and discovered by an attacker when using the +Remote Shard recovery mechanism. + +An additional change is the requirement of hardened indices on the first two +levels of key derivation. This is due to Keyfork potentially leaking private +keys when hardened derivation is not used. To be completely honest, I don't +entirely understand the math behind it. + +There is no reason to upgrade if Keyfork has been used as-is, as all supported +provisioners at this point in time require hardened derivation at all steps. + +### Changes in keyfork: + +``` +d04989e keyfork-derive-util: make key parsing fallible again, since secp256k1 isn't guaranteed correct +5d2309e keyfork-prompt: add SecurePinValidator for making new, secure, PINs +cdf4015 keyfork wizard: use correct derivation path for re-deriving shard decryption keys +f0e5ae9 keyfork-derive-openpgp: document KEYFORK_OPENPGP_EXPIRE +289cec3 keyfork wizard: upcast i and index to avoid wrapping add +9394500 keyfork-shard: generate nonce using hkdf +``` + +### Changes in keyfork-derive-openpgp: + +``` +f0e5ae9 keyfork-derive-openpgp: document KEYFORK_OPENPGP_EXPIRE +9f089e7 keyfork-derive-openpgp: use .first() in place of .get(0) +``` + +### Changes in keyfork-derive-util: + +``` +de4e98a keyfork-derive-util: black-box checking all zeroes +48ccd7c keyfork-derive-util: add note about potential side-channel when verifying keys +d04989e keyfork-derive-util: make key parsing fallible again, since secp256k1 isn't guaranteed correct +1de466c keyfork-derive-util: allow zeroable input for non-master-key derivation +61871a7 keyfork-derive-util: make private and public test keys more visible +2bca0a1 keyfork-derive-util: make Test{Public,Private}Key public, rename Internal algorithm +``` + +### Changes in keyfork-entropy: + +``` +5438f4e keyfork-entropy: downgrade entropy size limit to warning +``` + +### Changes in keyfork-mnemonic-util: + +``` +001fc0b remove trailing hitespace :( +6a265ad keyfork-mnemonic-util: add MnemonicBase::from_nonstandard_bytes +``` + +### Changes in keyfork-prompt: + +``` +5d2309e keyfork-prompt: add SecurePinValidator for making new, secure, PINs +``` + +### Changes in keyfork-qrcode: + +``` +fa125e7 keyfork-qrcode: prefer Instant over SystemTime for infallible time comparison +``` + +### Changes in keyfork-shard: + +``` +d04989e keyfork-derive-util: make key parsing fallible again, since secp256k1 isn't guaranteed correct +1a036a0 keyfork-shard: clean up documentation for encrypted shard padding +e068743 keyfork-shard: display error message on duplicate key fingerprints found +23db509 keyfork-shard: improve wording for counting shardholders +9461772 keyfork-shard: ignore duplicate certificate entries +6a265ad keyfork-mnemonic-util: add MnemonicBase::from_nonstandard_bytes +c0b19e2 keyfork-shard: assert shared secrets are contributory +0fe5301 keyfork-shard: add in bug messages +08a66e2 keyfork-shard: base64 encode content instead of base16 +6fa434e keyfork-shard: shorten length and pad inside encrypted block +9394500 keyfork-shard: generate nonce using hkdf +194d475 keyfork-shard: validate signatures using shard-specific validation requirements +``` + +### Changes in keyfork-zbar: + +``` +0c76869 .cargo/config.toml: add registry configuration :) +``` + +### Changes in keyforkd: + +``` +bcfcc87 keyforkd: add warning when loading seed with less than 128 bits +40551a5 keyforkd: require hardened derivation on two highest indexes +``` + +### Changes in keyforkd-client: + +``` +d04989e keyfork-derive-util: make key parsing fallible again, since secp256k1 isn't guaranteed correct +1de466c keyfork-derive-util: allow zeroable input for non-master-key derivation +40551a5 keyforkd: require hardened derivation on two highest indexes +``` + +### Changes in keyforkd-models: + +``` +40551a5 keyforkd: require hardened derivation on two highest indexes +``` + +# Keyfork v0.1.0 + +### Tagged releases: + +* `keyfork-bin 0.1.0` +* `keyfork-bug 0.1.0` +* `keyfork-crossterm 0.27.1` +* `keyfork-derive-key 0.1.0` +* `keyfork-derive-openpgp 0.1.0` +* `keyfork-derive-path-data 0.1.0` +* `keyfork-derive-util 0.1.0` +* `keyfork-entropy 0.1.0` +* `keyfork-frame 0.1.0` +* `keyfork-mnemonic-util 0.2.0` +* `keyfork-prompt 0.1.0` +* `keyfork-qrcode 0.1.0` +* `keyfork-shard 0.1.0` +* `keyfork-slip10-test-data 0.1.0` +* `keyfork 0.1.0` +* `keyfork-zbar-sys 0.1.0` +* `keyfork-zbar 0.1.0` +* `keyforkd-client 0.1.0` +* `keyforkd-models 0.1.0` +* `keyforkd 0.1.0` +* `smex 0.1.0` diff --git a/Cargo.lock b/Cargo.lock index d784e72..f810780 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1674,7 +1674,7 @@ dependencies = [ [[package]] name = "keyfork" -version = "0.1.0" +version = "0.2.0" dependencies = [ "card-backend-pcsc", "clap", @@ -1734,7 +1734,7 @@ dependencies = [ [[package]] name = "keyfork-derive-key" -version = "0.1.0" +version = "0.1.1" dependencies = [ "keyfork-derive-util", "keyforkd-client", @@ -1744,7 +1744,7 @@ dependencies = [ [[package]] name = "keyfork-derive-openpgp" -version = "0.1.0" +version = "0.1.1" dependencies = [ "anyhow", "ed25519-dalek", @@ -1756,14 +1756,14 @@ dependencies = [ [[package]] name = "keyfork-derive-path-data" -version = "0.1.0" +version = "0.1.1" dependencies = [ "keyfork-derive-util", ] [[package]] name = "keyfork-derive-util" -version = "0.1.1" +version = "0.2.0" dependencies = [ "digest", "ed25519-dalek", @@ -1799,7 +1799,7 @@ dependencies = [ [[package]] name = "keyfork-mnemonic-util" -version = "0.2.0" +version = "0.3.0" dependencies = [ "bip39", "hex", @@ -1813,7 +1813,7 @@ dependencies = [ [[package]] name = "keyfork-prompt" -version = "0.1.0" +version = "0.1.1" dependencies = [ "keyfork-bug", "keyfork-crossterm", @@ -1908,7 +1908,7 @@ dependencies = [ [[package]] name = "keyforkd-client" -version = "0.1.0" +version = "0.2.0" dependencies = [ "bincode", "ed25519-dalek", @@ -1923,7 +1923,7 @@ dependencies = [ [[package]] name = "keyforkd-models" -version = "0.1.0" +version = "0.2.0" dependencies = [ "keyfork-derive-util", "serde", diff --git a/crates/daemon/keyforkd-client/Cargo.toml b/crates/daemon/keyforkd-client/Cargo.toml index 14874a5..a60ec7b 100644 --- a/crates/daemon/keyforkd-client/Cargo.toml +++ b/crates/daemon/keyforkd-client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "keyforkd-client" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "MIT" @@ -12,9 +12,9 @@ ed25519 = ["keyfork-derive-util/ed25519", "ed25519-dalek"] secp256k1 = ["keyfork-derive-util/secp256k1", "k256"] [dependencies] -keyfork-derive-util = { version = "0.1.0", path = "../../derive/keyfork-derive-util", default-features = false, registry = "distrust" } +keyfork-derive-util = { version = "0.2.0", path = "../../derive/keyfork-derive-util", default-features = false, registry = "distrust" } keyfork-frame = { version = "0.1.0", path = "../../util/keyfork-frame", registry = "distrust" } -keyforkd-models = { version = "0.1.0", path = "../keyforkd-models", registry = "distrust" } +keyforkd-models = { version = "0.2.0", path = "../keyforkd-models", registry = "distrust" } bincode = "1.3.3" thiserror = "1.0.49" k256 = { version = "0.13.3", optional = true } diff --git a/crates/daemon/keyforkd-models/Cargo.toml b/crates/daemon/keyforkd-models/Cargo.toml index 1ef13cd..6930261 100644 --- a/crates/daemon/keyforkd-models/Cargo.toml +++ b/crates/daemon/keyforkd-models/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "keyforkd-models" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -keyfork-derive-util = { version = "0.1.0", path = "../../derive/keyfork-derive-util", default-features = false, registry = "distrust" } +keyfork-derive-util = { version = "0.2.0", path = "../../derive/keyfork-derive-util", default-features = false, registry = "distrust" } serde = { version = "1.0.190", features = ["derive"] } thiserror = "1.0.50" diff --git a/crates/daemon/keyforkd/Cargo.toml b/crates/daemon/keyforkd/Cargo.toml index b354175..a4bc0ec 100644 --- a/crates/daemon/keyforkd/Cargo.toml +++ b/crates/daemon/keyforkd/Cargo.toml @@ -13,11 +13,11 @@ multithread = ["tokio/rt-multi-thread"] [dependencies] keyfork-bug = { version = "0.1.0", path = "../../util/keyfork-bug", registry = "distrust" } -keyfork-derive-util = { version = "0.1.0", path = "../../derive/keyfork-derive-util", registry = "distrust" } +keyfork-derive-util = { version = "0.2.0", path = "../../derive/keyfork-derive-util", registry = "distrust" } keyfork-frame = { version = "0.1.0", path = "../../util/keyfork-frame", features = ["async"], registry = "distrust" } -keyfork-mnemonic-util = { version = "0.2.0", path = "../../util/keyfork-mnemonic-util", registry = "distrust" } +keyfork-mnemonic-util = { version = "0.3.0", path = "../../util/keyfork-mnemonic-util", registry = "distrust" } keyfork-derive-path-data = { version = "0.1.0", path = "../../derive/keyfork-derive-path-data", registry = "distrust" } -keyforkd-models = { version = "0.1.0", path = "../keyforkd-models", registry = "distrust" } +keyforkd-models = { version = "0.2.0", path = "../keyforkd-models", registry = "distrust" } # Not personally audited bincode = "1.3.3" diff --git a/crates/derive/keyfork-derive-key/Cargo.toml b/crates/derive/keyfork-derive-key/Cargo.toml index f3a9159..f66a11a 100644 --- a/crates/derive/keyfork-derive-key/Cargo.toml +++ b/crates/derive/keyfork-derive-key/Cargo.toml @@ -1,13 +1,13 @@ [package] name = "keyfork-derive-key" -version = "0.1.0" +version = "0.1.1" edition = "2021" license = "AGPL-3.0-only" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util", registry = "distrust" } -keyforkd-client = { version = "0.1.0", path = "../../daemon/keyforkd-client", registry = "distrust" } +keyfork-derive-util = { version = "0.2.0", path = "../keyfork-derive-util", registry = "distrust" } +keyforkd-client = { version = "0.2.0", path = "../../daemon/keyforkd-client", registry = "distrust" } smex = { version = "0.1.0", path = "../../util/smex", registry = "distrust" } thiserror = "1.0.48" diff --git a/crates/derive/keyfork-derive-openpgp/Cargo.toml b/crates/derive/keyfork-derive-openpgp/Cargo.toml index b40805e..ed16a78 100644 --- a/crates/derive/keyfork-derive-openpgp/Cargo.toml +++ b/crates/derive/keyfork-derive-openpgp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "keyfork-derive-openpgp" -version = "0.1.0" +version = "0.1.1" edition = "2021" license = "AGPL-3.0-only" @@ -10,8 +10,8 @@ default = ["bin"] bin = ["sequoia-openpgp/crypto-nettle"] [dependencies] -keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util", default-features = false, features = ["ed25519"], registry = "distrust" } -keyforkd-client = { version = "0.1.0", path = "../../daemon/keyforkd-client", default-features = false, features = ["ed25519"], registry = "distrust" } +keyfork-derive-util = { version = "0.2.0", path = "../keyfork-derive-util", default-features = false, features = ["ed25519"], registry = "distrust" } +keyforkd-client = { version = "0.2.0", path = "../../daemon/keyforkd-client", default-features = false, features = ["ed25519"], registry = "distrust" } ed25519-dalek = "2.0.0" sequoia-openpgp = { version = "1.17.0", default-features = false } anyhow = "1.0.75" diff --git a/crates/derive/keyfork-derive-path-data/Cargo.toml b/crates/derive/keyfork-derive-path-data/Cargo.toml index 07e51d8..7b3c903 100644 --- a/crates/derive/keyfork-derive-path-data/Cargo.toml +++ b/crates/derive/keyfork-derive-path-data/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "keyfork-derive-path-data" -version = "0.1.0" +version = "0.1.1" edition = "2021" license = "MIT" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -keyfork-derive-util = { version = "0.1.0", path = "../keyfork-derive-util", default-features = false, registry = "distrust" } +keyfork-derive-util = { version = "0.2.0", path = "../keyfork-derive-util", default-features = false, registry = "distrust" } diff --git a/crates/derive/keyfork-derive-util/Cargo.toml b/crates/derive/keyfork-derive-util/Cargo.toml index ae1d1d6..9a76193 100644 --- a/crates/derive/keyfork-derive-util/Cargo.toml +++ b/crates/derive/keyfork-derive-util/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "keyfork-derive-util" -version = "0.1.1" +version = "0.2.0" edition = "2021" license = "MIT" @@ -12,7 +12,7 @@ secp256k1 = ["k256"] ed25519 = ["ed25519-dalek"] [dependencies] -keyfork-mnemonic-util = { version = "0.2.0", path = "../../util/keyfork-mnemonic-util", registry = "distrust" } +keyfork-mnemonic-util = { version = "0.3.0", path = "../../util/keyfork-mnemonic-util", registry = "distrust" } keyfork-bug = { version = "0.1.0", path = "../../util/keyfork-bug", registry = "distrust" } # Included in Rust diff --git a/crates/keyfork-shard/Cargo.toml b/crates/keyfork-shard/Cargo.toml index 4d0737f..353ef5e 100644 --- a/crates/keyfork-shard/Cargo.toml +++ b/crates/keyfork-shard/Cargo.toml @@ -15,15 +15,15 @@ qrcode = ["keyfork-qrcode"] [dependencies] keyfork-bug = { version = "0.1.0", path = "../util/keyfork-bug", registry = "distrust" } -keyfork-prompt = { version = "0.1.0", path = "../util/keyfork-prompt", default-features = false, features = ["mnemonic"], registry = "distrust" } -keyfork-qrcode = { version = "0.1.0", path = "../qrcode/keyfork-qrcode", optional = true, default-features = false, registry = "distrust" } +keyfork-prompt = { version = "0.1.1", path = "../util/keyfork-prompt", default-features = false, features = ["mnemonic"], registry = "distrust" } +keyfork-qrcode = { version = "0.1.1", path = "../qrcode/keyfork-qrcode", optional = true, default-features = false, registry = "distrust" } smex = { version = "0.1.0", path = "../util/smex", registry = "distrust" } sharks = "0.5.0" thiserror = "1.0.50" # Remote operator mode -keyfork-mnemonic-util = { version = "0.2.0", path = "../util/keyfork-mnemonic-util", registry = "distrust" } +keyfork-mnemonic-util = { version = "0.3.0", path = "../util/keyfork-mnemonic-util", registry = "distrust" } x25519-dalek = { version = "2.0.0", features = ["getrandom"] } aes-gcm = { version = "0.10.3", features = ["std"] } hkdf = { version = "0.12.4", features = ["std"] } diff --git a/crates/keyfork/Cargo.toml b/crates/keyfork/Cargo.toml index d54db2e..7f321fc 100644 --- a/crates/keyfork/Cargo.toml +++ b/crates/keyfork/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "keyfork" -version = "0.1.0" +version = "0.2.0" edition = "2021" license = "AGPL-3.0-only" @@ -25,11 +25,11 @@ sequoia-crypto-backend-openssl = ["sequoia-openpgp/crypto-openssl"] [dependencies] keyfork-bin = { version = "0.1.0", path = "../util/keyfork-bin", registry = "distrust" } keyforkd = { version = "0.1.0", path = "../daemon/keyforkd", features = ["tracing"], registry = "distrust" } -keyforkd-client = { version = "0.1.0", path = "../daemon/keyforkd-client", default-features = false, features = ["ed25519"], registry = "distrust" } -keyfork-derive-openpgp = { version = "0.1.0", path = "../derive/keyfork-derive-openpgp", registry = "distrust" } -keyfork-derive-util = { version = "0.1.0", path = "../derive/keyfork-derive-util", default-features = false, features = ["ed25519"], registry = "distrust" } +keyforkd-client = { version = "0.2.0", path = "../daemon/keyforkd-client", default-features = false, features = ["ed25519"], registry = "distrust" } +keyfork-derive-openpgp = { version = "0.1.1", path = "../derive/keyfork-derive-openpgp", registry = "distrust" } +keyfork-derive-util = { version = "0.2.0", path = "../derive/keyfork-derive-util", default-features = false, features = ["ed25519"], registry = "distrust" } keyfork-entropy = { version = "0.1.0", path = "../util/keyfork-entropy", registry = "distrust" } -keyfork-mnemonic-util = { version = "0.2.0", path = "../util/keyfork-mnemonic-util", registry = "distrust" } +keyfork-mnemonic-util = { version = "0.3.0", path = "../util/keyfork-mnemonic-util", registry = "distrust" } keyfork-prompt = { version = "0.1.0", path = "../util/keyfork-prompt", registry = "distrust" } keyfork-qrcode = { version = "0.1.0", path = "../qrcode/keyfork-qrcode", default-features = false, registry = "distrust" } keyfork-shard = { version = "0.2.0", path = "../keyfork-shard", default-features = false, features = ["openpgp", "openpgp-card", "qrcode"], registry = "distrust" } diff --git a/crates/util/keyfork-mnemonic-util/Cargo.toml b/crates/util/keyfork-mnemonic-util/Cargo.toml index e3ce7e3..6e87205 100644 --- a/crates/util/keyfork-mnemonic-util/Cargo.toml +++ b/crates/util/keyfork-mnemonic-util/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "keyfork-mnemonic-util" -version = "0.2.0" +version = "0.3.0" description = "Utilities to generate and manage seeds based on BIP-0039 mnemonics." repository = "https://git.distrust.co/public/keyfork" edition = "2021" diff --git a/crates/util/keyfork-prompt/Cargo.toml b/crates/util/keyfork-prompt/Cargo.toml index 826e6e1..6fc6d15 100644 --- a/crates/util/keyfork-prompt/Cargo.toml +++ b/crates/util/keyfork-prompt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "keyfork-prompt" -version = "0.1.0" +version = "0.1.1" description = "Prompt management utilities for Keyfork" repository = "https://git.distrust.co/public/keyfork" edition = "2021" @@ -15,5 +15,5 @@ mnemonic = ["keyfork-mnemonic-util"] [dependencies] keyfork-bug = { version = "0.1.0", path = "../keyfork-bug", registry = "distrust" } keyfork-crossterm = { version = "0.27.1", path = "../keyfork-crossterm", default-features = false, features = ["use-dev-tty", "events", "bracketed-paste"], registry = "distrust" } -keyfork-mnemonic-util = { version = "0.2.0", path = "../keyfork-mnemonic-util", optional = true, registry = "distrust" } +keyfork-mnemonic-util = { version = "0.3.0", path = "../keyfork-mnemonic-util", optional = true, registry = "distrust" } thiserror = "1.0.51" diff --git a/scripts/make-changelog-blurb.sh b/scripts/make-changelog-blurb.sh new file mode 100644 index 0000000..c466d6d --- /dev/null +++ b/scripts/make-changelog-blurb.sh @@ -0,0 +1,20 @@ +set -eu +set -o pipefail + +LAST_REF="$1" +CURRENT_REF="${2:-HEAD}" + +cargo metadata --format-version=1 | \ + jq -r '.packages[] | select(.source == null) | .name + " " + .manifest_path' | \ + while read crate manifest_path; do + crate_path="$(dirname $manifest_path)" + git_log="$(git log --format='%h %s' "$LAST_REF"..HEAD "$crate_path")" + if test ! -z "$git_log"; then + echo "### Changes in $crate:" + echo "" + echo "\`\`\`" + echo "$git_log" + echo "\`\`\`" + echo "" + fi +done