Encrypts SMM Modules by AES-128 using key sealed in TPM2.0 device.
- SmmPackPkg (edk2)
- SmmPackSmm: Retrive TPM key and provides SmmPackProtocol for unpack
- SealKeyDxe: Seal key to TPM (PCR value can be read by using SmmPackSmm)
- TestSmm: Sample SMM module for testing (register own SMI handler and SMM protocol)
- SmmPackPacker (VS2019)
- smm-packer.cpp: Packs SMM module which can be unpacked by SmmPackSmm
- smm-packer-automated-addresss-shift-ghidra.cpp: Packs SMM module and shift address of protocol functions automatically (requires ghidra+efiseek)
- main.cpp: Copy the contents of one of the code above and compile to build a packer executable
- Setup edk2
- Copy
SmmPackPkgasedk2/SmmPackPkg - In
edk2/Conf/target.txt, edit below
ACTIVE_PLATFORMtoSmmPackPkg/SmmPackPkg.dscTARGET_ARCHtoX64TOOL_CHAIN_TAGtoGCC5
- Select which modules to build by editing
SmmPackPkg/SmmPackPkg.dsc build
- open SmmPackPacker.sln with Visual Studio 2019
- copy either smm-packer.cpp or smm-packer-automated-address-shift-ghidra.cpp to main.cpp
- make sure to rewrite the key with your key sealed in TPM
Ctrl-bto build
Note that after packing with smm-packer.cpp, if the packed SMM modules installs any protocol, the function address of protocol interface structure must be manually shifted. This process is included/automated in smm-packer-automated-address-shift-ghidra.cpp, but this requires ghidra+efiseek environment and changing of related path in the source code.
SmmPackPacker packs SMM modules by AES-128 before BIOS deployment. When executing packed modules, they decrypt themselves by using SmmPackProtocol's Unpack function which will be provided by SmmPackSmm. SmmPackSmm should be executed early in the DXE phase. You can add GUIDs of SmmPackSmm in the Apriori file. Most UEFI modules running at DXE and after are in PE format. SmmPackPacker will encrypt .text section of SMM module by AES-128 and adds Decrypt Stub (.ext section) to decrypt it. By passing DecryptAddr (.text section's base address) and DecryptSize (.text section's size) to SmmPackProtocol's Unpack function, it will decrypt the .text section using AES key stored in TPM2.0.
Key should be sealed into the TPM beforehand. Sealing is the TPM feature to restrict the access towards TPM data using PCR. By doing this, key cannot be read above OS or from other bootphases which avoids key to be theft. About further explanation of PCR, you can refer to my blog.
Above is the TPM command used to seal the key into TPM. Key is stored in the NV space of TPM (named NV Index) and restriction of read/write towards the key is actually the restriction towards this NV Index which the key is stored. You have to specify what PCRs are used and their digest value at PolicyPCR command. In this way, you can restrict the key (NV Index) to be only readable when PCR is in specific value.This Sealing can be done using SealKeyDxe, but you have to read your platform's PCR value using SmmPackSmm's TpmPcrRead() and set the digest of that value to SealKeyDxe's TpmPolicyPCR().



