Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Buildroot/board/FOG/FOS/rootfs_overlay/bin/fog.checkin
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ checkin() {
# must keep waiting however long that takes. What was NOT deliberate is that
# a dead server looked identical to a queue position -- $res was empty, so
# this printed " * (In line for 5s)" forever with nothing to diagnose.
# serverReason distinguishes them; the waiting behaviour is unchanged.
# serverReason distinguishes them; the waiting behavior is unchanged.
while [[ $res != "##@GO" ]]; do
callServer "${web}service/$php_post" "$poststring"
res="$serverBody"
Expand Down
16 changes: 8 additions & 8 deletions Buildroot/board/FOG/FOS/rootfs_overlay/bin/fog.enrollsb
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ esac
# nothing signed to boot, irreversibly from the client's side.
#
# Checked before the certificate fetch and before the already-trusted
# short-circuit: no db contents make enrolment useful here, so there is no state
# short-circuit: no db contents make enrollment useful here, so there is no state
# in which continuing tells the admin something more useful than this does.
if [[ $(sbPlatformBits) == 32 ]]; then
handleError "This machine has 32-bit UEFI firmware, which FOG cannot enrol. ($0)\n No Microsoft-signed 32-bit shim and no signed 32-bit iPXE exist, so it\n cannot boot FOG under Secure Boot enforcement even with this key trusted.\n Nothing was enrolled and nothing was changed. Leave Secure Boot off here."
handleError "This machine has 32-bit UEFI firmware, which FOG cannot enroll. ($0)\n No Microsoft-signed 32-bit shim and no signed 32-bit iPXE exist, so it\n cannot boot FOG under Secure Boot enforcement even with this key trusted.\n Nothing was enrolled and nothing was changed. Leave Secure Boot off here."
fi

dots "Fetching certificate"
Expand Down Expand Up @@ -93,12 +93,12 @@ if [[ $state == setup ]]; then
echo "Failed"
debugPause
# Deliberately spells out the state the machine is left in. A partial
# enrolment stops before the PK write, so the platform is still in Setup
# enrollment stops before the PK write, so the platform is still in Setup
# Mode and still boots exactly what it booted before -- that is worth
# saying, because "Secure Boot enrolment failed" otherwise reads like
# saying, because "Secure Boot enrollment failed" otherwise reads like
# the machine may now be unbootable, and someone will make an
# unnecessary trip to the firmware screen to check.
handleError "Automatic Secure Boot enrolment failed. ($0)\n This machine is still in Setup Mode and still boots as it did before;\n nothing has been made unbootable.\n Check that ${web}service/secureboot/ serves PK.auth, KEK.auth and db.auth --\n the FOG server needs efitools installed to produce them."
handleError "Automatic Secure Boot enrollment failed. ($0)\n This machine is still in Setup Mode and still boots as it did before;\n nothing has been made unbootable.\n Check that ${web}service/secureboot/ serves PK.auth, KEK.auth and db.auth --\n the FOG server needs efitools installed to produce them."
fi
echo "Done"
debugPause
Expand Down Expand Up @@ -126,18 +126,18 @@ if [[ -z $password ]]; then
handleError "Could not determine a one-time password for the MOK request. ($0)"
fi

dots "Staging MOK enrolment request"
dots "Staging MOK enrollment request"
if ! sbStageMok "$cert" "$password"; then
echo "Failed"
debugPause
handleError "The MOK enrolment request was NOT staged. ($0)\n Do not reboot expecting a MokManager prompt; nothing is pending.\n See the messages above for what ran."
handleError "The MOK enrollment request was NOT staged. ($0)\n Do not reboot expecting a MokManager prompt; nothing is pending.\n See the messages above for what ran."
fi
echo "Done"
debugPause

echo
echo "=============================================================================="
echo " A Secure Boot enrolment request is now pending on this machine."
echo " A Secure Boot enrollment request is now pending on this machine."
echo
echo " ONE-TIME PASSWORD: $password"
echo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ dots "Enrolling Secure Boot keys (forced)"
if ! sbEnrollDb; then
echo "Failed"
debugPause
handleError "[TEST] Forced Secure Boot enrolment failed. ($0)\n Firmware state was: $state\n Expected on a machine whose currently-enrolled PK/KEK do not match\n FOG's -- the write is rejected rather than applied partially.\n Check that ${web}service/secureboot/ serves PK.auth, KEK.auth and db.auth."
handleError "[TEST] Forced Secure Boot enrollment failed. ($0)\n Firmware state was: $state\n Expected on a machine whose currently-enrolled PK/KEK do not match\n FOG's -- the write is rejected rather than applied partially.\n Check that ${web}service/secureboot/ serves PK.auth, KEK.auth and db.auth."
fi
echo "Done"
debugPause
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2517,7 +2517,7 @@ wipeDisk() {
# Validate the mode before dispatching anywhere: an unknown or empty mode is
# a malformed task, and guessing a destructive action on one is its own
# hazard. Must stay ahead of the nvme branch below, which would otherwise
# erase on any mode it doesn't recognise.
# erase on any mode it doesn't recognize.
case $mode in
fast|normal|full) ;;
*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ function fill_disk(partition_names, partitions, args, n, fixed_partitions, origi
# Used for extended volumes (logical disks)
extended_margin = 2;
# The "find the next partition" scan below infers a partition's original
# size from where its neighbour starts, so the partition_names traversals
# size from where its neighbor starts, so the partition_names traversals
# need a defined order -- ascending partition number, the order the dump
# was written in. See by_partition_number().
old_sorted_in = PROCINFO["sorted_in"];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
# Secure Boot enrolment helpers.
# Secure Boot enrollment helpers.
#
# Deliberately a separate library rather than more of funcs.sh: this shares no
# state, no vocabulary and no failure modes with the imaging engine, and
Expand All @@ -9,8 +9,8 @@
# shim's MokList is a BOOT-SERVICES-ONLY variable, so the running OS cannot
# write it -- only MokManager, in boot services, can promote MokNew into
# MokList, and it demands the one-time password as proof of physical presence.
# So nothing here "enrols a MOK". It STAGES a request that a human then
# confirms at the MokManager screen. Fully automatic enrolment is the db path
# So nothing here "enrolls a MOK". It STAGES a request that a human then
# confirms at the MokManager screen. Fully automatic enrollment is the db path
# (Setup Mode), which is Phase 2 and lands beside this.

# The EFI global variable namespace. SetupMode, SecureBoot, PK and KEK live
Expand Down Expand Up @@ -95,7 +95,7 @@ sbState() {
#
# Why FOS cares at all: no Microsoft-signed 32-bit shim and no signed 32-bit
# iPXE exist, so there is no Secure Boot chain an ia32 machine can boot. See the
# refusal in bin/fog.enrollsb for what that means for enrolment.
# refusal in bin/fog.enrollsb for what that means for enrollment.
#
# The kernel has exposed fw_platform_size on every EFI boot since 4.14 and FOS
# runs 6.x, so on UEFI it is always readable. "unknown" therefore means a BIOS
Expand Down Expand Up @@ -231,7 +231,7 @@ sbCertInDb() {
# Two stores, because a machine can be trusting this certificate by either
# route: the Setup Mode path puts it in db with no MOK entry at all, and the
# staged-MOK path puts it in MokList with nothing in db. Missing either one
# sends a technician to a blue screen to re-enrol something already trusted.
# sends a technician to a blue screen to re-enroll something already trusted.
#
# THIS FUNCTION GOT IT WRONG ONCE, AND ONLY HARDWARE CAUGHT IT. It used to grep
# `mokutil --db` for the certificate's SHA-256. mokutil prints a **SHA1**
Expand All @@ -258,7 +258,7 @@ sbCertTrusted() {
esac
return 1
}
# Stage a MOK enrolment request, without prompting.
# Stage a MOK enrollment request, without prompting.
#
# mokutil normally reads the one-time password from the terminal, which is
# useless in a task. --generate-hash=<pw> prints the SHA-512 crypt string
Expand All @@ -269,7 +269,7 @@ sbCertTrusted() {
#
# The password is NOT a secret. It authenticates nothing at rest; it exists so
# that whoever answers MokManager after the reboot is demonstrably the same
# person who asked for the enrolment. It therefore has to be shown to the
# person who asked for the enrollment. It therefore has to be shown to the
# technician, which is the caller's job.
#
# $1 path to the DER certificate
Expand Down Expand Up @@ -408,7 +408,7 @@ sbWriteEfiAuthVar() {
[[ -s $path ]] || return 1
return 0
}
# Enrol this server's certificate into the platform's Secure Boot databases.
# Enroll this server's certificate into the platform's Secure Boot databases.
#
# Order is db, then KEK, then PK, and it is not interchangeable. Writing PK is
# what takes the platform OUT of Setup Mode; from that moment every further
Expand All @@ -426,7 +426,7 @@ sbWriteEfiAuthVar() {
sbEnrollDb() {
local var guid authfile
# Fetch all three BEFORE writing any. A download that fails halfway would
# otherwise leave the platform mid-enrolment for no better reason than a
# otherwise leave the platform mid-enrollment for no better reason than a
# web server hiccup, and the fetch is free to retry while a partial write
# is not.
for var in db KEK PK; do
Expand Down
8 changes: 4 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,8 @@ and add a new ADR for any similarly hard-to-reverse decision:
`--ses` flag must never be issued (it doesn't guarantee erasure); prefer
`sanitize` when supported, falling back to `format --ses=1` only when no
sanitize is in progress or unrecoverably failed.
- **0009 — Secure Boot enrolment.** shim's `MokList` is a boot-services-only
variable, so the running OS *cannot* enrol a MOK — only MokManager can, behind
- **0009 — Secure Boot enrollment.** shim's `MokList` is a boot-services-only
variable, so the running OS *cannot* enroll a MOK — only MokManager can, behind
a physical-presence password. `secureboot-funcs.sh`/`fog.enrollsb` therefore
**stage** a request and must never report that they enrolled anything. The
automatable path is writing `db` while the platform is in **Setup Mode**; note
Expand All @@ -247,7 +247,7 @@ and add a new ADR for any similarly hard-to-reverse decision:
(`CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y`) — activating it is downstream-only
work gated on the vendor-shim question. `CONFIG_LSM` is set explicitly rather
than left to `oldconfig`, because an LSM missing from the ordered list never
initialises, and `CONFIG_LOAD_UEFI_KEYS` is what imports the firmware's `db`
initializes, and `CONFIG_LOAD_UEFI_KEYS` is what imports the firmware's `db`
and `MokList` into the platform keyring. The trap this ADR exists for:
`make oldconfig` **silently drops** any symbol whose dependencies are unmet,
so a config can look right in git and produce a kernel missing lockdown
Expand All @@ -267,7 +267,7 @@ and add a new ADR for any similarly hard-to-reverse decision:
`keymap`, `mdraid`, `chkdsk`, `mc`, `setmacto`) aren't server-known data at
all and need their own design pass. See the ADR for the full analysis.
- **0012 — Microsoft-signed FOG shim (proposed, unstarted).** The only way to
remove Secure Boot enrolment entirely rather than automate it further —
remove Secure Boot enrollment entirely rather than automate it further —
gated on ADR-0011's redesign actually shipping, and on the still-inactive
ADR-0010 lockdown patch. `ipxe/shim` cannot be repurposed for this (it
trusts exactly one thing, derives its second stage from its own filename,
Expand Down
8 changes: 4 additions & 4 deletions docs/adr/0008-secure-wipe-by-device-class.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ secure erase operation requested"**. That reformats the namespace's LBA metadata
and returns in seconds, but the NVMe specification does not require the
controller to erase user data. Many drives do deallocate blocks on format, and a
deallocated read commonly returns zeros — which is exactly why this looked
correct in testing. That behaviour is implementation-defined per drive, not
correct in testing. That behavior is implementation-defined per drive, not
guaranteed, and "reads back as zeros" is not "the data is gone from the NAND".
Every NVMe wipe FOG has performed through this path should be assumed
non-erasing.
Expand Down Expand Up @@ -64,7 +64,7 @@ Class comes from `diskClass()`: `*nvme*` by name, otherwise the kernel's
say. `unknown` is treated as possibly-flash — it gets the SSD warning — because
the failure that matters is assuming flash is a platter, not the reverse.

`fast` is honestly labelled a metadata-only wipe on every non-NVMe class. It
`fast` is honestly labeled a metadata-only wipe on every non-NVMe class. It
destroys the partition table so the disk looks blank; it never claims to be a
secure erase. On NVMe it is a real erase, because a crypto erase is both
instantaneous and complete.
Expand Down Expand Up @@ -129,7 +129,7 @@ all. The correct primitive is ATA SANITIZE (`hdparm --sanitize-block-erase` /
`--sanitize-crypto-scramble`) or ATA Secure Erase.

We did not implement it here, and the overwrite remains. Two reasons. First,
removing the existing behaviour without a working replacement would leave SATA
removing the existing behavior without a working replacement would leave SATA
SSD users with less than they have today. Second — and this is the substantive
one — **the obstacle has already been investigated twice, and it is not merely
awkward.**
Expand Down Expand Up @@ -190,7 +190,7 @@ sanitize-log parse fails 5, and allowing a format fallback after a sanitize has
started fails 3.

That last control guards a non-obvious ordering constraint found while writing
these tests. `nvmeSecureErase()` treats any mode it does not recognise as
these tests. `nvmeSecureErase()` treats any mode it does not recognize as
"neither full nor fast" and issues `format --ses=1`, so with the validation
placed after the class dispatch — the natural reading order — an unknown mode
refused on `/dev/sda` but *erased* `/dev/nvme0n1`. The mode check must stay ahead
Expand Down
Loading