diff --git a/docs/guides/capsule-update.md b/docs/guides/capsule-update.md index 7039968898..054f14534b 100644 --- a/docs/guides/capsule-update.md +++ b/docs/guides/capsule-update.md @@ -29,6 +29,14 @@ mentioned, it means that it doesn't support this update method. | NovaCustom | NUC BOX | v0.9.0 | — | | Protectli | Vault VP66xx | v0.9.3 | — | +!!! note + + Enforcing capsule authentication in V2 made newer capsules incompatible + with the older ones. The first release with V2 publishes capsules of the + older kind which can be used to upgrade from prior releases, but starting + with this release **older capsules are no longer accepted** to not + compromise capsule authentication enhancements. + ## Prerequisites * _UEFI Shell_
diff --git a/docs/kb/capsule-updates-configs.md b/docs/kb/capsule-updates-configs.md index c90453af58..3de5f1aeae 100644 --- a/docs/kb/capsule-updates-configs.md +++ b/docs/kb/capsule-updates-configs.md @@ -1,9 +1,9 @@ # Capsule Update releases Dasharo releases that support Capsule Updates need to include a number of -additional options in their coreboot configuration file. The options correspond -to the required payload data described in -[Capsule Updates Details - Required Payload Data](./edk2-capsule-updates.md#capsule-information) +additional options in their coreboot configuration file. The most important +options directly correspond to the required payload data described in +[Capsule Updates Details - Required Payload Data](./edk2-capsule-updates.md#capsule-information). ## Configuration @@ -11,11 +11,17 @@ The coreboot configuration file can be found in the coreboot repository in the `configs/` directory under the name of `config._`. -The options that need to be set are: +The options that must be set are: -- `CONFIG_DRIVERS_EFI_MAIN_FW_GUID` -- `CONFIG_DRIVERS_EFI_MAIN_FW_VERSION` -- `CONFIG_DRIVERS_EFI_MAIN_FW_LSV` +- [`CONFIG_DRIVERS_EFI_MAIN_FW_GUID`](#config_drivers_efi_main_fw_guid) +- [`CONFIG_DRIVERS_EFI_MAIN_FW_VERSION`](#config_drivers_efi_main_fw_version) +- [`CONFIG_DRIVERS_EFI_MAIN_FW_LSV`](#config_drivers_efi_main_fw_lsv) + +The following settings may not be set (read their description to know under +which conditions): + +- [`CONFIG_EDK2_CAPSULES_V2`](#config_edk2_capsules_v2) +- [`CONFIG_EDK2_CAPSULES_V2_TRANSITION`](#config_edk2_capsules_v2_transition) ### CONFIG_DRIVERS_EFI_MAIN_FW_GUID @@ -40,8 +46,8 @@ Capsule Update. The `CONFIG_LOCALVERSION` option is a string representation of the version which does not allow reliable comparisons. The value consists of 8 hexadecimal digits which are grouped -into four groups of two numbers. Each group represents a single component of -a Dasharo version according to the [Versioning](https://docs.dasharo.com/dev-proc/versioning/) +into four groups of two digits. Each group represents a single component of +a Dasharo version according to the [Versioning](../dev-proc/versioning.md). `CONFIG_DRIVERS_EFI_MAIN_FW_VERSION` has to be updated on new releases to always match the `CONFIG_LOCALVERSION`. @@ -67,8 +73,38 @@ The value represents the lowest firmware version, that will be accepted as a valid one. A Capsule Update to a version lower than `CONFIG_DRIVERS_EFI_MAIN_FW_LSV` will not be allowed. May be used to forbid downgrading to versions with severe security vulnerabilities. The value -takes the same format as `CONFIG_DRIVERS_EFI_MAIN_FW_VERSION` +takes the same format as `CONFIG_DRIVERS_EFI_MAIN_FW_VERSION`. Examples: - Forbid changing the version to anything below release v0.1.0 - `CONFIG_DRIVERS_EFI_MAIN_FW_LSV="0x00010080"` + +### CONFIG_EDK2_CAPSULES_V2 + +This boolean option enables more advanced features: + +- Enforcing authentication of capsule images before processing them. +- Vendor's logo shown on the screen during an update, scaled proportionally. +- Smoother progress bar increments that better reflect amount of work done/left. +- Pop-up reporting success/failure of the firmware update with some diagnostic + information. +- Best-effort recovery if the update has failed halfway. + +Some devices don't have this option set, but newer releases may transition to +this version of capsules (see +[`CONFIG_EDK2_CAPSULES_V2_TRANSITION`](#config_edk2_capsules_v2_transition)). +Devices that have capsules enabled for the first time should preferably use +this option from the start to avoid transitioning later. + +### CONFIG_EDK2_CAPSULES_V2_TRANSITION + +This boolean option marks a release as transitional from initial capsule +implementation (v1) to a more advanced version (v2). Due to authentication +changes capsules can only be processed by an appropriate firmware (i.e., +v1-firmware and v1-capsule, v2-firmware and v2-capsule), which on its own makes +upgrading to a v2-firmware via capsules impossible. Enabling this option +requests [`capsule.sh` script](./edk2-capsule-updates.md#capsulesh-script) to +build v1-capsule for a v2-firmware thus permitting updates from v1-firmware. + +This option needs to be set only for a single public release, the first one that +gets `CONFIG_EDK2_CAPSULES_V2` set after using v1-capsules in previous releases. diff --git a/docs/kb/capsule-updates-overview.md b/docs/kb/capsule-updates-overview.md index 8bea2d0af1..08a4dffce7 100644 --- a/docs/kb/capsule-updates-overview.md +++ b/docs/kb/capsule-updates-overview.md @@ -33,8 +33,8 @@ on the user, resulting in higher probability of making a mistake. ### Embedded Flashing Code Firmware reads and writes system flash chip as part of its normal operation. -Capsule update mechanism reuses very same code to switch to a different firmware -image. +Capsule update mechanism reuses the very same code to switch to a different +firmware image. This way the means for firmware update are always there and require only minimal extra input to submit the capsule for an update. @@ -53,7 +53,7 @@ require use of several firmware update tools in the right order. The metadata can even take into account compatibility requirements between firmware of different components. For example, if you're trying to update a system firmware which requires EC version 1.2 but currently running EC firmware -is of version 1.1, the update will no happen, likely avoiding bricking the +is of version 1.1, the update will not happen, likely avoiding bricking the device. ### Convenience diff --git a/docs/kb/edk2-capsule-updates.md b/docs/kb/edk2-capsule-updates.md index bcbd661d11..01d3ba0f4e 100644 --- a/docs/kb/edk2-capsule-updates.md +++ b/docs/kb/edk2-capsule-updates.md @@ -294,7 +294,8 @@ of the output JSON file. The verification of capsules is performed via [public-key cryptography][wiki-pkc] (the concepts most relevant here: key pairs -and subkeys). This security mechanism uses a root key pair like this: +and subkeys). This security mechanism is meant to use a root key pair like +this: 1. Public key is embedded into the firmware at build time (one key is enough, but using multiple keys is also supported). @@ -302,7 +303,22 @@ and subkeys). This security mechanism uses a root key pair like this: 3. Signature embedded in the capsule is validated against the public key when an update is attempted to decide whether to perform the update. -Things to note: +The above describes a situation when `FmpDxe` is part of the firmware rather +than a capsule. The latter is more desirable in practice because it distributes +update code in the capsule, thus permitting changes to the update process which +were not anticipated at the time of the previous release. Because `FmpDxe` is +the entity responsible for capsule verification, moving it into the capsule +removes the security guarantee unless it's enforced by other means. +`SignedCapsulePkg` is one way of addressing this situation which it does by +having a two-part driver: a smaller part lives in the firmware and another one +goes into capsules. However, `SignedCapsulePkg` comes with a lot of baggage +and is hard to use when EDK is a payload for a multitude of different devices, +which is why [sealed capsules] were implemented as a much simpler alternative. +In short: an update capsule with `FmpDxe` is embedded as a payload of a capsule +with no drivers, firmware checks signature on the outer capsule's payload and +then processes the inner capsule in its place. + +More things to note: - public root key is well-known - private root key is stored in a safe place and nobody but the owner should @@ -328,6 +344,7 @@ versions will be compatible with one another (unless `LowestSupportedVersion` interferes). [wiki-pkc]: https://en.wikipedia.org/wiki/Public-key_cryptography +[sealed capsules]: https://github.com/tianocore/edk2/pull/12254 ## Generating signing keys with OpenSSL @@ -440,7 +457,7 @@ for these types of files in general, so don't read too much meaning into them. #### Prepare _root_ for EDK build system -EDK gets _root_ certificate(s) in a PCD. The PCD name differ and support one +EDK gets _root_ certificate(s) in a PCD. The PCD names differ and support one or many certificates, in this case it's `gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr` which expects one or more certificates in DER (binary) form combined via XDR (simple format where @@ -687,6 +704,18 @@ Output file name is generated based on coreboot options like - `emulation-qemu-q35-v0.2.0.cap` - `msi-ms7d25-ddr4-v1.1.9.cap` +### Sealed capsules + +When `CONFIG_EDK2_CAPSULES_V2` is set but `CONFIG_EDK2_CAPSULES_V2_TRANSITION` +isn't, `capsule.sh` produces a two-level capsule where the outer one is signed +by the keys specified by the parameters and the inner one is signed with EDK's +test keys. + +The inner capsule is signed because `FmpDxe` fails if there is no signature. +The test keys are used because it doesn't matter what the keys are as long as +the signature is valid and matches root key embedded into `FmpDxe` (not to be +confused with the key embedded into the firmware itself). + ### Generating test signing keys In order to test capsules signed with unsupported keys, one needs to generate a