MFCI UEFI Integration Guide¶
MfciPkg Provides¶
- a structure for encoding a manufacturer policy that is bound to a specific device and usage instance (they are 1-time use)
- a definition of the structure's digital signature format, authentication & authorization
- a test certificate and private key for development & testing
- a production Microsoft certificate and Enhanced Key Usage for authorizing Microsoft's cloud MFCI service
- a manufacturing-line-facing UEFI interface, based upon UEFI variables, that supports creation, installation, and removal of policies
- a UEFI-implementor-facing UEFI interface that reports the in-effect policy and notifications of policy changes
- a reference UEFI implementation that handles the authentication, target validation, and structure parsing, translating signed policy blobs into actionable 64-bit policies
- examples of policy change handlers for Secure Boot Clear and TPM Clear
- tests including data and scripts that simulate the manufacturer unlock process
UEFI Integration Overview¶
- Include MfciPkg and its dependencies in your platform
- Author code that sets the MFCI Per-Device Targeting Variable Names with the manufacturer, product, serial number, and optional OEM targeting values. These variables MUST be set prior the EndOfDxe event.
- Where applicable to your platform, leverage MFCI's PEI and/or DXE interfaces to synchronously query the in-effect MFCI policy, or register callbacks for notification of MFCI policy changes
Including MfciPkg and dependencies¶
FDF¶
Add the following to your EDK2 Flash Descriptor File (FDF)
INF MfciPkg/MfciDxe/MfciDxe.inf
INF MfciPkg/MfciPei/MfciPei.inf
DSC¶
Including Modules¶
MfciPkg provides a .dsc.inc
that can be !include
in your platform DSC.
An example follows:
!include MfciPkg/MfciPkg.dsc.inc
Additionally, an instance of MfciRetrievePolicyLib will need to be specified. The default instance of MfciRetrievePolicyLibNull must be overridden. Two other instances are available in the MfciPkg, or a custom version can be authored.
MfciRetrievePolicyLib|MfciPkg/Library/MfciRetrievePolicyLibViaHob/MfciRetrievePolicyLibViaHob.inf
MfciRetrievePolicyLib|MfciPkg/Library/MfciRetrievePolicyLibViaVariable/MfciRetrievePolicyLibViaVariable.inf
Including Pkcs Certificates¶
Mfci Policy Blobs need to be digitally signed for the system to consume their data.
The public portion of the Public/Private key needs to be included into for the MfciPkg to be able to verify
policy blobs. This is done through the PCDs PcdMfciPkcs7CertBufferXdr.
To help convert the Mfci Pkcs certificate into a PCD, the BinToPcd.py in MU_BASECORE can be used. Using BinToPcd.py will ensure that the public key is properly formatted into RFC 4506 External Data Representation Standard.
MU_BASECORE/BaseTools/Scripts/BinToPcd.py -i <PublicKey.cer> -o <Output.inc> -p gMfciPkgTokenSpaceGuid.PcdMfciPkcs7CertBufferXdr -x
Additionally, PcdMfciPkcs7RequiredLeafEKU needs to be filled out with the Extended Key Usage information. The leaf EKU is used as an additional check during policy blob validation. Failure to include the correct EKU leaf will result in the policy blob being rejected.
The below examples are from the Unit Test portion of this package. The Unit Test implementation can be followed to see how to convert a certificate into a binary pcd, and how to add the Extended Key Usage string into the PCD.
DEFINE MFCI_POLICY_EKU_TEST = "1.3.6.1.4.1.311.45.255.255"
# the unit test uses the test certificate that will also be used for testing end-to-end scenarios
!include MfciPkg/Private/Certs/CA-test.dsc.inc
gMfciPkgTokenSpaceGuid.PcdMfciPkcs7RequiredLeafEKU |$(MFCI_POLICY_EKU_TEST) # use the test version
When using !include MfciPkg/MfciPkg.dsc.inc
, please ensure the platform pcds for
PcdMfciPkcs7RequiredLeafEKU
and PcdMfciPkcs7RequiredLeafEKU
are included after the MfciPkg.dsc.inc
MfciPkg Dependencies¶
- Variable Policy
- Variable policy is used to protect MFCI's security data (UEFI variables) from malicious tampering
- MsCorePkg's MuVarPolicyFoundationDxe
- Variable policy phase notification support is required to secure some of the MFCI variables.
- EDK2's SecureBootVariableLib, specifically:
DeleteSecureBootVariables()
- EDK2's BaseCryptLib, specifically:
Pkcs7GetAttachedContent()
Pkcs7Verify()
VerifyEKUsInPkcs7Signature()
Populating Device Targeting Variables¶
An integrator must author code that sets the MFCI Per-Device Targeting Variable Names with the manufacturer, product, serial number, and optional OEM targeting values. These variables MUST be set prior the EndOfDxe event.
See the header file for type information on these variables, they must exactly match the contents of policies for targeting to successfully match them.
Take action based upon MFCI Policy & changes¶
The final piece of code integration is to enumerate the list of behaviors and actions to be supported, and activate their code by calling either MFCI's PEI and/or DXE interfaces to synchronously query the in-effect MFCI policy, or register callbacks for notification of MFCI policy changes.
State Machine¶
MfciPkg's public interface defines UEFI variable mailboxes for installing and removing policy blobs, see MFCI Per-Device Targeting Variable Names
A machine with no policy blob installed is deemed to have have a configuration policy value of 0x0 and is said to be running in the default customer mode, typically the most secure state with all security enabled.
There are 2 groups of mailboxes prefixed with Current...
and Next...
. The Current...
mailboxes represent the policy in effect for the current boot. The Next...
mailboxes are used for queuing
installation of a new policy.
Boot Timeline Example¶
- PEI
- PEI is considered too early in the boot root of trust to perform policy blob validation. A pre-validated, cached copy of configuration policy is available to PEI modules via the PEI interface. Policy will not change in the PEI phase, so a policy change notification is not part of the PEI interface. If a policy change occurs later in boot, the platform is guaranteed to reboot prior to the BDS phase.
- DXE prior to StartOfBds
- Drivers that need security policy augmentation should both get the current pre-verified policy and register for notification of policy changes
- OEM-supplied code populates UEFI variables that communicate the Make, Model, & SN targeting information to MFCI policy driver
- StartOfBds event
- The MFCI Policy Driver will...
- Check for the presence of a policy. If present...
- Verify its signature, delete the policy on failure
- Verify its structure, delete the policy on failure
- If the resulting policy is different from the current policy, notify registered handlers, make the new policy active, reboot
- If a next policy is not present, and a pre-verified policy was used for this boot, roll nonces, delete the pre-verified policy, & notify registered handlers
- Check for the presence of a policy. If present...
- The MFCI Policy Driver will...