Skip to content

Commit 4ab154a

Browse files
committed
initrd/gpg: refactor OEM card management into shared functions for reuse, add reprovision flow
Extract shared OpenPGP smartcard management functions from initrd/bin/oem-factory-reset.sh into initrd/etc/gpg_functions.sh so they can be reused by multiple callers. OEM functions become thin wrappers passing global variables as positional args; the reprovision flow calls the same shared functions to restore GPG subkeys from a LUKS-encrypted backup USB onto a replacement USB Security dongle. Shared functions (replacing OEM inline code): - gpg_card_factory_reset(): factory-reset + forcesig + key-attr (RSA and ECC/P-256), parameterized on admin PIN - gpg_keytocard_subkeys(): enable USB, verify card, move subkeys to slots 1-3 (sign, encrypt, auth) - gpg_set_card_identity(): cardholder name and login fields - gpg_reset_nk3_secret_app(): Nitrokey 3 Secrets app reset - gpg_card_change_pin(): GPG User PIN change New reprovision flow (reprovision_smartcard_from_backup()): 10-phase flow: mount LUKS backup -> detect key type -> factory- reset card -> import subkeys -> set identity -> sign /boot -> flash GUI integration: - k option in GPG Management Menu (gpg-gui.sh), always visible - K option in prompt_missing_gpg_key_action (gui-init.sh) - Clean boot wizard: OEM reset, reprovision, or ignore Code quality fixes from review: - Fix 6 sites where $? was clobbered by TRACE_FUNC/DEBUG calls - Replace --passphrase-file with --passphrase-fd 3 3< to avoid leaking PIN through /proc/<pid>/cmdline - Fix algo_code/bit_len extraction: head -1 for multi-key backups - Fix STATUS_OK mount emission: only on success - Fix gpg_reset_nk3_secret_app: return actual error code from hotp_verification, explicit return 0 for non-NK3 - Remove incorrect || [ $? -eq 2 ] patch: gpg --import exit code 2 is a fatal error, not unchanged - Fix pubkey.asc import: check success properly, fall back to keyring export on failure - Fix partition derivation for NVMe/MMC: stable [0-9]+$ regex - Add _luks_cleanup helper for every error return path (replaces broken EXIT trap pattern) - Re-run NK3 Secrets app reset with custom PIN on factory-reset retry - Add chmod 600 on /tmp/secret/gpg_pin - Write backup passphrase to /tmp/secret/backup_pass, use mount-usb.sh --pass-file to avoid argv leak - Shred /tmp/secret/backup_pass on mount success and failure - Shred /tmp/secret/gpg_pin after all GPG operations complete - Limit key_id derivation to first match (head -1) to prevent multi-line values breaking gpg --edit-key calls - Strip trailing <email> from cardholder name when no comment is present in UID line - Reset card_admin_pin to default after factory-reset step so subsequent forcesig/key-attr use the correct PIN - Ensure /tmp/secret exists before writing backup_pass (mkdir -p) - Export public key from keyring instead of referencing mount file: after successful pubkey.asc import, re-export from the keyring to /tmp/reprovision_pubkey.asc rather than pointing PUBKEY at the potentially-stale /media/pubkey.asc - Fix gpg_reset_nk3_secret_app header comment: removes inaccurate "to factory default" phrasing - Remove unused uid_decoded local variable from reprovision_smartcard_from_backup - Fix key_email extraction: add head -1 to prevent multi-line values when UID contains multiple <...> blocks - Fix parent_disk derivation for NVMe/MMC: use p?[0-9]+$ regex that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix pub_partition derivation for p-suffixed devices: detect whether the original partition used a p<num> separator and reconstruct the public partition as parent_disk+p2 vs parent_disk+2 accordingly that handles both regular (sda1) and p-suffixed (nvme0n1p1) partitions - Fix ownertrust import regex: use [0-9A-Fa-f] to handle lowercase hex fingerprints from gpg --with-colons - Add --pass-file option to mount-usb.sh: use PASS_FILE variable and pass path directly to cryptsetup --key-file instead of reading into PASS and echoing via process substitution, eliminating the argv leak that --pass-file was meant to fix Documentation: - doc/gpg.md, doc/configuring-keys.md, doc/architecture.md: updated for the new recovery path - doc/qemu.md: USB flash drive workflow, hardlink preservation, reprovision test - doc/recovery-shell.md: Authentication and Resetting Config sections Extends PR #1515 (2023): authentication via gpg_auth can now be enforced with key material restored from a backup. Tested on Nitrokey Pro 2 (reprovision end-to-end: factory reset, keytocard, PIN change, public key import, flash, reboot, gpg_auth works). Tested on Nitrokey 3 (OEM factory reset creates LUKS backup + provisions dongle). Signed-off-by: Thierry Laurion <insurgo@riseup.net>
1 parent 8d0064f commit 4ab154a

