From 8e3bbfdf84f71da240b8effedf8d52fc8f4fd572 Mon Sep 17 00:00:00 2001 From: scgbckbone Date: Mon, 8 Jun 2026 15:48:53 +0200 Subject: [PATCH] docs: index all docs and fix drift vs firmware --- docs/README.md | 20 +++++++++- docs/bip85-passwords.md | 16 ++++---- docs/generic-wallet-export.md | 73 ++++++++++++++++++++++++----------- docs/memory-map.md | 2 +- docs/menu-tree.txt | 14 +++++-- docs/msg-signing.md | 23 +++-------- docs/nfc-coldcard.md | 4 +- docs/notes-on-repro.md | 20 ++++++---- docs/secure-elements.md | 4 +- docs/security-model.md | 11 +++--- docs/seed-xor.md | 10 +++-- docs/temporary-seeds.md | 8 ++-- docs/upgrade-recovery.md | 2 +- docs/web2fa.md | 13 ++++--- shared/ndef.py | 2 +- 15 files changed, 139 insertions(+), 83 deletions(-) diff --git a/docs/README.md b/docs/README.md index 384f231c..d12402f7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,14 +3,32 @@ These docs are meant for you hackers out there... but also for anyone who wants to understand why it's safe to put your moneys into Coldcard. +- [`security-model.md`](security-model.md) The COLDCARD Mk4/Mk5/Q security model. - [`pin-entry.md`](pin-entry.md) Huge and detailed discussion of PIN codes and the security element that holds the secrets. +- [`secure-elements.md`](secure-elements.md) How the dual secure elements work together. - [`dev-access.md`](dev-access.md) How developers can modify Coldcard to extend it. - [`memory-map.md`](memory-map.md) Memory map highlights +- [`notes-on-repro.md`](notes-on-repro.md) Detailed breakdown of the reproducible build process. +- [`upgrade-recovery.md`](upgrade-recovery.md) Firmware upgrade and recovery process. - [`backup-files.md`](backup-files.md) Some details of our encrypted backup files. +- [`temporary-seeds.md`](temporary-seeds.md) Temporary (ephemeral) seeds and the Seed Vault. +- [`seed-xor.md`](seed-xor.md) More about _Seed XOR_ feature, including fully worked Seed XOR example, and useful XOR lookup chart. +- [`key-teleport.md`](key-teleport.md) Key Teleport: encrypted transfer of seeds and secrets between Q devices. +- [`spending-policy.md`](spending-policy.md) Spending policy: autonomous signing with configurable limits. +- [`microsd-2fa.md`](microsd-2fa.md) Using a MicroSD card as a second factor for login. +- [`web2fa.md`](web2fa.md) Web 2FA authentication. +- [`bip85-passwords.md`](bip85-passwords.md) Deriving deterministic passwords via BIP-85. +- [`msg-signing.md`](msg-signing.md) COLDCARD message signing. +- [`proof-of-reserves-bip-322.md`](proof-of-reserves-bip-322.md) BIP-322 generic signed message format and proof of reserves. +- [`generic-wallet-export.md`](generic-wallet-export.md) Generic JSON wallet export file format. +- [`bip-21-extensions.md`](bip-21-extensions.md) Coldcard's BIP-21 URI extensions, including multisig ownership address check. +- [`nfc-coldcard.md`](nfc-coldcard.md) NFC support on Coldcard Mk4 and Q. +- [`nfc-pushtx.md`](nfc-pushtx.md) NFC Push Transaction: broadcast a signed transaction via your phone. +- [`usb-batteries.md`](usb-batteries.md) Using USB battery packs with Coldcard. - [`electrum-usage.md`](electrum-usage.md) Importing seed words into Electrum for funds usage (and other tips). - [`bitcoin-core-usage.md`](bitcoin-core-usage.md) How to use with Bitcoin Core. +- [`bitcoin-core2of2desc.md`](bitcoin-core2of2desc.md) Airgapped 2-of-2 multisig with Bitcoin Core using descriptors. - [`limitations.md`](limitations.md) Documented limitations, policy choices, and TODO items. - [`paperwallet.pdf`](paperwallet.pdf) Example paper wallet template file. -- [`seed-xor.md`](seed-xor.md) More about _Seed XOR_ feature, including fully worked Seed XOR example, and useful XOR lookup chart. - [`menu-tree.txt`](menu-tree.txt) Dump of the menu system. Incomplete, may be out of date. diff --git a/docs/bip85-passwords.md b/docs/bip85-passwords.md index 40d9cab5..43beb3de 100644 --- a/docs/bip85-passwords.md +++ b/docs/bip85-passwords.md @@ -5,13 +5,13 @@ according to [BIP-85 PWD BASE64](https://github.com/bitcoin/bips/blob/master/bip Generated passwords can be sent as keystrokes via USB to the host computer, effectively using Coldcard as specialized password manager. -In addition to deriving up to 10,000 distinct secure passwords, the Coldcard Mk4 +In addition to deriving up to 10,000 distinct secure passwords, the Coldcard can also type them into a computer by emulating a USB keyboard, and simulating the keystrokes needed to type the password. #### Requirements -* Coldcard Mk4 with version 5.0.5 or newer +* Coldcard Mk4 or Mk5 (firmware 5.0.5 or newer), or any Q * USB-C with data link (won't work with power only cable from Coinkite) ## Type Passwords over USB @@ -32,11 +32,13 @@ to exit. Exiting from "Type Passwords" will cause Coldcard to turn off keyboard 1. Go to Advanced/Tools -> Derive Seed B85 -> Passwords 2. Choose "Password/Index number" (BIP-85 index) and press OK to generate password. 3. Screen shows generated password, path, and entropy from which password was derived -4. A few different options are available at this point: - 1. press 1 to save password backup file on MicroSD card (cleartext!) - 2. press 2 to send keystrokes (this will first of all enable keyboard emulation, then send keystrokes + enter, and finally disables keyboard emulation) - 3. press 3 to view password as QR code - 4. press 4 to send over NFC (only appears when NFC is enabled) +4. A few different options are available at this point (on Mk; on Q the NFC and + QR buttons are used instead of (3)/(4)): + 1. press (1) to save password backup file on MicroSD card (cleartext!) + 2. press (2) to save to Virtual Disk (only when available) + 3. press (3) to send over NFC (only appears when NFC is enabled) + 4. press (4) to view password as QR code + 5. press (6) to send keystrokes over USB (this enables keyboard emulation, sends keystrokes + enter, then disables keyboard emulation) ## Keyboard language settings diff --git a/docs/generic-wallet-export.md b/docs/generic-wallet-export.md index 0a503202..c6fe981f 100644 --- a/docs/generic-wallet-export.md +++ b/docs/generic-wallet-export.md @@ -5,9 +5,12 @@ wallet systems, but we also have a file format for general purpose exports, which we hope future wallet makers will leverage. It contains master XPUB, XFP for that, and derived values for the top hardened -position of BIP44, BIP84 and BIP49. +position of the single-signature schemes BIP44, BIP49 and BIP84, plus the +multisig schemes BIP48 (`bip48_1` = `.../1h` P2SH-P2WSH and `bip48_2` = `.../2h` P2WSH). +When the account number is zero, a BIP45 (`m/45h`) multisig section is also included +(it is omitted for non-zero accounts, as in the example below). -The feature can be found here: _Advanced > MicroSD > Export Wallet > Generic JSON_ +The feature can be found here: _Advanced/Tools > Export Wallet > Generic JSON_ Please contact us (or better yet, make a pull request), if you need something more in this file. @@ -18,32 +21,51 @@ Here is an example, produced by the Simulator for account number 123. ```javascript { - "chain": "XTN", + "chain": "BTC", "xfp": "0F056943", - "xpub": "tpubD6NzVbkrYhZ4XzL5Dhayo67Gorv1YMS7j8pRUvVMd5odC2LBPLAygka9p7748JtSq82FNGPppFEz5xxZUdasBRCqJqXvUHq6xpnsMcYJzeh", "account": 123, + "xpub": "xpub661MyMwAqRbcGC9DmWbtbAmuUjpMYxw4BWE88NSDHB3jSjfUK7KtYJuKa52GbowD3DVLkgsxH9QwPnTx5mjdHykYFEncnmAsNsCTbWzBhA7", "bip44": { - "deriv": "m/44'/1'/123'", - "first": "n44vs1Rv7T8SANrg2PFGQhzVkhr5Q6jMMD", "name": "p2pkh", - "xfp": "B7908B26", - "xpub": "tpubDCiHGUNYdRRGoSH22j8YnruUKgguCK1CC2NFQUf9PApeZh8ewAJJWGMUrhggDNK73iCTanWXv1RN5FYemUH8UrVUBjqDb8WF2VoKmDh9UTo" + "xfp": "5F898064", + "deriv": "m/44h/0h/123h", + "xpub": "xpub6DStQXfAgHuLbMpCf86ruVkF4yT9pSLyWsFiqQTWY9osuinq8Dyee4W5jCjMfyku5LNkRB9oFinrY5ufn9XXEn8Vvzc2jnifKMaQCNV7RBZ", + "desc": "pkh([0f056943/44h/0h/123h]xpub6DStQXfAgHuLbMpCf86ruVkF4yT9pSLyWsFiqQTWY9osuinq8Dyee4W5jCjMfyku5LNkRB9oFinrY5ufn9XXEn8Vvzc2jnifKMaQCNV7RBZ/<0;1>/*)#4tl8jryn", + "first": "1GTNtzG5xX2UhdD5e3Nu7i1WPxFdjxQMJt" }, "bip49": { - "_pub": "upub5DMRSsh6mNak9KbcVjJ7xAgHJvbE3Nx22CBTier5C35kv8j7g2q58ywxskBe6JCcAE2VH86CE2aL4MifJyKbRw8Gj9ay7SWvUBkp2DJ7y52", - "deriv": "m/49'/1'/123'", - "first": "2N87V39riUUCd4vmXfDjMWAu9gUCiBji5jB", - "name": "p2wpkh-p2sh", - "xfp": "CEE1D809", - "xpub": "tpubDCDqt7XXvhAdy1MpSze5nMJA9x8DrdRaKALRRPasfxyHpiqWWEAr9cbDBQ9BcX7cB3up98Pk97U2QQ3xrvQsi5dNPmRYYhdcsKY9wwEY87T" + "name": "p2sh-p2wpkh", + "xfp": "A748B1FC", + "deriv": "m/49h/0h/123h", + "xpub": "xpub6DDm8WzH5a9qjKkttzqSB3uGofNohU9D3n3UG8WMxkUZzJEMPTYiQRf1dvTFCQR82MjGW4LUMVuTtnW4hF17RpzCqVwhf6Z2fnJPWtjG164", + "desc": "sh(wpkh([0f056943/49h/0h/123h]xpub6DDm8WzH5a9qjKkttzqSB3uGofNohU9D3n3UG8WMxkUZzJEMPTYiQRf1dvTFCQR82MjGW4LUMVuTtnW4hF17RpzCqVwhf6Z2fnJPWtjG164/<0;1>/*))#5j7t2n2u", + "_pub": "ypub6Y42SBfCEFhKacx1jMd4P8zmydXFe68hxtZh3XQFLkrT3Q3ae7iH2VK9f8QqCK53Rzr5FXw2pAG1n57dQwR8E4fohqe8F1NWwWN2uVRfBry", + "first": "3CeBRbJKCpg7BpJME2vM8ZxhCjBnhG4toy" }, "bip84": { - "_pub": "vpub5Y5a91QvDT45EnXQaKeuvJupVvX8f9BiywDcadSTtaeJ1VgJPPXMitnYsqd9k7GnEqh44FKJ5McJfu6KrihFXhAmvSWgm7BAVVK8Gupu4fL", - "deriv": "m/84'/1'/123'", - "first": "tb1qc58ys2dphtphg6yuugdf3d0kufmk0tye044g3l", "name": "p2wpkh", - "xfp": "78CF94E5", - "xpub": "tpubDC7jGaaSE66VDB6VhEDFYQSCAyugXmfnMnrMVyHNzW9wryyTxvha7TmfAHd7GRXrr2TaAn2HXn9T8ep4gyNX1bzGiieqcTUNcu2poyntrET" + "xfp": "2C5207AA", + "deriv": "m/84h/0h/123h", + "xpub": "xpub6CaWStGvcXqSW9BzU2vpCoP7aWjz9VfR5DS2nuYWVvKV2nug2dESg3HdFsaWHeoZaxuAhNcPB3TH2gq8MugS3JX1yGuhB4QbC2BneaYqB16", + "desc": "wpkh([0f056943/84h/0h/123h]xpub6CaWStGvcXqSW9BzU2vpCoP7aWjz9VfR5DS2nuYWVvKV2nug2dESg3HdFsaWHeoZaxuAhNcPB3TH2gq8MugS3JX1yGuhB4QbC2BneaYqB16/<0;1>/*)#yk84tprf", + "_pub": "zpub6rF34DckutvQCjaE8kW4cya7vT2t2jeQuSUUMhLHFw5F8zY8XwZZvAbuJHVgHU7QQF8nCKoW6NANoG4FoJWTdmtDhxJYLt3ZjUK5RqUSMdF", + "first": "bc1qhj6avwmp5lhpgqwm6dgxrf3v5lf67rjm99a8an" + }, + "bip48_1": { + "name": "p2sh-p2wsh", + "xfp": "845A3542", + "deriv": "m/48h/0h/123h/1h", + "xpub": "xpub6EkcQSTygvxVnBP2X2fM6HY5D7wv46tWbBc54ADaypuCr47vQh1GPdPAZFdx81ou5Rp4vBnzeJT5MDWDZstzijxkHfrofXRycpt1ASfg1La", + "desc": "sh(wsh(sortedmulti(M,[0f056943/48h/0h/123h/1h]xpub6EkcQSTygvxVnBP2X2fM6HY5D7wv46tWbBc54ADaypuCr47vQh1GPdPAZFdx81ou5Rp4vBnzeJT5MDWDZstzijxkHfrofXRycpt1ASfg1La/0/*,...)))", + "_pub": "Ypub6kUxqLsLQa4M43jXJ3ux8SyP6t8dD5ZbpZmxkpP1jc7VXLW4RkZ76ouEPAZ1gMgiiXzrYFPfzBC8MfjYaoTxfTm1zUfdeqiTnHDX8raCfeg" + }, + "bip48_2": { + "name": "p2wsh", + "xfp": "2A01C6B0", + "deriv": "m/48h/0h/123h/2h", + "xpub": "xpub6EkcQSTygvxVneXmk3ywiS2PFhBdiPxeMxYf6RFxHCHH36NxdcN7DjUpudCppAAxs58CG6DQLjtqZNmyC3MpgVob6wpdeATjpZZ1woX92EF", + "desc": "wsh(sortedmulti(M,[0f056943/48h/0h/123h/2h]xpub6EkcQSTygvxVneXmk3ywiS2PFhBdiPxeMxYf6RFxHCHH36NxdcN7DjUpudCppAAxs58CG6DQLjtqZNmyC3MpgVob6wpdeATjpZZ1woX92EF/0/*,...))", + "_pub": "Zpub75KE91YFZFbpup5PMS2AxgZCKRWnozdEWTEmaUKGQysSmUaKuL5WYyf2kk5UNQhhupRnddQe9GzST7crvfLoRTHTg6KtDPZiFjxBJobzcUz" } } ``` @@ -51,7 +73,14 @@ Here is an example, produced by the Simulator for account number 123. ## Notes 1. The `first` address is formed by added `/0/0` onto the given derivation, and is assumed -to be the first (non-change) receive address for the wallet. +to be the first (non-change) receive address for the wallet. It is only present on the +single-signature sections (`bip44`, `bip49`, `bip84`); multisig sections omit it. + +1a. Each section includes a `desc` field: a ready-to-import Bitcoin output descriptor +(with `#checksum`). Single-sig descriptors use the `<0;1>/*` multipath form. Multisig +sections (`bip48_1`, `bip48_2`, and `bip45` when present) emit a `sortedmulti(...)` +template with `M` and a trailing `...` as placeholders, to be completed with your +threshold and the other co-signers' keys. 2. The user may specify any value (up to 9999) for the account number, and it's meant to segregate funds into sub-wallets. Don't assume it's zero. @@ -59,8 +88,8 @@ segregate funds into sub-wallets. Don't assume it's zero. 3. When making your PSBT files to spend these amounts, remember that the XFP of the master (`0F056943` in this example) is the root of the subkey paths found in the file, and you must include the full derivation path from master. So based on this example, -to spend a UTXO on `tb1qc58ys2dphtphg6yuugdf3d0kufmk0tye044g3l`, the input section -of your PSBT would need to specify `(m=0F056943)/84'/1'/123'/0/0`. +to spend a UTXO on `bc1qhj6avwmp5lhpgqwm6dgxrf3v5lf67rjm99a8an`, the input section +of your PSBT would need to specify `(m=0F056943)/84'/0'/123'/0/0`. 4. The `_pub` value is the [SLIP-132](https://github.com/satoshilabs/slips/blob/master/slip-0132.md) style "ypub/zpub/etc" which some systems might want. It implies a specific address format. diff --git a/docs/memory-map.md b/docs/memory-map.md index d7504711..3be819d4 100644 --- a/docs/memory-map.md +++ b/docs/memory-map.md @@ -38,7 +38,7 @@ directly from python programs. | Start | Size | Notes |---------------|-----------|-------------------------- -| 0x0800 0000 | 128k | Bootloader code, including reset vector. See `stm32/mk4-bootloader` +| 0x0800 0000 | 112k | Bootloader code, including reset vector. See `stm32/mk4-bootloader` | 0x0801 c000 | 8k | Sensitive "pairing secrets" for SE1 and SE2 | 0x0801 e000 | 8k | MCU keys, consumable; 256 32-bit write-once slots. | 0x0802 0000 | 16k | Interrupt handlers, file header (Micropython and Coldcard code) diff --git a/docs/menu-tree.txt b/docs/menu-tree.txt index f9101319..89221f2e 100644 --- a/docs/menu-tree.txt +++ b/docs/menu-tree.txt @@ -247,13 +247,14 @@ Bitcoin Core Nunchuk Bull Bitcoin - Zeus + Blue Wallet Electrum Wallet Wasabi Wallet Fully Noded Unchained Theya Bitcoin Safe + Zeus Samourai Postmix Samourai Premix Descriptor @@ -279,13 +280,14 @@ Bitcoin Core Nunchuk Bull Bitcoin - Zeus + Blue Wallet Electrum Wallet Wasabi Wallet Fully Noded Unchained Theya Bitcoin Safe + Zeus Samourai Postmix Samourai Premix Descriptor @@ -360,6 +362,7 @@ Enable User Management [MAYBE] Paper Wallets + WIF Store NFC Tools [IF NFC ENABLED] Sign PSBT Show Address @@ -630,13 +633,14 @@ Bitcoin Core Nunchuk Bull Bitcoin - Zeus + Blue Wallet Electrum Wallet Wasabi Wallet Fully Noded Unchained Theya Bitcoin Safe + Zeus Samourai Postmix Samourai Premix Descriptor @@ -661,13 +665,14 @@ Bitcoin Core Nunchuk Bull Bitcoin - Zeus + Blue Wallet Electrum Wallet Wasabi Wallet Fully Noded Unchained Theya Bitcoin Safe + Zeus Samourai Postmix Samourai Premix Descriptor @@ -694,6 +699,7 @@ Coldcard Backup Restore Seed XOR Paper Wallets + WIF Store NFC Tools [IF NFC ENABLED] Sign PSBT Show Address diff --git a/docs/msg-signing.md b/docs/msg-signing.md index a79b6dd7..6907e882 100644 --- a/docs/msg-signing.md +++ b/docs/msg-signing.md @@ -2,15 +2,16 @@ COLDCARD can sign messages send to it via USB with the help of `ckcc` utility, sign messages provided via specially crafted file on SD card or Vdisk, -and Mk4 can also sign messages sent to COLDCARD via NFC. +and NFC-equipped models (Mk4, Mk5, and Q) can also sign messages sent to COLDCARD via NFC. +The resulting signature can be returned over SD card/Vdisk, NFC, or — on Q — as a QR code. Signature format follows [BIP-0137](https://github.com/bitcoin/bips/blob/master/bip-0137.mediawiki) specification. COLDCARD Mk3 and COLDCARD Mk4 up to version `5.1.0` used compressed P2PKH header byte for all script types. -From Mk4 `5.1.0` correct header byte is used for corresponding script type. +From version `5.1.0` correct header byte is used for corresponding script type. ### Verification -From COLDCARD Mk4 version `5.1.0` users can verify signed messages directly on the device. +From version `5.1.0` users can verify signed messages directly on the device. If signature file is on SD card or Virtual disk `Advanced/Tools -> File Management -> Verify Sig File`. In case signature file is detached signature of signed export (or any other file), COLDCARD can check if digest of file specified in the message matches contents of file. This requires file signed to be available on SD card or Vdisk. @@ -21,7 +22,7 @@ Bitcoin core can only verify P2PKH. ## Signed Exports -From Mk4 version `5.1.0` most of SD card and Virtual disk exports are accompanied by detached signature file. +From version `5.1.0` most of SD card and Virtual disk exports are accompanied by detached signature file. If exported file name is `addresses.csv` signature file name will be `addresses.sig`. ### Message construction and signature file format @@ -39,8 +40,6 @@ IFOvGVJrm31S0j+F4dVfQ5kbRKWKcmhmXIn/Lw8iIgaCG5QNZswjrN4X673R7jTZo1kvLmiD4hlIrbuL -----END BITCOIN SIGNATURE----- ``` -### What is signed - ### What Is Signed 1. **Single sig address explorer exports:** Signed by the key corresponding to the first (0th) address on the exported list. @@ -60,14 +59,4 @@ IFOvGVJrm31S0j+F4dVfQ5kbRKWKcmhmXIn/Lw8iIgaCG5QNZswjrN4X673R7jTZo1kvLmiD4hlIrbuL 6. **Multisig exports:** public keys are encoded as P2PKH address for all multisg signature exports * Multisig wallet descriptor: signed by the key corresponding to the first external address of own enrolled extended key `my_key/0/0` * Generic XPUBs export: signed by the key corresponding to the first external address of own standard P2WSH derivation `m/48h/h/h/2h/0/0` - * Multisig address explorer export: Signed by own key at the same derivation as first (0th) row on exported list. `my_key//` - -### What is NOT signed - -Multisig exports and generic multisig xpub exports are not signed. It is not clear at this point -whether to sign these exports with some generic single signature key (i.e. `m/44'/'/0'/0/0`) -or with our portion (leg) of script. In both cases script type (address format) would not match as multisignature -message signing is not standardized. - -1. **Multisig exports** -2. **Generic multisig exports** \ No newline at end of file + * Multisig address explorer export: Signed by own key at the same derivation as first (0th) row on exported list. `my_key//` \ No newline at end of file diff --git a/docs/nfc-coldcard.md b/docs/nfc-coldcard.md index 34d52451..5d3d8004 100644 --- a/docs/nfc-coldcard.md +++ b/docs/nfc-coldcard.md @@ -1,6 +1,6 @@ -# NFC and Coldcard Mk4 +# NFC and Coldcard -(Applies to Coldcard Mk4 only) +(Applies to NFC-equipped models: Mk4, Mk5, and Q) ## Usage diff --git a/docs/notes-on-repro.md b/docs/notes-on-repro.md index abf0429a..31066709 100644 --- a/docs/notes-on-repro.md +++ b/docs/notes-on-repro.md @@ -11,11 +11,17 @@ The entrypoint makefile for repro builds. The `repro` command in `shared.mk` is the first step in the repro build process, which triggers a docker build and run process. ```makefile +repro: submods-match code-committed repro: docker build -t coldcard-build - < dockerfile.build - (cd ..; docker run $(DOCK_RUN_ARGS) sh src/stm32/repro-build.sh $(VERSION_STRING) $(MK_NUM)) + (cd ..; docker run $(DOCK_RUN_ARGS) sh src/stm32/repro-build.sh $(VERSION_STRING) $(HW_MODEL) $(PARENT_MKFILE)) ``` +`$(HW_MODEL)` is the model string (e.g. `mk4`, `q1`) and `$(PARENT_MKFILE)` is the +top-level makefile being used (`MK-Makefile` or `Q1-Makefile`). The `submods-match` +and `code-committed` prerequisites ensure the submodules and working tree are clean +before a repro build. + Below are interesting sections from the docker logs that give an idea as to what is going on in build process: ```stdout @@ -61,19 +67,19 @@ Successfully installed signit-1.0 ... -+ make -f MK4-Makefile setup ++ make -f MK-Makefile setup ... -+ make -f MK4-Makefile firmware-signed.bin firmware-signed.dfu production.bin dev.dfu firmware.lss firmware.elf ++ make -f MK-Makefile firmware-signed.bin firmware-signed.dfu production.bin dev.dfu firmware.lss firmware.elf ... -signit sign -b l-port/build-COLDCARD_MK4 -m 4 5.0.7 -o firmware-signed.bin +signit sign -b l-port/build-COLDCARD_MK4 -m mk4 5.0.7 -o firmware-signed.bin ... -signit sign -m 4 5.0.7 -r firmware-signed.bin -k 1 -o production.bin +signit sign -m mk4 5.0.7 -r firmware-signed.bin -k 1 -o production.bin You don't have that key (1), so using key zero instead! ... @@ -96,7 +102,7 @@ production.bin ... -+ make -f MK4-Makefile 'PUBLISHED_BIN=/tmp/checkout/firmware/releases/2022-10-05T1724-v5.0.7-mk4-coldcard.dfu' check-repro ++ make -f MK-Makefile 'PUBLISHED_BIN=/tmp/checkout/firmware/releases/2022-10-05T1724-v5.0.7-mk4-coldcard.dfu' check-repro ... @@ -183,7 +189,7 @@ To summarize `check-repro`: - `split` (cli/signit.py: Line 153-175) is run against the release `*.dfu` resulting in a `check-fw.bin` and `check-bootrom.bin`. "This splits the DFU file into the two parts it contains: the main firmware (COLDCARD application) and the boot loader code." -- `check` (cli/signit.py: Line 176-241) is run against each the release `check-fw.bin` and our built `firmware-signed.bin`. +- `check` (cli/signit.py: Line 176-243) is run against each the release `check-fw.bin` and our built `firmware-signed.bin`. - a hexdump is taken of each the release `check-fw.bin` and our built `firmware-signed.bin` piped through $TRIM_SIG which removes 64 bytes of signature data and subsitutes it with a common string. diff --git a/docs/secure-elements.md b/docs/secure-elements.md index d1c9f41e..44def43e 100644 --- a/docs/secure-elements.md +++ b/docs/secure-elements.md @@ -92,8 +92,8 @@ increases flexibility and resistance to known plain text attacks. | `pin stretch` | slot 2 | HMAC | SE1 | Key stretching for PIN entry and anti-phish words | `firmware` | slot 14 | SHA256d | SE1 | Firmware checksum, controls green/red LEDs | `nonce/chksum` | slot 10 | data | SE1 | AES nonce and GMAC tag, protected by PIN -| `SE2 easy key` | page 15 | AES via HMAC | SE2 | Another SE2 part of AES seed key -| `SE2 hard key` | page 14 | AES via ECC | SE2 | SE2's part of AES seed key; ECC used to unlock +| `SE2 easy key` | page 14 | AES via HMAC | SE2 | Another SE2 part of AES seed key +| `SE2 hard key` | page 15 | AES via ECC | SE2 | SE2's part of AES seed key; ECC used to unlock | `tpin key` | `tpin_key` | HMAC(key) | MCU | Key for HMAC used to encrypt trick PINs | `trick PIN slots` | pages 0-12 | HMAC | SE2 | Protect duress wallet seeds and pins (6 spots) | `SE2 trash` | secret B | HMAC | SE2 | Used to destroy values (only SE2 knows the value) diff --git a/docs/security-model.md b/docs/security-model.md index f7a75869..03db46e7 100644 --- a/docs/security-model.md +++ b/docs/security-model.md @@ -1,4 +1,4 @@ -# COLDCARD Mk4/Q Security Model +# COLDCARD Mk4/Mk5/Q Security Model ## Abstract @@ -96,9 +96,10 @@ user entered the True PIN. An attacker will only have access to the duress wallet. They won't have access to steal the main stash. The private key can be automatically derived using BIP-85 methods, -based on account numbers 1001, 1002, or 1003. Because this is BIP-85 -based and uses a 24-word seed, it behaves exactly like a normal -wallet. Defining a passphrase for the wallet is also possible. +based on account numbers 1001, 1002, or 1003 for a 24-word duress wallet +(or 2001, 2002, 2003 for a 12-word one). Because this is BIP-85 +based, it behaves exactly like a normal wallet. Defining a passphrase +for the wallet is also possible. The Mk4 also supports older COLDCARD duress wallets and their UTXOs on the blockchain. There is an option to create compatible wallets @@ -243,7 +244,7 @@ COLDCARD's case to do so, but the option is there if needed. ## SD Card Recovery Mode -Mk4/Q bootloader is smart enough to be able to read an SD card. You +Mk4/Mk5/Q bootloader is smart enough to be able to read an SD card. You will only be able to trigger the SD card loading code, if the COLDCARD was powered down during the upgrade process. At that point, the intended firmware image has been lost because it it held in diff --git a/docs/seed-xor.md b/docs/seed-xor.md index b79fb843..be32bb76 100644 --- a/docs/seed-xor.md +++ b/docs/seed-xor.md @@ -12,7 +12,7 @@ are not discrete and you could be compelled to produce the passphrase. Enter [_Seed XOR_](https://seedxor.com), a plausibly deniable means of storing secrets in two or more parts that look and behave just -like the original secret. One 12 or 24-word seed phrase becomes two or more parts +like the original secret. One 12-, 18-, or 24-word seed phrase becomes two or more parts that are also BIP-39 compatible seeds phrases. These should be backed up in your preferred method, metal or otherwise. These parts can be individually loaded with honeypot funds as each one has same word length, with the last being @@ -78,10 +78,12 @@ words right the next day. When the parts are made deterministically, we take a double-SHA256 over a fixed string (`Batshitoshi`), your master secret, and the text -`1 of 4 parts` which changes for each part. +`0 of 4 parts` which changes for each part (the index is 0-based). -In random mode, we simply pick 32 random bytes (and then double-SHA256 -them) from the Coldcard's True Random Number Generator (TRNG).. +In random mode, we simply pick random bytes (and then double-SHA256 +them) from the Coldcard's True Random Number Generator (TRNG). The number +of bytes matches your secret length: 16, 24, or 32 bytes for a 12-, 18-, +or 24-word seed respectively. This is done to make all but the one part. The final part is the value needed to get back to your secret, so it's the XOR of the diff --git a/docs/temporary-seeds.md b/docs/temporary-seeds.md index 08207145..8f646ae8 100644 --- a/docs/temporary-seeds.md +++ b/docs/temporary-seeds.md @@ -1,7 +1,7 @@ # Temporary Seeds -[_(new in v5.0.7, requires Mk4)_](upgrade.md) +[_(new in v5.0.7, requires Mk4, Mk5, or Q)_](upgrade.md) Temporary seed (renamed in `5.2.0` from Ephemeral seed) is a temporary secret completely separate @@ -42,7 +42,7 @@ Read more about `Seed Vault` feature below. - `24 words` - `XPRV (BIP-32)` - pick derivation `Index` in next prompt, or just press OK for index 0 - - Press (2) in next prompt to activate derived secret as a temporary seed + - Press (0) in next prompt to activate derived secret as a temporary seed * temporary seed can be activated from Duress Wallet - go to `Settings -> Login Settings -> Trick Pins` @@ -66,7 +66,7 @@ Ability to generate and use **Temporary seed** is available on Coldcard when: # Restore Master -[_(new in v5.2.0, requires Mk4)_](upgrade.md) +[_(new in v5.2.0, requires Mk4, Mk5, or Q)_](upgrade.md) From version `5.2.0` users no longer need to reboot COLDCARD to return to their "master seed" (one stored in SE2). Once COLDCARD has temporary @@ -84,7 +84,7 @@ Seed Vault entries can only be deleted in Seed Vault menu. # Seed Vault -[_(new in v5.2.0, requires Mk4)_](upgrade.md) +[_(new in v5.2.0, requires Mk4, Mk5, or Q)_](upgrade.md) Seed Vault adds the ability to store multiple temporary secrets into encrypted settings for simple recall and later use (AES-256-CTR encrypted with your master seed's key). diff --git a/docs/upgrade-recovery.md b/docs/upgrade-recovery.md index e499a24e..59e1cc76 100644 --- a/docs/upgrade-recovery.md +++ b/docs/upgrade-recovery.md @@ -1,7 +1,7 @@ # Firmware Upgrade and Recovery Process -_This document applies only to the Mk4. Earlier COLDCARDs did not use this approach._ +_This document applies to the Mk4, Mk5, and Q. Earlier COLDCARDs did not use this approach._ On the COLDCARD, we have done away with the slow external SPI flash (serial flash) chip entirely (used in Mk1-Mk3). In it's place we diff --git a/docs/web2fa.md b/docs/web2fa.md index 3923b3f3..5fa88d6a 100644 --- a/docs/web2fa.md +++ b/docs/web2fa.md @@ -30,8 +30,8 @@ the correct code. - Usual 2fa base32 secret is picked by CC and stored in CC (so that server is stateless) - CC creates URL encrypted to the pubkey of server, containing args: - shared secret for TOTP (same value as held in user's phone) - - the response nonce (16 bytes, or 8 digits for Mk4) to be revealed to the user - on successful auth + - the response nonce (32 bytes, shown as 64 hex chars, on Q; or 8 digits on Mk4) + to be revealed to the user on successful auth - flag if Q model, so can provide a QR to be scanned in that case (rather than digits) - some text label for what's being approved, which is presented to user so they can pick correct 2fa shared secret. @@ -82,12 +82,15 @@ the correct code. ## URL Format - https://coldcard.com/2fa?ss={shared_secret}&q={is_q}&g={nonce}&nm={label_text} + https://coldcard.com/2fa?g={nonce}&ss={shared_secret}&nm={label_text}&q={is_q} +(the query string is then encrypted to the server's pubkey, so the args above +are what is inside the encrypted payload.) + +- `nonce`: text string that is either 8 digits on Mk4, or 64 hex chars on Q - `shared_secret`: 16 chars of Base32-encoded pre-shared secret -- `is_q`: flag indicating use of QR to provide nonce back to user -- `nonce`: text string that is either 8 digits for Mk4, or hex digits for QR - `nm`: human readable label for the transaction/purpose +- `is_q`: flag indicating use of QR to provide nonce back to user Server will accept plaintext arguments as above, but normally everything after the question mark is encrypted. diff --git a/shared/ndef.py b/shared/ndef.py index 57749e03..7769863f 100644 --- a/shared/ndef.py +++ b/shared/ndef.py @@ -2,7 +2,7 @@ # # ndef.py -- NDEF records: making them and parsing them. # -# - see ../docs/nfc-on-coldcard.md for background. +# - see ../docs/nfc-coldcard.md for background. # - cross platform file # from struct import pack, unpack