2022-11-21 05:44:04 -05:00
|
|
|
#![no_main]
|
|
|
|
#![no_std]
|
2023-01-22 09:22:03 -05:00
|
|
|
#![deny(unsafe_op_in_unsafe_fn)]
|
2022-11-21 05:44:04 -05:00
|
|
|
|
2022-11-21 11:52:06 -05:00
|
|
|
extern crate alloc;
|
2022-11-21 10:22:44 -05:00
|
|
|
|
2023-05-22 17:28:59 -04:00
|
|
|
mod common;
|
2022-11-22 10:18:12 -05:00
|
|
|
|
2023-05-22 17:28:59 -04:00
|
|
|
#[cfg(feature = "fat")]
|
|
|
|
mod fat;
|
|
|
|
|
|
|
|
#[cfg(feature = "thin")]
|
|
|
|
mod thin;
|
|
|
|
|
2023-06-10 12:06:50 -04:00
|
|
|
#[cfg(all(feature = "fat", feature = "thin"))]
|
|
|
|
compile_error!("A thin and fat stub cannot be produced at the same time, disable either `thin` or `fat` feature");
|
|
|
|
|
2023-07-23 12:46:47 -04:00
|
|
|
use linux_bootloader::efivars::{export_efi_variables, get_loader_features, EfiLoaderFeatures};
|
|
|
|
use linux_bootloader::measure::measure_image;
|
|
|
|
use linux_bootloader::tpm::tpm_available;
|
|
|
|
use linux_bootloader::uefi_helpers::booted_image_file;
|
2023-05-22 17:28:59 -04:00
|
|
|
use log::info;
|
|
|
|
use uefi::prelude::*;
|
2022-11-22 10:18:12 -05:00
|
|
|
|
2023-07-23 12:46:47 -04:00
|
|
|
/// Lanzaboote stub name
|
|
|
|
pub static STUB_NAME: &str = concat!("lanzastub ", env!("CARGO_PKG_VERSION"));
|
2023-01-13 20:31:31 -05:00
|
|
|
|
2022-11-25 12:08:54 -05:00
|
|
|
/// Print the startup logo on boot.
|
2023-02-20 19:28:25 -05:00
|
|
|
fn print_logo() {
|
|
|
|
info!(
|
2022-11-25 12:08:54 -05:00
|
|
|
"
|
2023-02-20 19:28:25 -05:00
|
|
|
_ _ _
|
|
|
|
| | | | | |
|
|
|
|
| | __ _ _ __ ______ _| |__ ___ ___ | |_ ___
|
|
|
|
| |/ _` | '_ \\|_ / _` | '_ \\ / _ \\ / _ \\| __/ _ \\
|
|
|
|
| | (_| | | | |/ / (_| | |_) | (_) | (_) | || __/
|
|
|
|
|_|\\__,_|_| |_/___\\__,_|_.__/ \\___/ \\___/ \\__\\___|
|
|
|
|
|
2022-11-21 10:22:44 -05:00
|
|
|
"
|
2023-02-20 19:28:25 -05:00
|
|
|
);
|
2022-11-21 10:22:44 -05:00
|
|
|
}
|
2022-11-21 05:44:04 -05:00
|
|
|
|
|
|
|
#[entry]
|
2022-11-21 11:52:06 -05:00
|
|
|
fn main(handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
|
2022-11-21 05:44:04 -05:00
|
|
|
uefi_services::init(&mut system_table).unwrap();
|
|
|
|
|
2023-02-20 19:28:25 -05:00
|
|
|
print_logo();
|
2022-11-21 09:36:39 -05:00
|
|
|
|
2023-04-29 16:09:08 -04:00
|
|
|
if tpm_available(system_table.boot_services()) {
|
|
|
|
info!("TPM available, will proceed to measurements.");
|
2023-07-23 12:46:47 -04:00
|
|
|
// Iterate over unified sections and measure them
|
|
|
|
// For now, ignore failures during measurements.
|
|
|
|
// TODO: in the future, devise a threat model where this can fail
|
|
|
|
// and ensure this hard-fail correctly.
|
|
|
|
let _ = measure_image(
|
|
|
|
&system_table,
|
|
|
|
booted_image_file(system_table.boot_services()).unwrap(),
|
|
|
|
);
|
|
|
|
// TODO: Measure kernel parameters
|
|
|
|
// TODO: Measure sysexts
|
2023-04-29 16:09:08 -04:00
|
|
|
}
|
|
|
|
|
2023-04-28 21:51:39 -04:00
|
|
|
if let Ok(features) = get_loader_features(system_table.runtime_services()) {
|
|
|
|
if !features.contains(EfiLoaderFeatures::RandomSeed) {
|
|
|
|
// FIXME: process random seed then on the disk.
|
2023-04-29 16:09:08 -04:00
|
|
|
info!("Random seed is available, but lanzaboote does not support it yet.");
|
2023-04-28 21:51:39 -04:00
|
|
|
}
|
|
|
|
}
|
2023-07-23 12:46:47 -04:00
|
|
|
export_efi_variables(STUB_NAME, &system_table).expect("Failed to export stub EFI variables");
|
2023-04-28 21:51:39 -04:00
|
|
|
|
2023-05-22 17:28:59 -04:00
|
|
|
let status;
|
2023-02-02 10:29:48 -05:00
|
|
|
|
2023-05-22 17:28:59 -04:00
|
|
|
#[cfg(feature = "fat")]
|
|
|
|
{
|
|
|
|
status = fat::boot_linux(handle, system_table)
|
|
|
|
}
|
2023-02-02 10:29:48 -05:00
|
|
|
|
2023-05-22 17:28:59 -04:00
|
|
|
#[cfg(feature = "thin")]
|
|
|
|
{
|
stub: make handling of insecure boot more explicit
When Secure Boot is not available (unsupported or disabled), Lanzaboote
will attempt to boot kernels and initrds even when they fail the hash
verification. Previously, this would happen by falling back to use
LoadImage on the kernel, which fails if Secure Boot is available, as the
kernel is not signed.
The SecureBoot variable offers a more explicit way of checking whether
Secure Boot is available. If the firmware supports Secure Boot, it
initializes this variable to 1 if it is enabled, and to 0 if it is
disabled. Applications are not supposed to modify this variable, and in
particular, since only trusted applications are loaded when Secure Boot
is active, we can assume it is never changed to 0 or deleted if Secure
Boot is active.
Hence, we can be sure of Secure Boot being inactive if this variable is
absent or set to 0, and thus treat all hash verification errors as
non-fatal and proceed to boot arbitrary kernels and initrds (a warning
is still logged in this case). In all other cases, we treat all hash
verification failures as fatal security violations, as it must be done
in the case where Secure Boot is active (it is expected that this does
not lead to any false positives in practice, unless there are bigger
problems anyway).
2023-10-01 13:21:11 -04:00
|
|
|
status = thin::boot_linux(handle, system_table).status()
|
2023-02-02 09:54:27 -05:00
|
|
|
}
|
2023-05-22 17:28:59 -04:00
|
|
|
|
|
|
|
status
|
2022-11-21 05:44:04 -05:00
|
|
|
}
|