Capsule Based System Firmware Update Verify Generated Keys - jljusten/tianocore GitHub Wiki

Back to Capsule Based System Firmware Update

The following steps can be used to verify that the capsule-based system firmware update feature has been integrated into a platform correctly. These steps use generated keys for a specific platform. One key generation method is described here.

The steps provided in this section are focused on verifying the use of generated keys. A more complete set of verification steps for the test signing key are provided here. These steps use the CapsuleApp.efi utility to display and verify fields in the FMP, ESRT, and Capsule structures.

NOTE: Each step in this sequence depends on all the previous steps. If any step in this sequence does not match expectations, then debug and resolve the integration issue before proceeding to the next step.

Add Generated Private Keys to tools_def.txt

  • Update Conf/tools_def.txt to use generated private keys. The bottom of tools_def.txt has a section labeled Pkcs7Sign tool definitions. The default settings for this section does not include a *_*_*_PKCS7SIGN_FLAGS statement. This means the test signing keys are used by default. In order for the build to sign system firmware update capsules using generated private keys, the --signer-private-cert, --other-public-cert, and --trusted-public-cert flags must be provided.
    The example below adds these three flags and uses the environment variables called KEYS_PATH and KEYS_BASE_NAME to specify the path and base name of generated private keys. This follows the key file naming used here.
##################
# Pkcs7Sign tool definitions
##################
*_*_*_PKCS7SIGN_PATH       = Pkcs7Sign
*_*_*_PKCS7SIGN_GUID       = 4AAFD29D-68DF-49EE-8AA9-347D375665A7
*_*_*_PKCS7SIGN_FLAGS      = --signer-private-cert ENV(KEYS_PATH)\ENV(KEYS_BASE_NAME)Cert.pem --other-public-cert ENV(KEYS_PATH)\ENV(KEYS_BASE_NAME)Sub.pub.pem --trusted-public-cert ENV(KEYS_PATH)\ENV(KEYS_BASE_NAME)Root.pub.pem

NOTE: This is one of many possible methods to sign images. This example is a simple method that helps verify that the test keys can be replaced with generated keys. Each product owner must decide on the signing method and signing tools that provide proper protection of their private keys.

Add Generated Public Key to Platform DSC

  • Update Platform DSC file to set the PCD gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer to the generated public key. The example below adds the generated public key to the [PcdsDynamicExVpd] section. <MaxSize> must be set to a value that is at least as big as the number of bytes in the generated <public key>. <public key> is the list of bytes from the binary .cer file that is described here. A hex dump utility may be used to convert the binary file to the list of hex values. The example below shows the PCD setting for the test signing public key from the file BaseTools\Source\Python\Pkcs7Sign\TestRoot.cer
