Remove brand name from this configuration variable. For backward
compatibility, update config.user in init if the branded variable is
present.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Debian 12's initrd by default now consists of an uncompressed cpio
archive containing microcode, followed by a zstd-compressed cpio
archive. inject_firmware.sh only supported gzip-compressed cpio, so it
could not extract /init from this archive.
Add zstd-decompress to decompress zstd streams (uncompressed size is
about 180 KB).
Add unpack_initramfs.sh which is able to decompress uncompressed, gzip,
or zstd archives, with multiple segments, much like the Linux kernel
itself does.
Use unpack_initramfs.sh to extract /init for blob jail.
Don't compress the new archive segment containing firmware and the
updated /init.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
PureBoot doesn't have any other three-valued settings and this doesn't
present very well in the config UI.
Instead make this a two-valued setting; drop the mode that forces the
EC setting to "stay off" at every boot because this is the default.
When disabling automatic power-on, disable the EC BRAM setting too.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Stop manually loading config values, just update config in environment.
Never test values against "n", since many default to empty. Always
test ="y" or !="y", any other value is off.
Add set_user_config() function to set a value in config.user,
combine configs, and update config in environment. Use it in setting
implementations.
Remove toggle_config, it wasn't very useful because the settings still
test y/n in order to show specific confirmation and success messages.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Blob jail provides device firmware blobs to the OS, so the OS does not
have to ship them. The firmware is passed through the initrd to
/run/firmware, so it works with both installed and live OSes, and there
are no race conditions between firmware load and firmware availability.
The injection method in the initrd is specific to the style of init
script used by PureOS, since it must add a copy command to copy the
firmware from the initrd to /run. If the init script is not of this
type, boot proceeds without device firmware.
This feature can be enabled or disabled from the config GUI.
Blob jail is enabled automatically if the Intel AX200 Wi-Fi module is
installed and the feature hasn't been explicitly configured.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Mini v1/v2's EC can automatically power on the system when power is
applied, based on a value in EC BRAM. Add a configuration setting to
optionally set this value.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Boards can place a file in $(board)/initrd/bin/board-init.sh to perform
board-specific initialization.
If present, the board's $(board)/initrd directory is included in the
initrd via board.initrd.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
USB autoboot automatically boots to a USB flash drive if one is present
during boot. This is intended for headless deployments as a method to
recover the installed operating system from USB without needing to
attach a display and keyboard.
USB autoboot can be controlled in config.user and the config GUI.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Restricted Boot mode only allows booting from signed files, whether that
is signed kernels in /boot or signed ISOs on mounted USB disks. This
disables booting from abitrary USB disks as well as the forced "unsafe"
boot mode. This also disables the recovery console so you can't bypass
this mode simply by running kexec manually.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
PureBoot Basic mode provides the full Linux userspace in firmware from
Heads without requiring verified boot or a Librem Key. Basic and
verified boot can be switched freely without changing firmware, such as
if a Librem Key is lost.
PureBoot Basic can apply firmware updates from a USB flash drive, and
having a complete Linux userspace enables more sophisticated recovery
options.
Basic mode boots to the first boot option by default, setting a default
is not required. This can be configured in the config GUI.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Add these two functions for use in config-gui.sh for future toggles.
load_config_value() obtains the value of a config setting, defaulting
to 'n'. get_config_display_action() displays 'Enable' or 'Disable'
depending on the current value.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
enable_usb_storage() inserts usb-storage.ko if not already loaded, then
waits for USB storage devices to appear.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
pause_automatic_boot() prompts that an automatic boot is about to occur
and allows the user to interrupt it.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Extract utilities from config-gui.sh for use in additional config
settings. read_rom() reads the current ROM with a message for failure.
replace_rom_file() replaces a CBFS file in a ROM. set_config() sets a
configuration variable in a file.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Currently Heads will check files in /boot for tampering before booting
into a system. It would be nice if you could use the trusted environment
within Heads and extend this to check files in / itself. This new script
adds that functionality, however due to the length of time it takes to
perform these kinds of checks, it doesn't run automatically (yet).
This feature can be configured from the config GUI - the root device/
directories to check can be set, and it can be configured to run during
boot.
To make this a bit easier to use, I added a feature to detect whether
the hash file exists and if not, to display a more limited menu to the
user guiding them to create the initial hash file. Otherwise it will
display the date the file was last modified, which can be useful to
determine how stale it is.
Reduce friction when generating a new TOTP/HOTP secret by eliminating
an unnecessary 'press enter to continue' prompt following QR code
generation, and by attempting to use the default admin PIN set by
the OEM factory reset function. Fall back to prompting the user
if the default PIN fails.
Also, ensure error messages are visible to users before being returned
back to the GUI menu from which they came by wrapping existing calls to die()
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
On machines without a TPM, we'd still like some way for the BIOS to
attest that it has not been modified. With a Librem Key, we can have the
BIOS use its own ROM measurement converted to a SHA256sum and truncated
so it fits within an HOTP secret. Like with a TPM, a malicious BIOS with
access to the correct measurements can send pre-known good measurements
to the Librem Key.
This approach provides one big drawback in that we have to truncate the
SHA256sum to 20 characters so that it fits within the limitations of
HOTP secrets. This means the possibility of collisions is much higher
but again, an attacker could also capture and spoof an existing ROM's
measurements if they have prior access to it, either with this approach
or with a TPM.
Signed-off-by: Kyle Rankin <kyle.rankin@puri.sm>
On some newer platforms of intel (confirmed on nehalem, sandy/ivy
bridge), coreboot after commit [2ac149d294af795710eb4bb20f093e9920604abd](https://review.coreboot.org/cgit/coreboot.git/commit/?id=2ac149d294af795710eb4bb20f093e9920604abd)
registers an SMI to lockdown some registers on the chipset, as well
as access to the SPI flash, optionally. The SMI will always be triggered
by coreboot during S3 resume, but can be triggered by either coreboot
or the payload during normal boot path.
Enabling lockdown access to SPI flash will effectly write-protect it,
but there is no runtime option for coreboot to control it, so letting
coreboot to trigger such SMI will leave the owner of the machine lost
any possibility to program the SPI flash with its own OS, and becomes
a nightmare if the machine is uneasy to disassemble, so a scheme could
be implement, in which the SMI to lockdown chipset and SPI flash is left
for a payload to trigger, and temporarily disabling such triggering in
order to program the SPI flash needs authentication.
I have implemented a passcode-protected runtime-disableable lockdown
with grub, described [here](https://github.com/hardenedlinux/Debian-GNU-Linux-Profiles/blob/master/docs/hardened_boot/grub-for-coreboot.md#update-for-coreboot-after-commit-2ac149d294af795710eb4bb20f093e9920604abd). In order to implement a similar scheme for
Heads, I wrote [io386](https://github.com/hardenedlinux/io386).
With this commit, io386 will be called before entering boot routine
to trigger the SMI to finalize the chipset and write protect the SPI
flash at the same time. Entering recovery shell will leave the flash
writable.
(The authentication routine implemented in previous revisions has been
split as an independent commit.)
Originally proposed under PR#326
This isn't in a loop, continue makes no sense. ash had silently
ignored it. Proceeding to the do_boot below is the correct behavior.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
For partitioned media or when more than one device is present, this
fixes a benign script error that ash had apparently ignored.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
- Trace calls need to happen after sourcing /etc/functions not before
- Move sourcing of external files at beginning of file, remove /etc/functions sourcing duplicate
- gpg error redirection was sent to /dev/null where expected to be added to whiptail in case of error (2>&1 instead and redirection to file)
Problem
When using a custom password for TPM, the OEM re-ownership process is broken
Impact
The OEM re-ownership process breaks for any user setting a custom password and not just using 12345678
First appeared
6923fb5e20
Detail
on line 498, if blank, the TPM custom password is overwritten with TPM_PASS_DEF (eg, when no custom password is set by the user installing)
```
if [ "$TPM_PASS" == "" ]; then TPM_PASS=$TPM_PASS_DEF; fi
```
so far so good. $TPM_PASS should be used for all TPM interaction from this point. $TMP_PASS_DEF is now a disposed of variable.
we see that happens when resetting the TPM on line 712 (generate_checksums) is that $TPM_PASS is used (correctly)
```## reset TPM and set password
if [ "$CONFIG_TPM" = "y" ]; then
echo -e "\nResetting TPM...\n"
tpmr reset "$TPM_PASS" >/dev/null 2>/tmp/error
---SNIP
```
The TPM now has either the custom password of the user, or the default of 12345678 depending on user selection.
On line 712, we duck into the generate_checksums sub, which for some reason reverts to TPM_PASS_DEF
```
# create Heads TPM counter
if [ "$CONFIG_TPM" = "y" ];then
if [ "$CONFIG_IGNORE_ROLLBACK" != "y" ]; then
tpmr counter_create \
-pwdo "$TPM_PASS_DEF" \
--SNIP
```
This then, rightly, fails due to
```
Authentication failed (Incorrect Password) (ox1) from TPM_CreateCounter
```
- /tmp/initrd_extract was attempted to be deleted while under that directory when no crypptab found.
- changing of directory to / is non-conditional prior of deletion: move to cleaning step
- Clarity on message displayed to user when a generic crypttab will be generated in case of no OS override
TPM password must be 1-32 characters. Loop if the password is not
valid or the repeated password doesn't match, so the user can try
again.
Move prompt_new_owner_password to functions and use in both gui-init
and tpm-reset.
Fixes#1336
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
They're the same other than a TRACE, combine them. Use busybox
insmod since the insmod script uses bash, we don't need the TPM PCRs on
legacy-flash-boards.
Remove PCR4 extend, these boards lack TPM configuration. Update ROM
example name.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
init must use busybox ash because it is used on legacy-flash boards.
Change shebang, move needed functions to ash_functions.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Multiple traps overwrite each other. While no tpmr functions have more
than one trap right now, it is fragile, and the quoting is complex due
to double expansion. Use at_exit to add exit handlers that accumulate
and do not require special quoting.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
tpm-reset is just a prompt for the password followed by tpmr reset.
oem-factory-reset already bypasses the prompt, just call tpmr reset
directly.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
These were still writing some debugging output containing flags and
PCRs even when debug was not enabled. Use DEBUG.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
We just set the TPM owner password, so there's no need to make the user
enter it again. Eliminates some failure modes if the user mistypes it
or enters the wrong password.
Allow optionally passing in the TPM owner password in tpmr seal,
check_tpm_counter(), seal-totp, and generate_totp_htop(). The user is
still prompted if the password is needed but was not provided, so
existing uses in other contexts continue to work unchanged.
Prompt for the password in reset_tpm() and pass it down to each of the
above.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Heads doesn't use the endorsement hierarchy, but we shouldn't leave it
with an empty password following a tpm2 clear.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Don't hash password used to seal an object. This limits the password
to 32-characters but avoids obfuscating the usage of the password. The
32-character limit is considered acceptable because password limits are
lower already (GPG token limits to 25 chars). We may allow >32 char
passwords in the future by hashing only if the password is >32 chars.
Always pass passwords as hex to tpm2-tools to avoid possible ambiguity
if the password begins with a control prefix like 'hex:' or 'file:'.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Set consistent dictionary lockout parameters suited to Heads. Disable
lockout reset by setting a random password.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
gui-init: do not consume two unseal attempt to unseal both totp and hotp + cosmetic changes (slow down TPM DA lockout)
kexec-seal-key: Add DEBUG statement for PCR precalc
seal-totp: add DEBUG statements regarding skipping of PCR5 and PCR6 involvement into TOTP/HOTP sealing ops
seal-hotpkey: Add DEBUG statements related to reuse of TOTP sealed secret
tpmr: add DO_WITH_DEBUG calls to output pcrread and extend calls
tpmr: typo correction stating TRACE calls for tpm2 where it was for tpm1
tpmr: add DO_WITH_DEBUG calls for calcfuturepcr
functions: Cosmetic fix on pause_recovery asking user to press Enter to go to recovery shell on host console when board defines CONFIG_BOOT_RECOVERY_SERIAL
Not so related but part of output review and corrections:
kexec-insert-key: cosmetic changes prepending "+++" to disk related changes
kexec-save-default: cosmetic changes prepending "+++" to disk related changes
config/coreboot-qemu-tpm*.config: add ccache support for faster coreboot rebuild times
We already have HMAC sessions for encryption and decryption, there's no
need to create an ad-hoc session in tpm2_unseal.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
tpm2-tools is able to log pcap files of TPM2 commands, which can be
inspected with wireshark. Add CONFIG_TPM2_CAPTURE_PCAP to capture
these from the tpmr wrapper, and enable for qemu TPM2 boards.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
TPM2 must be prepared for shutdown, or it may track an auth failure for
dictionary attack prevention (per the spec, to prevent an attack by
attempting to authenticate and then powering off the TPM before it can
update the nonvolatile counter).
Add tpmr shutdown to prepare for shutdown (no-op on TPM1). Invoke it
from poweroff and reboot.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Provide tpmr commands pcrread, pcrsize, calcfuturepcr, and seal for
both TPM1 and TPM2.
Combine seal logic for TPM1/TPM2 in seal-totp, kexec-seal-key. This is
essentially the TPM2 logic now that tpmr provides the same wrapped
commands for both TPM1 and TPM2.
Remove algorithm prefix from PCR list in tpmr unseal for consistency
with tpmr seal.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
tpmr extend with -ic (extend with literal data) was adding a newline,
use echo -n so it only includes the data given in the hash.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Clean up TODO comments.
Clean up redirections for tpm2 pcrread, use bash redirect to command.
Use DO_WITH_DEBUG --mask-position to trace tpmr seal for TPM2 and hide
the password.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
No need to test whether bash is a symlink, bash ships on all boards
using the normal init script now.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Provide mask_param() function to uniformly mask secret parameters,
while still indicating whether they are empty.
Extend DO_WITH_DEBUG to allow masking a password parameter by position,
using mask_param(). Move from ash_functions to functions (isn't used
by ash scripts).
Mask password parameters in kexec-unseal-key and tpmr seal. Use
mask_param() on existing masked params in tpmr.
Trim more troubleshooting output from tpm2_extend() in tpmr.
Clarify tpmr kexec_finalize echo; it's the TPM's platform heirarchy,
users might not know what this was referring to.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Provide an HMAC session to tpm2 when unsealing with an auth policy.
The HMAC session is used for transport encryption.
This allows transport encryption to work when unsealing.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Remove dump of all PCRs from tpm2_extend, it was causing other errors
to roll off the screen before they could be inspected, and it's no
longer needed now that TPM2 is working.
Silence nonsense errors from unseal if TPM2 hasn't been reset. tpm2 -S
with a file that doesn't exist would complain that the parameter format
was not understood (looks like a script error), when the actual problem
was that the file doesn't exist yet. We can't try to unseal anyway
without a primary handle, so just exit unsuccessfully in that case.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Busybox no longer has CONFIG_BASH since we are deploying bash on most
boards. We also should clearly indicate which scripts cannot use
bashisms.
Change shebang in x230-flash.init, t430-flash.init, flash.sh to
/bin/ash. Execute /bin/sh for interactive shells.
Move key functions needed by those scripts to initrd/etc/ash_functions.
Source ash_functions instead of functions in those scripts, so any
bashisms in other functions won't break parsing of the script in ash.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
bash will not be the default interactive shell since readline support
increases the binary size significantly. Use /bin/sh (busybox ash) for
that.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Use /bin/sh (ash in busybox builds) for interactive shells, not bash.
Preparation for trimming interactive features from bash to reduce size.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
The size parameter is actually the size of the sealed secret to TPM1,
not the unsealed data size. TPM2 does not observe the sealed secret,
so just ignore that parameter.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Provide tpmr unseal to unseal a file with TPM1 or TPM2. For TPM1, it
wraps tpm nv_readvalue and tpm unsealfile. For TPM2, it wraps tpm2
unseal.
kexec-unseal-key, seal-hotpkey, unseal-hotp, and unseal-totp no longer
need to differentiate TPM1/TPM2.
Fixes spurious shred errors on TPM2 that only apply to TPM1 (temporary
sealed secret file and shred are now internal to tpmr).
Fixes TPM1 disk unlock key unsealing due to logic errors relating to
exit status of tpmr unseal or tpm unsealfile (now always uses status of
tpmr unseal).
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
TPM2 locks the platform heirarchy, flushes transient objects, and
flushes sessions. (This now cleans up sessions created during
startsession that previously were not cleaned up, although the OS might
flush all sessions as well.)
TPM1 currently does not do anything, but the command is accepted so
kexec-boot does not need to differentiate TPM1/2.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
TPM2 is only required to support password lengths up to its longest
hash size (32 chars for sha256). Pass the sha256 of the password
instead of the actual password so the password can be arbitrarily long.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Set flags 'fixedtpm|fixedparent|adminwithpolicy'. Plain password auth
is no longer allowed. For objects sealed with a password, the password
is part of the auth policy, so both PCRs and password must be satisfied
to unseal.
Tested by manually attempting to unseal disk unlock key with password:
tpm2 unseal -c 0x81000003 -p "<password>"
This now correctly returns an error indicating this auth method is not
allowed.
Relative to the documented default flags for tpm2_create:
* sign, decrypt: Not applicable to a sealed object, tpm2_create
automatically removed these from the defaults.
* fixedtpm, fixedparent: Kept
* sensitivedataorigin: Not applicable an object where the sensitive
data is not generated by the TPM.
* userwithauth: Removed this, "user" actions must satisfy auth policy.
* adminwithpolicy: Added this, "admin" actions must satisfy auth
policy.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
After saving a disk unlock key, if debug output is enabled, drop to
a recovery shell to allow inspection of debug output.
The script isn't intended to return from this point after sealing a
key - returning attempts to boot, which can't unseal the key.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Trace parameters to seal/unseal and some key tpm2 invocations. Trace
invocation of tpmr seal/unseal for disk unlock key.
Add DO_WITH_DEBUG() to trace a command and parameters, then execute it.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
When sealing/unsealing with a password, use a policy including both the
specified PCRs and the object password. Fixes sealing and unsealing
disk unlock key.
tpm2 seems to have a bug in parameter decryption when using a policy
session and password in this way, disable encryption in the policy
session as a workaround.
Flags still need to be set on the sealed object correctly, as the
password is normally allowed on its own as an alternative to policy
auth.
Add -Q to some tpm2 invocations to silence diagnostics on stdout.
Pass filename for unsealed secret rather than capturing from stdout
for robustness against tpm2 diagnostics on stdout.
Fix unseal result check in kexec-unseal-key.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
- /tmp/debug.log is created and appended by all TRACE and DEBUG calls in code
- fix some logic errors seen when no DEBUG entry were outputted in /tmp/debug.log
Always send password via stdin to tpm2 create, tpm2 unseal. The password
could being with things like 'file:', 'str:', 'pcr:' that would be
interpreted by tpm2.
Deduplicate the TPM1/2 code in kexec-unseal-key. The TPM2 code was not
actually prompting for the password or sending it to tpmr unseal.
Password is still not working yet though.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Most logic throughout Heads doesn't need to know TPM1 versus TPM2 (and
shouldn't, the differences should be localized). Some checks were
incorrect and are fixed by this change. Most checks are now unchanged
relative to master.
There are not that many places outside of tpmr that need to
differentiate TPM1 and TPM2. Some of those are duplicate code that
should be consolidated (seal-hotpkey, unseal-totp, unseal-hotp), and
some more are probably good candidates for abstracting in tpmr so the
business logic doesn't have to know TPM1 vs. TPM2.
Previously, CONFIG_TPM could be variously 'y', 'n', or empty. Now it
is always 'y' or 'n', and 'y' means "any TPM". Board configs are
unchanged, setting CONFIG_TPM2_TOOLS=y implies CONFIG_TPM=y so this
doesn't have to be duplicated and can't be mistakenly mismatched.
There were a few checks for CONFIG_TPM = n that only coincidentally
worked for TPM2 because CONFIG_TPM was empty (not 'n'). This test is
now OK, but the checks were also cleaned up to '!= "y"' for robustness.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Use common password prompt logic in tpm-reset rather than duplicating
in tpmr reset.
Use common logic in config-gui.sh to reset the TPM.
Use common logic in oem-factory-reset to reset TPM. Fixes extra
prompts for TPM2 owner password even when choosing to use a common
password. Fix sense of "NO TPM" check in TOTP generation (which only
happened to work because CONFIG_TPM is empty for TPM2).
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
$CONFIG_TPM needs to be quoted, or [ syntax is incorrect when it's
empty. Fixes errors in console with TPM2 (but behavior was correct due
to [ still returning false as expected).
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Resetting the TPM creates a new primary object, and there is no reason
for kexec-save-default to sign an old hash. Always update the hash
instead of creating it only if it doesn't exist.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Resetting the TPM invalidates the primary handle hash, and
kexec-save-default only generates a hash if none exists. Remove the
hash file when it is invalidated.
OEM reset and "Reset Configuration" both already remove all kexec
files.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
-coreboot support of TPM v2.0 (shared config for TPM2 support across all 4 previous variations)
-swtpm set to be launched under TPM v2.0 mode under board config
-Documentation file under each board.md softlinks to qemu-coreboot-fbwhiptail-tpm1.md (which has been generalized)
This is skeleton for TPM v2 integration under Heads
-------------
WiP
TODO:
- libcurl cannot be built as a tpm2-tools dependency as of now not sure why. curl currently needs to be added in board config to be built
- Note: tpm-reset (master and here) needs some review, no handle of no tpm use case. Caller is responsible to not call it otherwise does nothing
- init tries to bind fd and fails currently
- Note: Check if whiptail is different of fbwhiptail in clearing screen. As of now every clear seems to be removed, still whiptail clears previous console output
- When no OS' /boot can be mounted, do not try to TPM reset (will fail)
- seal-hotpkey is not working properly
- setting disk unlock key asks for TPM ownership passphrase (sealing in NV requires ownership, but text is misleading user as if reowning TPM)
- We should cache input, feed tpm behind the scene and wipe passphrase and state clearly that this is TPM disk unlock kye passphrase.
- primary key from TPM2 is invalid most of the time from kexec-select-boot and verifying global hashes but is setuped correctly at disk unlock key setup
- would be nice to take advantage of bash function tracing to understand where we are for debugging purposes, code takes ash in consideration only
- tpmr says it implements nv calls but actually doesn't. Removing those falsely wrapped functions would help.
- Implementing them would be better
- REVIEW TODOS IN CODE
- READD CIRCLECI CONFIG
Current state:
- TPM unseal works without disk unlock key and generates TOTP properly (was missing die condition at unseal to not produce always good TOTP even if invalid)
- TPM disk encryption key fails. Hypothesis is that sealing with USB drivers loaded and measures in inconsistent with sealed with/without.
- TPM disk unsealing happens without USB modules being loaded in non-HOTP setup. This fails.
- Current tests are with fbwhiptail (no clear called so having traces on command line of what happens)
- Testing with HOTP implementation for sealing/unsealing since that forces USB module loads on each boot to remove this from failing possibilities
- Add TRACE function tracing output under etc/functions, depending on CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT enabled in board configs
- Replace current DEBUG to TRACE calls in code, reserving DEBUG calls for more verbose debugging later on (output of variables etc)
- add 'export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y' in qemu-coreboot(fb)whiptail-tpm1(-hotp) boards to see it in action
- kexec-save-default extracts initrd crypttab files and creates /boot/kexec_initrd_crypttab_overrides.txt entries pointing to /secret.key
- kexec-insert-key applies /boot/kexec_initrd_crypttab_overrides.txt to replace initrd's crypttabs files pointing to inserted /secret.key through cpio
- Both scripts inform the user of applied magic on screen
Not all distro put crypttab under /etc/ within initramfs, but finding it at
runtime needs unpacking, which may be hard to do, so it is made overridable
with a file at /boot/kexec_initrd_crypttab_path.txt, whose content could be
obtained with $ cpio -t < ${uncompressed_initrd} | grep crypttab .
The "target" field of the record within the crypttab stored in the root
file system for the luks container which is going to be unlocked via
kexec-insert-key should be modified into the same "luks-$uuid" format,
otherwise the boot sequence will get stuck when OS is trying to unlock them
again, in order to map them according to "target" fields written in the
crypttab stored in the root fs.
Adds check to detect device formatted as fat32 without partition table.
With fat32 fdisk does not print message about invalid partition table
and instead it'll print an empty table with header.
In both cases total output has the same length of 5 lines: 3 about
device info, 1 empty line and the 5th will be the table header or
invalid partition message.
Signed-off-by: Daniel Pineda <daniel.pineda@puri.sm>
Since it's not supposed to be shell safe, just display safe
inside double quotes, we can allow some more characters.
Also fix the escape character not being escaped.
busybox sha256sum will create a checksum file for uncommon file names
(e.g. /boot/foo"$\n"bar), but fail to verify that exact file.
https://bugs.busybox.net/show_bug.cgi?id=14226
Thus disallow all files in /boot/ with strange file names at the time of
signing for now. Verifying in the presence of new files with such file
names in /boot/ is no issue for the kexec_tree verification due to the
previously implemented escaping mechanism.
Attempt to fix the following issues:
1. unescaped file names may let an attacker display arbitrary
whiptail prompts --> escape, original code by @JonathonHall-Purism
2. whiptail itself allows escape characters such as \n
--> use an escape character not used by whiptail, i.e. #
3. performance issues caused by diff'ing too early -->
only generate a diff to display to the user, if an actual issue is
found
If the user selects "continue to main menu" from an error, do not show
any more error prompts until reaching the main menu.
We still try to initialize everything (GPG, TOTP, HOTP) so that the
main menu can still show TOTP/HOTP if GPG is not configured, etc., but
no more prompts are shown after selecting "continue to main menu".
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
A lot of echo_entry() is now common to elf/multiboot/xen kernels, just
branch for the type-specific logic.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
If a boot option doesn't refer to a valid file for the kernel/initrd,
ignore it. Such an option is never bootable, because we would fail to
find the kernel/initrd. This could happen if the path contained GRUB
variables, or specified a device that wasn't /boot, etc.
This is checked before expanding GRUB variables. It's unlikely that
any kernel/initrd path containing variables would end up working when
all variables expand to nothing (since we do not handle GRUB
variables).
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Some configs specify kernel/initrd paths relative to a device (often
found in a variable). Assume the device is the /boot partition and
ignore the device specification.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Extract exclusion for unpartitioned block device of partitioned media
to gui_functions, and exclude them even if kernel hasn't listed the
partitions yet. (Fixes flash/USB boot prompts incorrectly trying to
use the whole device for partitioned media the first time.)
Ignore block devices of size 0, like empty USB SD card readers.
Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
- Have Talos II supported by detecting correctly size of mtd chip (not internal: different flashrom output needs to be parsed for chip size)
- Read SPI content only once: 66% speedup (TOCTOU? Don't think so, nothing should happen in parallel when flashing insingle user mode)
- Have the main flash_progress loop not break, but break in flash_rom state subcases (otherwise, verifying step was breaking)
- Change "Initializing internal Flash Programmer" -> "Initializing Flash Programmer"
- Apply changes suggested by @SergiiDmytruk under https://github.com/osresearch/heads/pull/1230#issuecomment-1295332539 to reduce userland wasted time processing flashrom -V output
It specifies whitespace-separated list of console devices to run Heads
on in addition to the default one.
Example for board config:
export CONFIG_BOOT_EXTRA_TTYS="tty0 tty1"
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
EC signatures requires that the digest has the corresponding length. Removing the hardcoded sha2-256 hash function and adding support of sha2-384 and sha2-512 should allow using EC crypto.
- Take System Info changes from 06311ff068 (Thanks to @nestire)
- Move changes to seperate script under /bin/oem-system-info-xx30
- Add additional camera and wifi card IDs, add synaptic touchpad detection if kernel has module built in
Above changes squashed in this commit.
Since /etc/luks-functions are currently exporting passphrases tested good per cryptsetup to be reused in the code,
the logic calling both luks_reencrypt and luks_change_passphrase testing for non-empty luks_current_Disk_Recovery_Key_passphrase
was bogus.
This commit includes a new variable luks_new_Disk_Recovery_Key_desired which is set when reencryption is desired.
The 3 use cases (reencrypt+passphrase change, reencrypt no passphrase change and passphrase change alone now only test
for luks_new_Disk_Recovery_Key_desired and luks_new_Disk_Recovery_Key_passphrase_desired, nothing else.
network-init-reovery can be used to automatically set RTC clock to obtained NTP clock.
The script would fail if other devices devices previously registered on the network with the same MAC.
Consequently, maximized boards are detected here, and a full random MAC is generated and used instead of using hardcoded DE:AD:C0:FF:EE.
This continues to generate checksums and sign them per new GPG User PIN, but does not set a default boot option.
The user hitting Default Boot on reboot will go through having to setup a new boot default, which will ask him to setup a Disk Unlock Key if desired.
Otherwise, hitting Default Boot goes into asking the user for its Disk Recovery Key passphrase, and requires to manually setup a default boot option.
Simplify the menu options by removing the duplication of the entry name
in the menu selections; instead, use clear verbiage to distinish
between booting one time and making the default. And as the majority of
the boot menu is shown is when the grub entires have changed and the
user is prompted to select a new default, so make that the first/default
menu option.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Drop the duplicated kernel info which hurts readability, runs off the
end of the menu window. This also makes it easier to identify which
menu option is the default, and more closely resembles the grub menu
shown in a traditional BIOS boot.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
- initrd/bin/oem-factory-reset: adds a measured integrity output prior of prompts. Goal is for stating TOTP/HOTP/boot detached signed measurements prior of initiating a Re-Ownership, validating provisioned OEM state.
- initrd/bin/gui-init : Add two additional menu options to LUKS reencrypt and LUKS passphrase change, calling functions of initrd/bin/reencrypt-luks
- initrd/bin/gui-init : Add option F for EOM Factory Reset / Reownership when no public key is exported by key-init
oem-factory-reset: adapt code so that custom passphrases can be provided by user without changing oem factory reset workflow.
oem-factory-reset: output provisioned secrets on screen at the end of of the process.
oem-factory-reset: warn user of what security components will be provisioned with defaults/customs PINs prior of choosing not after
gui-init and oem-factory-reset: change OEM Factory Reset -> OEM Factory Reset / Re-Ownership to cover actual use cases
bin/kexec-parse-boot: test 2bb1f52bf5 that fix correctly comma seperated arguments.
Still TODO: when booting, Heads tries to find where the ISO with /dev/disk/by-label/ARCH_202202 wich is never brought up. uuids could, not sure why the label is not brought up correctly. Maybe an issue in the way Arch makes the ISO.
@tslilc : Any idea to continue #584 or modify #762?
It is going to be enabled later anyway (if CONFIG_HOTPKEY=y), so it can
also be simplified by enabling it at the very beginning.
This enables USB keyboard consistently during all boot menus, including
the "No Bootable OS Found" prompt. It isn't a big deal for "normal"
laptop usage, but it is important for automatic tests and also
non-laptop systems.
Show state of flashrom reads/writes by means of a progress bar,
as used in the Librem coreboot flashing scripts
v2: add adjustment for use with `--ifd`
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
-CircleCI addition.
-Removal of t530-flash, w530-flash boards, flash scripts and associated coreboot configs (no more legacy boards additions)
This is a merger of #1071, #1072 and #1073 so that test builds are available over CircleCI until osresearch/master CircleCI gets unlocked.
When files in /boot fail hash verification, the list of files
can sometimes overflow the whiptail msgbox, preventing the
prompt and buttons to update checksums from showing. To mitigate
this, if # of files is > 10, use less to show the file list and
present a separate prompt to update the checksums once the file
list has been viewed.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
- Fixed inversed HEIGHT and WIDTH usage
- Fixed height to 30 and width to 90 as everywhere else
This was causing a blank screen when whiptail without framebuffer (fbwhiptail) was used.
Actually, it seems like the width and height under whiptail calls are only taken into consideration under NEWT, not FBWHIPTAIL.
Some devices, like older Librem laptops, use BAT vs BAT0 for the
primary battery. Accomodate this by using BAT* instead of BAT0.
Could break on multi-battery devices, but none supported in tree
currently so more of a theoretical problem.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
copy/paste error resulted in user-entered comment never
being set/checked/used, and email address being overwritten.
Fix variable usage so comment and email are set correctly.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Grepping on just 'Disk' can lead to disk UUID identifier strings
being added to /tmp/disklist, which then fail to parse later on.
Avoid this by grepping on 'Disk /dev' instead.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
After updating/flashing a new ROM, a new TOTP secret must be generated,
but the $TOTP variable needs to be updated afterwards, otherwise it
will show the previous failure which led to the new secret being
created.
Fix this by re-calling update_totp() after generating a new secret
or resetting the TPM.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
If user selects to manually update the TOTP via the menu,
we should do it regardless of elapsed time from previous
check. Otherwise, HOTP will be checked regardless of validity
of TOTP.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Modify update_checksums() to return 0/1 on success/failure, and modify
callers to notify the user on error with a GUI msg.
Set background color as appropriate in gui-init.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Currently, if no disks on system, selection of a new /boot
device will silently fail and simply return the user to the
previous screen. Add an error dialog if no disks found.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Persist the background color (and error state) through
the main menu and all submenus. Use warning
background color for destructive operations, error color
for errors.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Checking the keyring for a GPG and updating the TOTP/HTOP
status need only happen once at initial boot; the latter
can be updated at any later time from the main menu itself.
Having them repeated each loop of the main menu is unnecessary
(and often annoying). Likewise, the default auto boot can be
moved and the first_pass (and unused MAIN_MENU_OPTIONS)
variable dropped.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Now that all menu options are encapsulated in shell
functions, move menu handling from the main loop to
inside the menu/submenu function itself.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Break menus and menu items into functions where possible.
Improves readability of code / functional flow, and
makes future refactoring easier.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Name better reflects function purpose, allows 'update_totp'
to be used to actually update the TOTP code.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
strings from $cmdremove should only be removed from $cmdline if they are enclosed by spaces of if they are at the beginning of $cmdline followed by a space or if they are at the end of $cmdline prepended by a space
if CONFIG_AUTO_BOOT_TIMEOUT exists and is set, and if HOTP
validation was successful, then attempt to boot the default
target after CONFIG_AUTO_BOOT_TIMEOUT seconds if not interrupted
by key press
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
The -u arg does not take a parameter, so remove the trailing colon.
Fixes /boot hashes not being updated when update_checksums() is called.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
If an installed OS is not detected, then skip setting the
default boot device or generating /boot checksums.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Check for presence of CONFIG_BOOT_DEV, and if missing or
unable to be mounted, present the user with a menu offering the
option to select another disk, boot from USB, continue to
main menu, or drop to a recovery shell.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Set and export currently-used defaults in gui-init, but still
allow for inidividual boards to override via config if desired.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Strip the path prefix from the ROM filename, and place on own
line to prevent truncation with long filenames / narrow screens.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
This will allow it to be used elsewhere within the UI.
Rename CONFIG_BOOT_GUI_MENU_NAME to better indicate use/function.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
* modules/coreboot: add option to use coreboot 4.11
Port patches from coreboot 4.8.1 to 4.11:
* 0000-measure-boot -> 0001
* 0010-cross-compiler-support
All other patches for coreboot 4.8.1 have either already been
integrated, or are for platforms which do not need to be migrated
to coreboot 4.11 (they will move to 4.12 or newer).
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
* patches/coreboot-4.11: Add Broadwell-DE platform patch
Add a patch for FSP Broadwell-DE to make use of Heads' measured boot.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
* patches/coreboot-4.11: Add patch to read serial # from CBFS
Will be used by multiple Librem boards.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
* patches/coreboot-4.11: add board support for Librem Server L1UM
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
* Librem Server L1UM: add new board
Add board config, coreboot config, kernel config files.
Add conditional purism-blobs dependency to coreboot-4.11 module.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
* flash.sh: add special handling for librem_l1um board
Add support for persisting PCIe config via PCHSTRP9 in flash descriptor.
This is needed to support multiple variants of the L1UM server which
use the same firmware but differ in PCIe lane configuration via the
PCH straps configuration in the flash descriptor.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
* patches/coreboot-4.11: Add 'Use PRIxPTR to print uintptr_t' patch
Cherry-picked from upstream coreboot (post-4.11), fixes compilation issue.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
* CircleCI: add target to build board librem_l1um
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Update_checksum was already changing files in /boot, befor checking for
gpg card. If no card is present, the user will end up in the recovery
next time instead of getting the same dialog again. Therefore, the
confirm_gpg_card should be checked before altering files.
The dead -u flag/$update_counter is used to mark the necessisty to
update the hash files now.
Currently, exiting the recovery shell results in a kernel panic,
necessitating a hard reset / power cycle. As this is less than ideal,
drop the exec and add a loop to restart the shell.
Addresses issue #833
Tested under qemu-coreboot-fbwhiptail
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Changing the default boot was failing because remove the old entries did
not work as `rm "/some/path/*.txt"` does not work as intended, e.g. the
asterisk is no catch-all.
Some grub configs/bls entries contain the full paths to the
kernel/initrd files, which the parsers currently fail to handle,
causing a failed boot without any useful error being presented to the user.
To fix this, strip the bootdir prefix from the menu entries when parsing,
should it exist.
Test: build/boot Librem 13v2 w/F32 and bls entries containing absolute paths.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
When a new /boot device is selected, wait until after
successfully mounting the newly-selected device before
updating CONFIG_BOOT_DEV.
Also, don't assume /boot already mounted, as this can cause
a false failure and prevent mounting of the newly-selected device.
Lastly, tidy up the error output in case mounting /boot fails.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Using 'let' in these scripts fails when evaluating to zero
for some reason, so replace with '$(())' which works as intended.
Test: Boot device selection menu shown properly when
new/unpartitioned drive installed.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
Attempting to reset the TPM when once isn't present causes a kernel
panic, so let's not allow users to do that.
Test: verify 'No TPM Detected' shown on Librem Mini when Reset TPM
option selected from menu.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>
-r will always succeed since the file will be generated regardless
of number of boot entries found. Use -s instead to check for zero
file size.
Signed-off-by: Matt DeVillier <matt.devillier@puri.sm>