10 files changed

Lines changed: 1071 additions & 297 deletions

File tree

doc/architecture.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ The CI pipeline's workspace and cache behavior is documented in
132132

133133
- **No network at boot** — all verification is local; no certificate authorities
134134
- **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.
136136
- **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.
137137
- **Auditability** — all source is open, builds are reproducible, ROM images are verifiable
138138

doc/configuring-keys.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,23 @@ If you already have a provisioned USB Security dongle:
160160
3. Follow the steps. After reflashing, reboot.
161161
4. Generate a new TOTP/HOTP secret when prompted.
162162

163+
### Restoring Keys from Backup
164+
165+
If you chose the in-memory backup path during OEM factory reset and your
166+
dongle is lost, broken, or wiped:
167+
168+
1. Insert the backup USB thumb drive and your (new) dongle.
169+
2. Go to `Options -> GPG Management -> Reprovision smartcard from GPG key backup`.
170+
3. Enter the backup passphrase when prompted.
171+
4. Heads detects the key type from the backup, factory-resets the dongle,
172+
restores the subkeys, and sets the card identity.
173+
5. After success, flash the public key to the running BIOS for persistence.
174+
6. Re-sign /boot via `Options -> Update checksums and sign all files in /boot`.
175+
176+
This requires the LUKS-encrypted backup USB drive created during OEM factory
177+
reset (answer Y to "format an encrypted USB Thumb drive"). Without it, run
178+
a new OEM Factory Reset / Re-Ownership to rekey the device.
179+
163180
## Forgotten GPG User PIN
164181

165182
From Recovery Shell with the dongle inserted:

doc/gpg.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,18 @@ public key into the Heads firmware:
130130
3. From Heads: `Options -> GPG Management -> Add a GPG key to the running BIOS + reflash`.
131131
4. Reboot. Generate a new TOTP/HOTP secret when prompted.
132132

