Verify feature using test signing keys
Brief summary
Validate the CAPSULE_ENABLE feature using test signing keys before using product-specific signing keys.
Additional context
This task consists of testing whether:
- FMP capsules signed as described in https://github.com/Dasharo/dasharo-issues/issues/803 with develop keys can be used,
- FMP capsules signed with any other key are discarded.
Tests should be performed on one of available MSI boards (full release testing on all variants will be performed later, in https://github.com/Dasharo/dasharo-issues/milestone/36).
Tested firmware consisting of https://github.com/Dasharo/coreboot/pull/509 and https://github.com/Dasharo/edk2/pull/147 on MSI PRO Z690-A DDR4 board.
Two good capsules (signed by EDK2 test keys) with different version numbers were prepared as described in the documentation. Both capsules were used to update the board successfully. It was verified by looking at BIOS Version field printed by smbios -t 0 command of UEFI Shell after applying each of them.
One bad capsule (signed by custom keys) was prepared in the following way. Creation of keys:
mkdir custom-keys
cd custom-keys
# make root certificate
openssl genrsa -aes256 -out root.p8e 2048
openssl req -new -x509 -days 3650 -key root.p8e -out root.crt
openssl x509 -in root.crt -outform PEM -out root.pub.pem
# create CA using the root certificate ("demoCA" comes from /etc/ssl/openssl.cnf)
mkdir -p demoCA/newcerts
touch demoCA/index.txt
echo 01 > demoCA/serial
# sub key
openssl genrsa -aes256 -out sub.p8e 2048
openssl req -new -key sub.p8e -out sub.csr
openssl ca -extensions v3_ca -in sub.csr -days 3650 -out sub.crt -cert root.crt -keyfile root.p8e
openssl x509 -in sub.crt -outform PEM -out sub.pub.pem
# signing key
openssl genrsa -aes256 -out sign.p8e 2048
openssl req -new -key sign.p8e -out sign.csr
openssl ca -in sign.csr -days 3650 -out sign.crt -cert sub.crt -keyfile sub.p8e
openssl pkcs12 -export -out sign.pfx -inkey sign.p8e -in sign.crt
openssl pkcs12 -in sign.pfx -nodes -out sign.p12
JSON file for GenerateCapsule using custom keys (paths relative to EDK2 payload worktree):
{
"EmbeddedDrivers": [
{
"Driver": "../Build/DasharoPayloadPkgX64/RELEASE_COREBOOT/X64/FmpDxe.efi"
}
],
"Payloads": [
{
"Payload": "../../../../../build/coreboot.rom",
"Guid": "00112233-4455-6677-8899-AABBCCDDEEFF",
"FwVersion": "0x00020000",
"LowestSupportedVersion": "0x00000000",
"OpenSslSignerPrivateCertFile": "custom-keys/sign.p12",
"OpenSslOtherPublicCertFile": "custom-keys/sub.pub.pem",
"OpenSslTrustedPublicCertFile": "custom-keys/root.pub.pem"
}
]
}
Making a capsule:
BaseTools/BinWrappers/PosixLike/GenerateCapsule \
--encode \
--capflag PersistAcrossReset \
--capflag InitiateReset \
--json-file custom.json \
--output ms7d25-dd4-badkeys.cap
Trying to update the firmware with CapsuleApp.efi ms7d25-dd4-badkeys.cap results in a reboot for an update, start and immediate termination of the update followed by another reboot. At this point CapsuleApp.efi -S printed the following result of an attempted update:
CapsuleMax - CapsuleFFFF
CapsuleLast - Capsule0000
CapsuleName: Capsule0000
Capsule Guid: 6DCBD5ED-E82D-4C44-BDA1-7194199AD92A
Capsule ProcessedTime: 08/11/2024 21:34
Capsule Status: Security Violation
Capsule FMP Version: 0x1
Capsule FMP PayloadIndex: 0x0
Capsule FMP UpdateImageIndex: 0x1
Capsule FMP UpdateImageTypeId: 00112233-4455-6677-8899-AABBCCDDEEFF
Capsule FMP CapsuleFileName: ""
Capsule FMP CapsuleTarget: ""
Security Violation is the error code in this case.
https://github.com/Dasharo/coreboot/pull/509 now includes capsule.sh script. It can non-interactively create keys with ./capsule.sh keygen {keys-dir-name} making the process much smoother. Soon it will be updated with integration of the new key into EDK which will allow a more advanced test capable of catching more cases:
- Build firmware using set of keys A (test keys used by default will do) and generate an update capsule using this build.
- Integrate a different set of keys (set B) into EDK and rebuild the firmware.
- Try running and updating the firmware from step 2 with the capsule from step 1. The update attempt must fail with security violation status.
@SergiiDmytruk
I'm having problems generating keys with caspule.sh
janprusinowski in ~/Desktop/Coreboot/coreboot on uefi-capsules ● ● λ ./capsule.sh keygen keys
OK to remove 'keys'? [y/N] y
========== MAKING ROOT CERTIFICATE ==========
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
34:2b:47:9d:c4:55:3e:2d:41:85:49:74:00:0c:7a:6a:00:0e:a6:91
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=XX, ST=Province, O=Org, CN=root
Validity
Not Before: Aug 30 10:24:55 2024 GMT
Not After : Aug 28 10:24:55 2034 GMT
Subject: C=XX, ST=Province, O=Org, CN=root
X509v3 extensions:
X509v3 Subject Key Identifier:
13:7A:1A:D9:E6:33:C6:C4:0B:7C:AF:76:98:1E:1D:F0:90:48:FA:6C
X509v3 Authority Key Identifier:
13:7A:1A:D9:E6:33:C6:C4:0B:7C:AF:76:98:1E:1D:F0:90:48:FA:6C
X509v3 Basic Constraints: critical
CA:TRUE
/home/janprusinowski/Desktop/Coreboot/coreboot/payloads/external/edk2/workspace/Dasharo/BaseTools/Scripts/BinToPcd.py:41: SyntaxWarning: invalid escape sequence '\_'
if re.split ('[a-zA-Z\_][a-zA-Z0-9\_]*\.[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']:
/home/janprusinowski/Desktop/Coreboot/coreboot/payloads/external/edk2/workspace/Dasharo/BaseTools/Scripts/BinToPcd.py:47: SyntaxWarning: invalid escape sequence '\_'
if re.split ('[a-zA-Z\_][a-zA-Z0-9\_]*', Argument) != ['', '']:
/home/janprusinowski/Desktop/Coreboot/coreboot/payloads/external/edk2/workspace/Dasharo/BaseTools/Scripts/BinToPcd.py:16: DeprecationWarning: 'xdrlib' is deprecated and slated for removal in Python 3.13
import xdrlib
========== MAKING SUBROOT CERTIFICATE ==========
Using configuration from /etc/pki/tls/openssl.cnf
ca: /etc/pki/CA/newcerts is not a directory
/etc/pki/CA/newcerts: No such file or directory
@JanPrusinowski If you were following the documentation and created the index.txt and serial in demoCA directory somewhere in your workspace then you need to either change the CA directory to your demoCA directory or move all it's contents into /etc/pki/CA, including the newcerts, for example:
sudo mkdir -p /etc/pki/CA
sudo chown -R $USER:$USER /etc/pki/CA
cp -r demoCA/* /etc/pki/CA/
Then everything should work fine. At least it does in my case.
I have prepared tests for: TC1: Update DUT with a capsule and check if the update was sucessfull by checking if BIOS Version has changed. TC2: Try to update DUT with capsule with invalid keys. Verify if the DUT reboots twice. Verify that the BIOS Version wasn't changed. TC3: Try to update DUT with invalid GUID. Same as TC2 but with wrong GUID and valid keys. Also run them both on Qemu and MSI More details can be found at: https://github.com/Dasharo/open-source-firmware-validation/pull/457
To run tests on qemu prepare a valid capsule file and then use this capsule file to generate invalid capsules required in tests by running the script:
./scripts/capsules/capsule_update_tests.sh dasharo.cap
then start the tests:
robot -v snipeit:no -L TRACE -v rte_ip:127.0.0.1 -v config:qemu -v capsule_fw_file:dasharo.cap dasharo-stability/capsule-update.robot
To start tests on MSI before preparing the capsule please edit FW to enable Console Serial Redirection. Use the guide: https://github.com/Dasharo/open-source-firmware-validation/blob/develop/docs/troubleshooting.md without it a successful flash of DUT will prevent tests from working correctly. Before starting the test run the capsule prepare script (same as on qemu).
robot -v snipeit:no -L TRACE -v rte_ip:192.168.10.188 -v config:msi-pro-z690-a-ddr5 -v sonoff_ip:192.168.10.69 -v pikvm_ip:192.168.10.45 -v device_ip:192.168.10.39 -v fw_file:./msi_ms7d25_v1.1.2_ddr5.rom -v capsule_fw_file:./msi_ms7d25_v1.1.3_ddr5.cap dasharo-stability/capsule-update.robot
Tests on MSI fail for now as FW doesn't support capsule update yet. @SergiiDmytruk @krystian-hebel I could test if it works if I would get a modified FW for MSI - however on qemu everything works as it should and tests itself start on MSI so everything should work when the modified FW will be available.
Tests that were added: TC1: Update DUT with a capsule and check if the update was sucessfull by checking if BIOS Version has changed. TC2: Try to update DUT with capsule with invalid keys. Verify if the DUT reboots twice. Verify that the BIOS Version wasn't changed. TC3: Try to update DUT with invalid GUID. Same as TC2 but with wrong GUID and valid keys.
Test that cant be added untill we will have at least few releases: TC4: Try to update DUT with invalid fw version. This test might not work as @krystian-hebel stated that we might need at least 3 releases to be able to check if it works.
PR availible: https://github.com/Dasharo/open-source-firmware-validation/pull/457
MSI tests were conducted on: MSI tests were conducted on: MSI PRO Z690-A DDR5 Logs can be found in my previous comment
I have updated tests and the script generating capsules required by tests. Tests now work on MSI. log-msi-pass.zip
First somewhat successful test. The FS on which Ubuntu is installed showed in Uefi Shell is not consistent and it may need to be somehow dynamically determined or found. Locally I added a loop iterating over all the FS's.
- CUP001.001 Failed because
Capsule StatuswasSecurity Violationand notNot Ready. - CUP002.001 Passed
- CUP050.001 Failed because
No match found for 'to boot directly' in 3 minutes, the platform booted into Ubuntu beforeto boot directlywas found. Serial redirection was turned off. Maybe I have did something wrong when setting it in the FW using dcu. I will set it in the binary again and run the tests another time.
Yesterday new binaries were tested with success on:
-
MSI PRO Z790-P WIFI DDR5 (RPL 13th) Logs and binaries: msi-ms7e06-v.9.zip
-
MSI PRO Z690-A DDR4 Logs and binaries: ddr4.zip
-
MSI PRO Z690-A DDR4 Logs and binaries: ddr5.zip
There was a change due to doping 'InitiateReset' flag in building capsules. DUT does not reboot automatically after performing update. FUM is now initiated each time after performing the Capsule Update. We had to rebuild binaries and modify tests as the testing criteria had changed.
- CUP001.001 - Capsule Status check was edited to check for Security Violation.
- CUP050 renamed to CUP999 - Time for FW update and reboot was increased to 5 min as 3 min was not enough on some platforms.