BenWestgate / Bails

Bails is a Bitcoin solution protecting against surveillance, censorship, and confiscation. It installs Bitcoin Core on the encrypted Persistent Storage of Tails, creates and recovers Bitcoin Core wallets from Codex32 (BIP93) seed backups, and creates backup Bails USB sticks and shareable blank Bails USB sticks. Learn more in README.md.
MIT License
38 stars 7 forks source link

New Feature: Panic Mode #81

Open BenWestgate opened 10 months ago

BenWestgate commented 10 months ago

Inspired by: OWASP User Privacy Protection Cheat Sheet

If wallets are placed into encrypted volumes, panic mode can load fake decoy watch-only wallets if the user entered their distressed password. The key origin information can be spoofed. These could be sub-accounts of the real master-seed for recovery purposes.

Loading a private_keys_enabled wallet is more difficult as in order to look like the real wallet, the master xprv needs to be in the descriptors, which means grinding for master xprvs to match the real one's fingerprint.

"Adversaries must have no way to know a panic mode already exists..." this means while the feature would be opt-in, every user whether they set-up panic mode or not, would have to have enough encrypted volumes created for plausible deniability of those who do use it.

I can possibly use Veracrypt Hidden Volumes for this. It must be able to be created and decrypted without an administration password setup.

"The password for the hidden volume must be substantially different from the password for the outer volume."

This applies regardless of if I use LUKS2 volumes or Veracrypt. A good default would be for people who do NOT use panic mode to have to enter their Persistent Storage Passphrase to Load their wallets. Then users who want a Panic Mode can create a "substantially different" passphrase for their Real wallet and an attacker will see the Fake wallet with the default passphrase.

epiccurious commented 10 months ago

ACK

These could be sub-accounts of the real master-seed for recovery purposes.

if the real wallet is at m / {44,48,84,86}' / 0' / 0' / {0,1} / *

Then the fake wallet could be

m / {44,48,84,86}' / 0' / 1' / {0,1} /*

But the key origin info in the descriptor can lie and say: [fingerprint]/ {44,48,84,86}'/ 0'/ 0'/ {0,1}/* So it looks the same as a real wallet descriptor.

This works as long as the spend passphrase is not given out or it is a watch-only.

How would this work? Would distress sub-accounts be visible to the user in the standard wallet or only relevant for a recovery/sweep of funds? By sub-accounts, are you referring to a custom HD derivation path.

You COULD include the descriptors for the distress sub account as inactive in the Real wallet, for a combined balance, although care may be needed to not spend from it in a privacy reducing way. Or you could include two wallets when the Real passphrase is given, the distress and real wallet. Or you could just open the real wallets for the real passphrase and the distress wallets for the distress passphrase.

Go ahead and share your opinion because I don't have strong preferences. Keep in mind you could have a wallet passphrase written down hidden somewhere that's for more secret wallets that you rarely need to watch. So the encrypted wallet volumes do not have to be used only for plausible deniability. If say you trust say your family, you could even share a Bails USB and just use distinct wallet load passphrases and a shared Persistent Storage passphrase to not see one another's private wallet details. (if you don't keylog one another lol)

You'd recover the funds by restoring the m / {44,48,84,86}' / 0' / 1' / {0,1} /* account.

grinding for master xprvs to match the real one's fingerprint

How much of a time expensive would grinding be?

It takes about one minute on a single thread with a i5-1135g7

An other issue is you'd want these to be child keys of the real master xprv (then lie again on the key origin and fingerprint in xprv serialization to make the fake look like a master). But bip32 has only 2^31 hardened indexes so it's not guaranteed (but likely) to find an index that if treating the child xprv like a master xprv will produce the same fingerprint. But now you have a 32-bit + number you'd have to store to recover the plausibly fake private_keys_enabled wallet.

So that is the recovery of the fake vs spendability of the fake trade off. I'm siding towards watch-only. The updated create new seed process will allow creating watch-only wallets, so it's not a setup that wouldn't ordinarily exist if using Bails more as warm or cold storage.

BenWestgate commented 10 months ago

The reason the fingerprint should match the real wallet is the new #72 uses the bip32 fingerprint in bech32 as a default identifier for codex32 strings. If the extortioner had access to a share and your Persistent Storage, he would know your wallet is probably a fake if the identifier didn't match the share. Although you can set custom identifiers and you can manually fake your own key origin info, or say the codex32 shares are not yours, these are not the most plausible denials for the mismatch.

BenWestgate commented 10 months ago

Panic Mode has been implemented with luks2 encrypted loop back files.

At wallet creation time, users will specify whether to "Require a passphrase to Load this wallet". The label of the file-system is the wallet name.

The loopback files will be stored somewhere conspicuous and double clicking them will prompt for the passphrase and load the wallet into Bitcoin Core.

To create a Panic mode, use a decoy wallet either Encrypted by the Persistent Storage passphrase, then create a secret wallet with a substantially different passphrase from the Persistent Storage passphrase.

Bails can automatically create multiple luks2 vaults whether the user has an encrypted wallet or not. Under distress the user can plausibly claim they did not use this optional feature. Unfortunately, users in distress who did not use the feature won't be able to claim they did not, unless they delete it.

This makes the 3 options at wallet creation time:

59

BenWestgate commented 9 months ago

For decoy wallets, when the user has the default share identifier, we will brute force the next BIP85 derived extended private master key that has the same identifier, that way decoys can spend without giving away that they are decoy wallets.

For custom share IDs, we should probably brute force a bip32 seed with their desired ID, then the process can be agnostic thereafter.

On restore, the root master xprv can be brute forced again so nothing needs to be backed up. The first matching fingerprint will always be used making it deterministic as well.

BenWestgate commented 3 months ago

Note: clear text wallets will be removed from the Beta in order to cheaply get clone for a friend functionality. The best way to clone is to always encrypt all your sensitive wallet data so the root of the Persistent Storage is safe to share.

Before a wallet is created or restored, the user will be asked to create a new vault if the wallet name doesn't specify a vault that is already open. This allows one to have multiple wallets in a specific vault for convenience.

Possibly not specifying a vault name just the wallet name, makes the root of the encrypted file system labeled as wallet name its wallet folder.

Trying to find a balance between typing passphrases and opening multiple wallets. One passphrase per wallet could be clunky for users. We don't have to get this right.

Ex:

Wallet name: secret/Wallet

  1. will create an encrypted loopback filesystem labeled secret.
  2. It will auto-mount at /media/$USER/secret when decrypted.
  3. /media/$USER is symlinked to .bitcoin/wallets/, so unlocking the vault for secret will create an empty folder at .bitcoin/wallets/secret
  4. After the seed is restored Bitcoin core creates a wallet folder at .bitcoin/wallets/secret/Wallet.
  5. At this point they could restore another wallet and if named: _secret/Wallet2, it would not prompt for a passphrase if "secret" is already mounted and instead would create a new wallet folder at _.bitcoin/wallets/secret/Wallet2
  6. These wallets vanish when the loopback file is locked until it is unlocked again.
github-actions[bot] commented 1 month ago

Stale issue message

BenWestgate commented 1 month ago

The code in install-core has been commented where this will affect it. The current design will be to create a symlink to /media/$USER named wallets in the datadir. Alternatively, walletdir=/media/$USER could be set in Bitcoin.conf.

There will be no option to not have encrypted wallets. That way we get the clone feature easily right after this is in.