133+
### Restoring Keys from Backup
134+
135+
See [configuring-keys.md](configuring-keys.md#restoring-keys-from-backup) for
136+
the full recovery flow. In short:
137+
138+
1. Insert the backup USB thumb drive and the replacement dongle.
139+
2. From Heads: `Options -> GPG Management -> Reprovision smartcard from GPG key backup`.
140+
3. Enter the backup passphrase.
141+
142+
The backup drive must have been created by the OEM factory reset flow with
143+
the "format an encrypted USB Thumb drive" option set to Y.
144+
133145
## Nitrokey 3 Specifics
134146

135147
- Supports NIST P-256 ECC keys in addition to RSA — significantly faster key

doc/qemu.md

Lines changed: 75 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -126,40 +126,98 @@ Use `qemu-img snapshot` before modifying the root disk.
126126
### USB flash drive workflow
127127

128128
```bash
129-
mkdir -p qemu_img # safe storage inside clone
129+
mkdir -p ~/Qemu_img # persistent storage outside repo
130+
# (same filesystem as repo;
131+
# hardlinks only work within
132+
# a single partition)
130133

131134
# Step 1: Create the USB image via the Makefile.
132135
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm2 \
133136
QEMU_USB_SIZE=64G run
134-
# build/x86/.../usb_fd.raw now exists.
137+
# -> build/x86/.../usb_fd.raw now exists.
135138

136-
# Step 2: Save a master copy IMMEDIATELY (before population).
137-
cp build/x86/qemu-coreboot-fbwhiptail-tpm2/usb_fd.raw qemu_img/usb_fd.img
138-
rm build/x86/qemu-coreboot-fbwhiptail-tpm2/usb_fd.raw
139-
cp -alf qemu_img/usb_fd.img build/x86/qemu-coreboot-fbwhiptail-tpm2/usb_fd.raw
139+
# Step 2: Save a master copy (hardlink, zero-cost, survives make clean).
140+
cp -al build/x86/qemu-coreboot-fbwhiptail-tpm2/usb_fd.raw \
141+
~/Qemu_img/usb_fd.img
140142

141143
# Step 3: Populate with ISOs.
142-
sudo losetup --find --show --partscan build/x86/.../usb_fd.raw
144+
sudo losetup --find --show --partscan \
145+
build/x86/qemu-coreboot-fbwhiptail-tpm2/usb_fd.raw
143146
sudo mount /dev/loop0p1 /mnt
144147
cp ~/Downloads/ISOs/*.iso /mnt/
145148
sudo umount /mnt && sudo losetup -d /dev/loop0
146149

147-
# Step 4: Hardlink into other board build directories.
148-
cp -alf qemu_img/usb_fd.img build/x86/qemu-coreboot-fbwhiptail-tpm1-hotp/usb_fd.raw
149-
cp -alf qemu_img/usb_fd.img build/x86/qemu-coreboot-fbwhiptail-tpm2-hotp/usb_fd.raw
150+
# Step 4: Hardlink into other board build directories (zero-cost).
151+
cp -alf ~/Qemu_img/usb_fd.img \
152+
build/x86/qemu-coreboot-fbwhiptail-tpm1-hotp/usb_fd.raw
153+
cp -alf ~/Qemu_img/usb_fd.img \
154+
build/x86/qemu-coreboot-fbwhiptail-tpm2-hotp/usb_fd.raw
150155

151156
# Next run uses the hardlink — Makefile skips creation since the file exists.
152157
```
153158

154159
### Daily development cycle
155160

156-
After OS install + USB provisioned, reference both from `./qemu_img/`:
161+
After OS install + USB provisioned, reference the root disk from `./qemu_img/`
162+
(inside the repo clone — Docker visibility) and USB backups from `~/Qemu_img/`
163+
(outside the repo — survives clean builds via hardlinks):
164+
165+
```bash
166+
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp \
167+
PUBKEY_ASC=pubkey.asc \
168+
USB_TOKEN=Nitrokey3NFC \
169+
ROOT_DISK_IMG=./qemu_img/root.qcow2 \
170+
inject_gpg run
171+
```
172+
173+
Root disk images live at `./qemu_img/` because `ROOT_DISK_IMG` is passed to
174+
`make` inside the Docker container, which only sees `$(pwd)`. USB backup
175+
images live at `~/Qemu_img/` and are bridged into the build directory via
176+
hardlinks (`cp -alf`).
177+
178+
179+
### Testing GPG key reprovision from a backup drive
180+
181+
The GPG key reprovision flow ('k' in the GPG Management Menu, or the 'K'
182+
option when signing fails) restores subkeys from a LUKS-encrypted backup
183+
drive created during OEM factory reset onto a (new) OpenPGP smartcard.
184+
This can be tested in QEMU.
185+
186+
First run OEM factory reset to populate the virtual USB drive with backup
187+
material (this creates `build/x86/<board>/usb_fd.raw` with the LUKS private
188+
+ exFAT public partition layout). Afterwards, save the virtual USB drive
189+
and canokey state, then hardlink back for the second run:
190+
191+
```bash
192+
# ~/Qemu_img/ stores files OUTSIDE the repo so they survive make clean.
193+
# Hardlinks work because ~/heads/ and ~/Qemu_img/ share the same partition.
194+
mkdir -p ~/Qemu_img
195+
196+
# Save canokey state and populated USB backup image (hardlink, zero-cost).
197+
cp -al build/x86/qemu-coreboot-fbwhiptail-tpm1-hotp/.canokey-file \
198+
~/Qemu_img/.canokey-file
199+
cp -al build/x86/qemu-coreboot-fbwhiptail-tpm1-hotp/usb_fd.raw \
200+
~/Qemu_img/backup_drive.raw
201+
202+
# Hardlink back into the build dir so make run picks them up.
203+
cp -alf ~/Qemu_img/.canokey-file \
204+
build/x86/qemu-coreboot-fbwhiptail-tpm1-hotp/.canokey-file
205+
cp -alf ~/Qemu_img/backup_drive.raw \
206+
build/x86/qemu-coreboot-fbwhiptail-tpm1-hotp/usb_fd.raw
207+
208+
# Second run uses the preserved backup with no USB_FD_IMG override.
209+
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp run
210+
```
157211

158-
./docker_repro.sh make BOARD=qemu-coreboot-fbwhiptail-tpm1-hotp \
159-
PUBKEY_ASC=pubkey.asc \
160-
USB_TOKEN=Nitrokey3NFC \
161-
ROOT_DISK_IMG=./qemu_img/root.qcow2 \
162-
inject_gpg run
212+
Inside the VM: Options -> GPG Options -> 'k' Reprovision smartcard from GPG
213+
key backup. Enter the backup passphrase (the Admin PIN you set during OEM
214+
factory reset). The flow will:
215+
- Detect the key type (RSA or ECC) from the backup
216+
- Factory-reset the virtual canokey and set matching key attributes
217+
- Import the master key and subkeys from the LUKS partition
218+
- Move subkeys to the smartcard via keytocard
219+
- Set the card identity (name, email) from the backup key's UID
220+
- Offer to flash the public key to ROM (decline -- QEMU cannot reflash)
163221

164222

165223
Running via Docker wrappers
@@ -188,7 +246,7 @@ environment reference. Important ones are `HEADS_DISABLE_USB`
188246

189247
Make variables such as `USB_TOKEN`, `PUBKEY_ASC`, `INSTALL_IMG`,
190248
`QEMU_MEMORY_SIZE`, `QEMU_DISK_SIZE`, `QEMU_USB_SIZE`,
191-
`ROOT_DISK_IMG`, `CPUS` and `V`
249+
`ROOT_DISK_IMG`, `USB_FD_IMG`, `CPUS` and `V`
192250
are forwarded to the `make` invocation and affect how
193251
`targets/qemu.mk` runs QEMU. See `targets/qemu.mk` for token formats
194252
and examples.

doc/recovery-shell.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,62 @@ The Recovery Shell boots with PCR 4 set to `recovery` instead of
2020
- TOTP/HOTP sealing and TPM Disk Unlock Key creation/unsealing do not work.
2121
- To perform seal/unseal operations return to the normal GUI boot.
2222

23+
## Authentication
24+
25+
`gpg_auth()` in `initrd/etc/functions.sh` guards the recovery shell and
26+
external media boot entry. On boards with `CONFIG_HAVE_GPG_KEY_BACKUP=y`,
27+
recovery calls `gpg_auth()` before opening the bash prompt, and
28+
`media-scan.sh` (called from `usb-init.sh`) also invokes `gpg_auth` before
29+
scanning USB devices. TPM operations, flash/update, GPG management, and
30+
all other GUI menu functions are NOT gated by this check -- they remain
31+
accessible from the main menu.
32+
33+
After OEM Factory Reset / Re-Ownership or the reprovision flow,
34+
`CONFIG_HAVE_GPG_KEY_BACKUP=y` is persisted in the user config stored in
35+
CBFS, ensuring the authentication requirement applies on every boot for
36+
boards where the compile-time default differs.
37+
38+
**What it guards against:** Recovery shell access gives full bash within the
39+
initrd, including direct block device read/write, SPI flash access, TPM
40+
commands, and GPG key operations. An unauthenticated physical attacker with
41+
shell access could flash malicious firmware, delete `/boot` content, lock TPM
42+
PIN counters permanently, sign unauthorized `/boot` content, or attempt
43+
LUKS disk decryption.
44+
45+
**How it works:** `gpg_auth()` generates a random nonce, the user signs it
46+
with their GPG key (smartcard or backup USB drive) within 3 attempts, and the
47+
signature is verified against the ROM-fused public keyring. On failure,
48+
`DIE` exits the session. With `CONFIG_RESTRICTED_BOOT=y`, the shell is
49+
blocked entirely and the system reboots after 5 seconds.
50+
51+
**Without authentication:** If the board does not have
52+
`CONFIG_HAVE_GPG_KEY_BACKUP` set, `gpg_auth()` is a no-op and the recovery
53+
shell opens without prompting.
54+
55+
## Resetting Configuration
56+
57+
`Options -> Change configuration settings -> 'r'` (`Clear GPG key(s) and reset
58+
all user settings`) wipes the running system configuration:
59+
60+
- Clears `~/.gnupg` (GPG keyring, trustdb)
61+
- Deletes `/boot/kexec*` (signatures, checksums, boot options)
62+
- Removes all `heads/` files from CBFS (keyring, trustdb, config.user)
63+
- Reflashes the cleaned firmware
64+
- Resets the TPM if present
65+
66+
**Attestation impact:** Removing `heads/` files from CBFS changes the SPI flash
67+
contents measured into PCR 7 by `cbfs-init` at next boot. Combined with the
68+
TPM reset, TOTP/HOTP unseal will fail on the next boot — Heads shows the
69+
standard red-menu TOTP error prompt.
70+
71+
**Recovery after wipe:** Run OEM Factory Reset / Re-Ownership (Options -> 'F')
72+
to fully reprovision ([configuring-keys.md](configuring-keys.md)). If you have a
73+
GPG key backup USB drive from a previous in-memory OEM reset, use
74+
`GPG Options -> 'k' Reprovision USB Security dongle from GPG key backup`
75+
to restore subkeys from the backup ([configuring-keys.md#restoring-keys-from-backup](configuring-keys.md#restoring-keys-from-backup)),
76+
then flash the public key to ROM, re-sign /boot, and generate new TOTP/HOTP
77+
secrets.
78+
2379
## Common Operations
2480

2581
### Manual boot

initrd/bin/gpg-gui.sh

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,20 @@ TRACE_FUNC
1010

1111
while true; do
1212
unset menu_choice
13+
# Build menu options dynamically
14+
menu_options=(
15+
'r' ' Add GPG key to running BIOS and reflash'
16+
'a' ' Add GPG key to standalone BIOS image and flash'
17+
'e' ' Replace GPG key(s) in the current ROM and reflash'
18+
'l' ' List GPG keys in your keyring'
19+
'p' ' Export public GPG key to USB drive'
20+
'g' ' Generate GPG keys manually on a USB security dongle'
21+
'k' ' Reprovision USB Security dongle from GPG key backup'
22+
)
23+
menu_options+=('x' ' Exit')
1324
whiptail_type $BG_COLOR_MAIN_MENU --title "GPG Management Menu" \
1425
--menu 'Select the GPG function to perform' 0 80 10 \
15-
'r' ' Add GPG key to running BIOS and reflash' \
16-
'a' ' Add GPG key to standalone BIOS image and flash' \
17-
'e' ' Replace GPG key(s) in the current ROM and reflash' \
18-
'l' ' List GPG keys in your keyring' \
19-
'p' ' Export public GPG key to USB drive' \
20-
'g' ' Generate GPG keys manually on a USB security dongle' \
21-
'x' ' Exit' \
26+
"${menu_options[@]}" \
2227
2>/tmp/whiptail || recovery "GUI menu failed"
2328

2429
menu_choice=$(cat /tmp/whiptail)
@@ -64,6 +69,9 @@ while true; do
6469
gpg_post_gen_mgmt
6570
fi
6671
;;
72+
"k")
73+
reprovision_smartcard_from_backup
74+
;;
6775
esac
6876

6977
done

initrd/bin/gui-init.sh

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,18 @@ prompt_missing_gpg_key_action() {
241241
retry_label=" Retry (after connecting $DONGLE_BRAND)"
242242
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?"
243243
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'
248+
)
249+
menu_options+=(
250+
'm' ' Return to main menu'
251+
'x' ' Exit to recovery shell'
252+
)
244253
whiptail_error --title "ERROR: GPG signing key unavailable" \
245-
--menu "$retry_msg" 0 80 4 \
246-
'r' "$retry_label" \
247-
'F' ' OEM Factory Reset / Re-Ownership' \
248-
'm' ' Return to main menu' \
249-
'x' ' Exit to recovery shell' \
254+
--menu "$retry_msg" 0 80 6 \
255+
"${menu_options[@]}" \
250256
2>/tmp/whiptail || recovery "GUI menu failed"
251257

252258
option=$(cat /tmp/whiptail)
@@ -257,6 +263,9 @@ prompt_missing_gpg_key_action() {
257263
F)
258264
oem-factory-reset.sh
259265
;;
266+
K)
267+
reprovision_smartcard_from_backup
268+
;;
260269
x)
261270
recovery "User requested recovery shell"
262271
;;
@@ -543,9 +552,26 @@ clean_boot_check() {
543552
fi
544553

545554
# OS is installed, no kexec files present, no GPG keys in keyring, security token present
546-
# prompt user to run OEM factory reset
547-
oem-factory-reset.sh \
548-
"Clean Boot Detected - Perform OEM Factory Reset / Re-Ownership?"
555+
# offer to provision or reprovision
556+
if ! whiptail_warning --title "Heads setup wizard" \
557+
--menu "No GPG keys, no /boot signatures, and a USB Security dongle\ndetected. /boot has an installed OS.\n\nHow would you like to proceed?" 0 80 5 \
558+
'F' ' OEM Factory Reset / Re-Ownership (full provisioning)' \
559+
'K' ' Reprovision USB Security dongle from GPG key backup' \
560+
'i' ' Ignore and continue to main menu' \
561+
2>/tmp/whiptail; then
562+
return
563+
fi
564+
565+
option=$(cat /tmp/whiptail)
566+
case "$option" in
567+
F)
568+
oem-factory-reset.sh \
569+
"Clean Boot Detected - Perform OEM Factory Reset / Re-Ownership?"
570+
;;
571+
K)
572+
reprovision_smartcard_from_backup
573+
;;
574+
esac
549575
}
550576

