This makes capsule PKCS#7 signatures reproducible.
openssl smime -sign embeds a signingTime signed attribute (current
UTCTime) by default. Because the attribute is inside the signed
digest, the resulting RSA signature differs on every invocation even
when the key and payload are identical, breaking reproducible builds
of signed FMP capsules.
Pass -noattr to drop all signed attributes from the SignerInfo. The
signature is then computed directly over the content, producing
byte-identical output across runs.
The FMP update path is unaffected: FmpAuthenticationLibPkcs7 calls
Pkcs7Verify() without extracting signed attributes, and rollback
protection uses FwVersion / LowestSupportedVersion in
FMP_PAYLOAD_HEADER plus the auth header MonotonicCount, not
signingTime. signingTime is only consumed by DxeImageVerificationLib
for Secure Boot dbt checks on PE/COFF images, which is a separate
code path.
Signed-off-by: Michał Kopeć <michal.kopec@3mdeb.com>
Modern AMD platforms cannot initialize graphics in 32bit mode (using
PEI GOP or VBIOS), because of UMA memory allocation above 4G by
default. One would have to force the recovery path so that UMA is
allocated below 4G. To allow running AMD x64 GOP, some modifications
are needed. Firstly, the GOP still needs VBIOS, so PCI IO must provide
it from FFS. Then, the GOP driver must also be included in the FFS, so
that DXE dispatcher picks it up and runs it.
TEST=Successfully initialize integrated graphics on MSI PRO B850-P WIFI.
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
coreboot always uses TSC for timestamps, force correct timer library
so measurements are accurate. A mismatch of timers will result in
incorrect tick and nanosecond calculations due to different timer
frequency.
Add a copy of BaseCpuTimerLib from UefiCpuPkg and replace TSC frequency
calculation with the value obtained from coreboot timestamp table.
On Intel systems where the UefiCpuPkg/CpuTimerLib is used, there is no
mismatch. However, AMD systems do not have the required CPUID, so the
default timer is HPET, not TSC.
TEST=Boot Gigabyte MZ33-AR1 and use systemd-analyze. The firmware boot
time is no longer 19 minutes, but indicates correct time spent in
firmware.
Upstream-Status: Pending
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
AMD silicon has different definitions for SLP_Sx states written
to the ACPI PM register than Intel.
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
The timer/counter start and end value were hardcoded instead of being
read from the performance protocol.
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Upstream-Status: Pending
coreboot always uses TSC for timestamps, force correct timer library
so measurements are accurate. A mismatch of timers will result in
incorrect tick and nanosecond calculations due to different timer
frequency.
Add a copy of BaseCpuTimerLib from UefiCpuPkg and replace TSC frequency
calculation with the value obtained from coreboot timestamp table.
On Intel systems where the UefiCpuPkg/CpuTimerLib is used, there is no
mismatch. However, AMD systems do not have the required CPUID, so the
default timer is HPET, not TSC.
TEST=Boot Gigabyte MZ33-AR1 and use systemd-analyze. The firmware boot
time is no longer 19 minutes, but indicates correct time spent in
firmware.
Upstream-Status: Pending
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Do not clear testd attribute from above 4G RAM memory. It caused the
payload to mark above 4G ranges as reserved. As a result, Linux kernel
had only as much memory, as there is available memory below 4G reported
by coreboot. It caused out of memory processes kills in Linux.
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Upstream-Status: Pending
FWTS complains on MMCONF not being reseved in memory map. So reserve
it.
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Upstream-Status: Pending
There was a dirty hack for Intel platforms that read TOLUD register
to determine the boundary between MMIO and DRAM. It caused problems
on AMD platforms such as apu2, which does not have TOLUD register. As
a result, regions which held reserved memory were incorrectly
reported as RAM buffers or RAM itself and the OS allocated DMA there.
It could be observed with many IO_PAGE_FAULTs occurring in the OS.
See: Dasharo/dasharo-issues#1134
FWTS complains on ECAM MMCONF not being reserved in the memory map.
So carve it out of the memory map and report it as reserved.
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Upstream-Status: Pending
Mark the range 0x1000-0xa0000 as tested. It caused the payload to mark
this range as reserved. As a result, Linux kernel could not allocate
memory for real mode and panicked.
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Upstream-Status: Pending
On AMD server systems there are multiple PCI root bridges. The root
bridge scanning in UEFI Payload is not sufficient to detect the memory
and I/O apertures properly. For example, on Turin system, the I/O
aperture on the first root bridge containing the FCH may not have any
I/O resources detected on the PCI devices. This results in the I/O
decoding to be disabled on the root bridge, effectively breaking the
I/O-based serial ports, e.g. on Super I/Os and BMCs.
Populate the root bridge info from CB_TAG_RB_INFO which contains data
compatible with the Universal Payload PCI Root Bridges Info HOB. Make
the PciHostBridgeLib pick the HOB up, if available, and populate
proper root bridge apertures for AMD systems. Otherwise, fall back
to root bridge scanning.
Relevant coreboot patches:
https://review.coreboot.org/c/coreboot/+/89486https://review.coreboot.org/c/coreboot/+/89487
TEST=Boot UEFI Payload and see the serial console no longer breaks
after PCI enumeration in UEFI Payload on Gigabyte MZ33-AR1.
Upstream-Status: Pending
Signed-off-by: Michał Żygowski <michal.zygowski@3mdeb.com>
Optionally transforming a capsule via the protocol permits tweaking
capsule format and/or adding additional layers of verification without
embedding any specific details into DxeCapsuleLibFmp. The protocol must
be part of the running firmware so drivers embedded into capsules can't
affect processing of other capsules in this way.
A failure to transform a capsule results in it being skipped. A
successful transformation leads to its re-validation before further
processing.
Signed-off-by: Gustavo dos Santos Cardoso <gustavo_16a@hotmail.com>
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
This DXE driver implements CAPSULE_TRANSFORMATION_PROTOCOL to unseal
outer FMP capsule and extract the fully authenticated inner FMP capsule.
A sealed capsule is an FMP capsule that acts as a container for the real
FMP capsule. The two-level structure is meant to reuse as much as
possible of the existing functionality but address the fact that FMP
signs each payload individually instead of a capsule as a whole.
Signing a capsule in its entirety avoids the need to use a separate
mechanism to authenticate embedded drivers as well as prevents repacking
the capsule to modify its unsigned parts in any way.
Signed-off-by: Gustavo dos Santos Cardoso <gustavo_16a@hotmail.com>
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
It is essentially a hook into capsule processing mechanism that can be
used to additionally validate a capsule or pre-process it and return a
different capsule to be processed in its place.
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
This is a trivial library which allows its clients to get to the data
portion of an FMP payload.
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
This DXE can be used to validate firmware update key in cases when
FmpDxe is not part of the firmware.
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Detects if PcdFmpDevicePkcs7CertBufferXdr contains a test key. Having
it as a library allows to use the check outside of FmpDxe while avoiding
duplication.
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Improve the Capsule Update flow, so that if the
`CONFIG_EDK2_GRAPHICAL_CAPSULE_PROGRESS` is set but no monitor is
detected, the update doesn't fail but rather falls back to serial
mode.
Signed-off-by: Filip Lewinski <filip.lewinski@3mdeb.com>
Update the progress bar upon each block being read, not only after
reading the whole flash - and likewise for writing.
This improves the UX in the sense that the progress bar starts moving
at a steady pace right away, so that the update doesn't seem stuck.
Scale per-block write weight by (BlockCount / DifferingBlocks) instead
of shrinking TotalUnits; this keeps the denominator stable so progress
advances smoothly rather than jumping when only a fraction of blocks
differ.
The smooth progress bar feature is gated by a PCD that can
be passed by coreboot. It's autoenabled if CAPSULES_V2 is set.
Signed-off-by: Filip Lewinski <filip.lewinski@3mdeb.com>
MRC cache was being cleared on every capsule update, forcing a full
memory retraining cycle on the next boot. This is unnecessary because
the cache is versioned by FSP and will be invalidated automatically if
the FSP binary changes in the new firmware.
Migrate the {RECOVERY/RW}_MRC_CACHE FMAP regions the same way ROMHOLE,
BOOTSPLASH and SI_GBE are already handled. The region is not
offset-sensitive and its absence in either image is non-fatal.
Signed-off-by: Filip Lewinski <filip.lewinski@3mdeb.com>
Before returning with an error attempt to write original state of the
flash back, trying to recover as many blocks as possible:
- do up to three erase&write attempts of each writable block that
differs from its original state
- do not stop on errors, not all blocks are equally important for
normal firmware operation and doing a partial recovery may be good
enough
Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>