[PcdsDynamicExVpd]
!if $(CAPSULE_ENABLE)
  #
  # Custom public signing key PCD statement
  #
  # gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|*|<MaxSize>|{<public key>}
  #
  gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|*|756|{0x30, 0x82, 0x02, 0xf0, 0x30, 0x82, 0x01, 0xdc, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x34, 0x30, 0x27, 0x7f, 0x05, 0x3d, 0x95, 0x85, 0x43, 0xa0, 0xa4, 0xf5, 0x0c, 0x9a, 0xe7, 0xca, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x08, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30, 0x38, 0x30, 0x34, 0x31, 0x35, 0x30, 0x31, 0x34, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x08, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x94, 0xe6, 0x33, 0x4f, 0x56, 0xc3, 0x07, 0xa0, 0xd0, 0x99, 0x57, 0xc3, 0xe1, 0x56, 0x42, 0x01, 0x70, 0x59, 0x1c, 0x2f, 0x4a, 0x66, 0x8f, 0x34, 0x9e, 0x93, 0xbd, 0xb6, 0xec, 0x92, 0xa4, 0x90, 0x51, 0x5d, 0xc6, 0x8f, 0xb5, 0xc3, 0x86, 0x15, 0xdf, 0x60, 0x80, 0xbe, 0xb8, 0x78, 0x59, 0x5b, 0x9b, 0xfd, 0x27, 0x92, 0x69, 0xcc, 0xca, 0x8e, 0x3e, 0x9e, 0x81, 0x47, 0x5b, 0x84, 0xef, 0x5c, 0x9b, 0xb3, 0x4a, 0x43, 0x5b, 0x8d, 0x0b, 0x31, 0x04, 0x00, 0xb6, 0x8a, 0xc0, 0xa9, 0xf5, 0x21, 0xd0, 0x3f, 0xcd, 0xb0, 0x67, 0x7d, 0x50, 0x33, 0x2e, 0xfb, 0x1b, 0x2c, 0x16, 0x2e, 0xee, 0x56, 0x01, 0x87, 0xf6, 0xc8, 0xd4, 0x53, 0x07, 0x67, 0x99, 0x0b, 0x46, 0xbf, 0x1d, 0x90, 0xc6, 0xdb, 0x7f, 0x6d, 0x62, 0x0c, 0x4a, 0xac, 0xa8, 0xa2, 0x3c, 0x79, 0x0f, 0xad, 0x8f, 0xfe, 0xc1, 0xe8, 0xe5, 0x27, 0x3d, 0xf9, 0xa6, 0x9a, 0x1d, 0xec, 0x9a, 0x5f, 0x62, 0x51, 0x2e, 0x98, 0x1d, 0x29, 0xba, 0x6b, 0x8a, 0xfb, 0x43, 0x0e, 0x68, 0x29, 0xf5, 0xbe, 0x67, 0x48, 0x44, 0x28, 0x45, 0xfe, 0x1d, 0x3b, 0x50, 0x72, 0x6a, 0xc0, 0xbb, 0x0c, 0x9f, 0x02, 0x61, 0xad, 0x63, 0xa7, 0x87, 0xf6, 0x32, 0x9f, 0x3e, 0x16, 0x5c, 0xee, 0xcc, 0x05, 0xbd, 0x17, 0xe8, 0x46, 0x52, 0xaf, 0x50, 0x8a, 0xa6, 0x7e, 0x16, 0x69, 0x83, 0x69, 0x5b, 0x6e, 0x4d, 0xc7, 0xcf, 0x80, 0xb8, 0xcd, 0xf6, 0x66, 0x3f, 0xbe, 0x6c, 0xa0, 0xe8, 0x9c, 0x26, 0x60, 0xba, 0xa9, 0x05, 0xdd, 0x71, 0x4a, 0xbd, 0x00, 0xa8, 0x0c, 0xf7, 0x50, 0xab, 0x44, 0xd6, 0x3e, 0x87, 0x21, 0x3c, 0x2d, 0xe6, 0x33, 0x27, 0x5e, 0x21, 0x27, 0xb9, 0xdc, 0x38, 0x48, 0xd6, 0x3a, 0x96, 0xe1, 0x17, 0x47, 0x65, 0x65, 0xce, 0x3d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x48, 0x30, 0x46, 0x30, 0x44, 0x06, 0x03, 0x55, 0x1d, 0x01, 0x04, 0x3d, 0x30, 0x3b, 0x80, 0x10, 0xce, 0xb5, 0x7a, 0xcf, 0xe5, 0x21, 0xc7, 0x6b, 0xf3, 0xec, 0x92, 0xd4, 0xbf, 0x65, 0x2a, 0x35, 0xa1, 0x15, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x08, 0x54, 0x65, 0x73, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x82, 0x10, 0x34, 0x30, 0x27, 0x7f, 0x05, 0x3d, 0x95, 0x85, 0x43, 0xa0, 0xa4, 0xf5, 0x0c, 0x9a, 0xe7, 0xca, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1d, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x6b, 0x0d, 0xe0, 0x0a, 0xd0, 0xee, 0x5b, 0x3f, 0xb6, 0x73, 0x48, 0x62, 0xe8, 0xf4, 0x5b, 0xe1, 0xed, 0xd9, 0x00, 0xc5, 0xe5, 0x0e, 0x68, 0xfb, 0x53, 0x33, 0x30, 0x6a, 0x60, 0xba, 0xee, 0x38, 0x5b, 0x51, 0x63, 0x70, 0xd5, 0x7e, 0x05, 0xfe, 0xe4, 0x45, 0x2a, 0x15, 0x62, 0x1b, 0xfc, 0xd8, 0x75, 0x93, 0x56, 0xf6, 0xe6, 0x06, 0x85, 0x21, 0xf7, 0x08, 0x47, 0x26, 0xb9, 0xfe, 0x05, 0x4e, 0x90, 0x22, 0x54, 0xf4, 0x39, 0x09, 0x4c, 0x5c, 0x8e, 0xcd, 0x7c, 0x3b, 0xaf, 0x4b, 0x2d, 0x18, 0x06, 0xf4, 0x5c, 0x24, 0x2a, 0x64, 0xf7, 0x59, 0x75, 0x28, 0x97, 0xa9, 0x90, 0x2c, 0xba, 0x46, 0x02, 0x6a, 0x64, 0x66, 0x49, 0x32, 0xcb, 0x5d, 0x34, 0xfe, 0x24, 0xe4, 0x44, 0xb0, 0xc2, 0xad, 0x17, 0x1b, 0x05, 0x7d, 0xd3, 0x58, 0x88, 0x2e, 0xbe, 0x0e, 0xd7, 0x2b, 0xca, 0x5c, 0xbf, 0x28, 0x25, 0x3d, 0xd8, 0xbb, 0x3c, 0x38, 0x52, 0xe6, 0x27, 0xfa, 0xd2, 0xb8, 0x45, 0x6b, 0x5f, 0x7f, 0x4b, 0xb0, 0x23, 0x05, 0xe8, 0xaf, 0x67, 0xe8, 0xe2, 0x6c, 0x2f, 0x9f, 0xf8, 0x73, 0x7f, 0xc3, 0x17, 0xbc, 0xb2, 0x6a, 0x5b, 0x2a, 0xf3, 0x6b, 0xd3, 0xdc, 0x7f, 0xdf, 0x2f, 0xd0, 0xab, 0x06, 0x0c, 0xfe, 0x03, 0xe7, 0x8d, 0x82, 0xec, 0x84, 0x3d, 0xc8, 0x7d, 0xed, 0xcb, 0x6a, 0x5b, 0x35, 0x48, 0x55, 0x07, 0xfb, 0xaa, 0x78, 0x1a, 0x01, 0xbb, 0x98, 0x45, 0x8b, 0xda, 0x8a, 0xe3, 0x21, 0x57, 0x86, 0x15, 0x23, 0x17, 0x50, 0x1b, 0x9c, 0xbc, 0x1a, 0x59, 0xa8, 0x2a, 0xad, 0x3a, 0x7e, 0x01, 0x24, 0x83, 0xf7, 0xb0, 0x61, 0xe6, 0xbd, 0x4f, 0xd9, 0x91, 0x90, 0xa7, 0x2a, 0xb9, 0x0c, 0x3b, 0xab, 0x95, 0x20, 0x1c, 0xf0, 0x74, 0xce, 0x02, 0xba, 0x14, 0x5d, 0xf1, 0x91, 0x25, 0x4a}