551577
check_gpg_key() {
@@ -558,27 +584,35 @@ check_gpg_key() {
558584
fi
559585
local gpg_error_msg
560586
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'
591+
)
592+
menu_options+=(
593+
'i' ' Ignore error and continue to main menu'
594+
'x' ' Exit to recovery shell'
595+
)
561596
whiptail_error --title "ERROR: GPG keyring empty!" \
562-
--menu "$gpg_error_msg" 0 80 4 \
563-
'g' ' Add a GPG key to the running BIOS' \
564-
'F' ' OEM Factory Reset / Re-Ownership' \
565-
'i' ' Ignore error and continue to main menu' \
566-
'x' ' Exit to recovery shell' \
597+
--menu "$gpg_error_msg" 0 80 6 \
598+
"${menu_options[@]}" \
567599
2>/tmp/whiptail || recovery "GUI menu failed"
568600

569601
option=$(cat /tmp/whiptail)
570602
case "$option" in
571603
g)
572604
gpg-gui.sh && BG_COLOR_MAIN_MENU="normal"
573605
;;
606+
F)
607+
oem-factory-reset.sh
608+
;;
609+
K)
610+
reprovision_smartcard_from_backup
611+
;;
574612
i)
575613
skip_to_menu="true"
576614
return 1
577615
;;
578-
F)
579-
oem-factory-reset.sh
580-
;;
581-
582616
x)
583617
recovery "User requested recovery shell"
584618
;;

0 commit comments

Comments
 (0)