You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
initrd/gpg: add reprovision smartcard from GPG key backup flow
- Add gpg_card_factory_reset() shared function for factory-reset +
forcesig + key-attr setting (RSA and ECC/P-256), extracted from
oem-factory-reset.sh with explicit --passphrase-file support
- Add gpg_keytocard_subkeys() shared function: enable USB, verify card,
move subkeys to slots 1-3 (sign, encrypt, auth)
- Add gpg_set_card_identity() shared function for cardholder name and
login fields with explicit admin PIN
- Add gpg_reset_nk3_secret_app() shared function for Nitrokey 3 Secrets
app reset, parameterized on admin PIN
- Replace oem-factory-reset.sh function bodies with thin wrappers that
call the shared gpg_* functions via positional args
- Add reprovision_smartcard_from_backup(): 10-phase flow that mounts
the LUKS backup, detects key type from imported key, mounts public
partition, factory-resets card, restores subkeys, sets identity,
offers ROM flash
- Add k option to GPG Management Menu (gpg-gui.sh), always visible
- Add K option in prompt_missing_gpg_key_action (gui-init.sh)
- Add clean boot wizard offering OEM reset, reprovision, or ignore
- Update doc/gpg.md, doc/configuring-keys.md, doc/architecture.md
for the new recovery path
- Document QEMU testing workflow and hardlink preservation pattern
in doc/qemu.md (USB flash drive workflow + reprovision test)
- Add Authentication and Resetting Configuration sections to
doc/recovery-shell.md
Extends PR #1515 (2023): authentication via gpg_auth can now be
enforced with key material restored from a backup, allowing recovery
shell access control even after dongle replacement.
Tested on Nitrokey 3: OEM factory reset creates LUKS backup + provisions
dongle successfully. Tested on Nitrokey Pro 2: reprovision from backup
restores subkeys to (new) dongle, PIN changes, public key import, ROM
flash, and gpg_auth works after reboot. Config wipe from Options menu
correctly triggers clean boot wizard with OEM/reprovision/ignore choice.
Signed-off-by: Thierry Laurion <insurgo@riseup.net>
Copy file name to clipboardExpand all lines: doc/architecture.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -132,7 +132,7 @@ The CI pipeline's workspace and cache behavior is documented in
132
132
133
133
-**No network at boot** — all verification is local; no certificate authorities
134
134
- **Hardware root of trust** — the coreboot bootblock (IBB) is the Static Core Root of Trust for Measurement (S-CRTM): the first code executed by the CPU, directly from SPI flash. Coreboot implements a transitive measurement chain: the CRTM measures FMAP and the bootblock image into the preram log, then each subsequent stage measures the next before executing it — bootblock measures romstage, romstage measures ramstage, ramstage measures the Heads payload. Measurements are taken during CBFS file loading, before decompression, and are recorded in TPM PCR 2 (SRTM) once the TPM hardware is initialized (`tpm_setup()`). Measurements taken before TPM init are cached in the preram log and flushed to PCR 2 by `tspi_measure_cache_to_pcr()` during `tpm_setup()`. The full chain — bootblock → romstage → ramstage → Heads Linux kernel + initrd — is recorded into PCR 2. PCRs 0, 1, and 3 remain zero as policy anchors. See [tpm.md](tpm.md#srtm-in-coreboot) for TPM init timing per board. See [wp-notes.md](wp-notes.md#pr0-chipset-locking) for SPI write-protection and PR0 chipset locking details.
135
-
-**Fail-closed**— failed integrity verification drops to a recovery shell. Recovery shell authentication via GPG smartcard is enforced when GPG key backup has been configured (`CONFIG_HAVE_GPG_KEY_BACKUP=y`), which is set by answering "y" to `"Would you like to format an encrypted USB Thumb drive to store GPG key material? (Required to enable GPG authentication)"` during OEM Factory Reset / Re-Ownership. Otherwise the recovery shell is unauthenticated. An "Ignore tampering and force a boot (Unsafe!)" option is available to override this.
135
+
-**Fail-closed**-- failed integrity verification drops to a recovery shell. Recovery shell authentication via GPG smartcard is enforced when GPG key backup has been configured (`CONFIG_HAVE_GPG_KEY_BACKUP=y`), which is set by answering "y" to `"Would you like to format an encrypted USB Thumb drive to store GPG key material? (Required to enable GPG authentication)"` during OEM Factory Reset / Re-Ownership, or by running "Reprovision smartcard from GPG key backup" from the GPG Management Menu. Otherwise the recovery shell is unauthenticated. An "Ignore tampering and force a boot (Unsafe!)" option is available to override this. See [recovery-shell.md](recovery-shell.md#authentication) for details.
136
136
-**Separation of duties** — the public key that verifies `/boot` signatures is stored in CBFS (ROM). The private key that signs `/boot` stays on a USB security dongle and never leaves it.
137
137
-**Auditability** — all source is open, builds are reproducible, ROM images are verifiable
# Second run uses the preserved backup with no USB_FD_IMG override.
200
+
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp run
201
+
```
202
+
203
+
Inside the VM: Options -> GPG Options -> 'k' Reprovision smartcard from GPG
204
+
key backup. Enter the backup passphrase (the Admin PIN you set during OEM
205
+
factory reset). The flow will:
206
+
- Detect the key type (RSA or ECC) from the backup
207
+
- Factory-reset the virtual canokey and set matching key attributes
208
+
- Import the master key and subkeys from the LUKS partition
209
+
- Move subkeys to the smartcard via keytocard
210
+
- Set the card identity (name, email) from the backup key's UID
211
+
- Offer to flash the public key to ROM (decline -- QEMU cannot reflash)
212
+
213
+
165
214
Running via Docker wrappers
166
215
===
167
216
We provide convenient wrapper scripts at the repository root that encapsulate Docker invocation and automatically handle common host integrations needed for QEMU runs.
@@ -188,7 +237,7 @@ environment reference. Important ones are `HEADS_DISABLE_USB`
188
237
189
238
Make variables such as `USB_TOKEN`, `PUBKEY_ASC`, `INSTALL_IMG`,
retry_msg="Cannot sign /boot because no private GPG signing key is available ($DONGLE_BRAND not inserted, wiped, or key not set up).\n\nInsert your $DONGLE_BRAND and retry.\n\nHow would you like to proceed?"
243
243
fi
244
+
menu_options=(
245
+
'r'"$retry_label"
246
+
'F'' OEM Factory Reset / Re-Ownership'
247
+
'K'' Reprovision USB Security dongle from GPG key backup'
gpg_error_msg="ERROR: $CONFIG_BRAND_NAME couldn't find any GPG keys in your keyring.\n\nIf this is the first time the system has booted, you should add a public GPG key to the BIOS now.\n\nIf you just reflashed a new BIOS, you'll need to add at least one public key to the keyring.\n\nIf you have not just reflashed your BIOS, THIS COULD INDICATE TAMPERING!\n\nHow would you like to proceed?"
587
+
menu_options=(
588
+
'g'' Add a GPG key to the running BIOS'
589
+
'F'' OEM Factory Reset / Re-Ownership'
590
+
'K'' Reprovision USB Security dongle from GPG key backup'
0 commit comments