!endif
  • A helper tool in BaseTools/Scripts/BinToPcd.py is availble to simplify setting large PCDs such as gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer. This helper tool can be used to convert a binary file to the list of hex values.
BinToPcd.py -i BaseTools\Source\Python\Pkcs7Sign\TestRoot.cer

BinToPcd.py also supports the generation of an entire PCD statement. The following example generates a PCD statement for a VPD section and sets the size of the PCD to the size of the test signing public key input file BaseTools\Source\Python\Pkcs7Sign\TestRoot.cer

BinToPcd.py -p gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer -t VPD -i BaseTools\Source\Python\Pkcs7Sign\TestRoot.cer

BinToPcd.py also supports the generation of an output file that can be included from a platform DSC file using a !include statement. This allows a pubic key value to be updated without updating to the platform DSC file. Instead, the BinToPcd.py helper tool is run with a new public key input file. The example below shows the generation of the output file MyPublicKey.inc.

BinToPcd.py -p gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer -t VPD -i BaseTools\Source\Python\Pkcs7Sign\TestRoot.cer -o MyPublicKey.inc

The following is the update to a platform DSC file to include the PCD statement generated by the BinToPcd.py helper tool above. This example assumes MyPublicKey.inc is in the same directory as the platform DSC file.

[PcdsDynamicExVpd]
!if $(CAPSULE_ENABLE)
  #
  # Custom public signing key from include file
  #
  # gEfiSecurityPkgTokenSpaceGuid.PcdPkcs7CertBuffer|*|<MaxSize>|{<public key>}
  #
  !include MyPublicKey.inc
!endif

Build and Boot Firmware Image

  • If the tools_def.txt configuration sown above is used, then set the KEYS_PATH and KEYS_BASE_NAME environment variables to the path and base name of generated private keys. The following example sets the environment variables for generated keys in a Keys directory in thew QuarkPlaytformPkg and a base name for the key set to GalileoGen2.
set KEYS_PATH=%WORKSPACE%\edk2\QuarkPlatformPkg\Keys
set KEYS_BASE_NAME=GalileoGen2

These environment variable settings use the following generated private key files

QuarkPlatformPkg/Keys/GalileoGen2Root.pub.pem
QuarkPlatformPkg/Keys/GalileoGen2Sub.pub.pem
QuarkPlatformPkg/Keys/GelileiGen2Cert.pem
  • Build firmware image setting the -D CAPSULE_ENABLE flag.

build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/Quark.dsc -D CAPSULE_ENABLE

  • Update target with new firmware image

  • Boot target to Boot Manager. The front page should not show a WARNING: Test key detected. message. If logging is enabled, then this same message should not be present in the log. If this message is still displayed, then the firmware is still using the public test signing key.

Build System Firmware Update Capsule

  • Update System Firmware Descriptor PEIM .aslc file to a higher version by updating the CURRENT_FIRMWARE_VERSION and CURRENT_FIRMWARE_VERSION_STRING defines. This file is described here

  • Build firmware image again setting the -D CAPSULE_ENABLE flag

build -a IA32 -t VS2015x86 -p QuarkPlatformPkg/Quark.dsc -D CAPSULE_ENABLE

Verify System Firmware Update Capsule

  • Copy System Firmware Update Capsule Image with higher version to a USB drive

  • Run CapsuleApp.efi <CapsuleImage> to load and process the system firmware update capsule.

  • If logging is enabled, then view the boot log to verify capsule processing.

  • Run CapsuleApp.efi -P to view the Firmware Management Protocol details and verify that the version information matches the version of the capsule that was processed.

Back to Capsule Based System Firmware Update

⚠️ **GitHub.com Fallback** ⚠️