Compare commits

...

62 Commits

Author SHA1 Message Date
71606314f8 CryptoPkg: Fix wrong logic in X509GetTBSCert
REF:
https://bugzilla.tianocore.org/show_bug.cgi?id=4509

Both return 0x80 value and
Asn1Tag != V_ASN1_SEQUENCE are wrong return.

Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
2024-06-06 14:49:44 +00:00
90cb1ec332 OvmfPkg/PlatformInitLib: allow PhysBits larger than 48
If GuestPhysBits reports more than 48 phys-bits can be used allow
to go beyond that limit.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2024-06-06 09:06:28 +00:00
603ad2d6ae OvmfPkg/PlatformInitLib: add support for GuestPhysBits
Add support for GuestPhysBits (cpuid 0x80000008, eax, bits 23:16).

GuestPhysBits is a field which can be set by the hypervisor to inform
the guest about the /usable/ physical address space bits.  This can be
smaller than the PhysBits of the CPU, for example because of nested
paging limitations.

OVMF will read GuestPhysBits, log the value, in case it is set use it
as upper limit.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2024-06-06 09:06:28 +00:00
65b0d08786 MdeModulePkg/HiiDatabaseDxe: Remove assert for VarStoreId = 0
It is legal for the VarStoreId of a question to
be 0 per the UEFI spec:
"Specifies the identifier of a previously
declared variable store to use when storing the
question’s value. A value of zero indicates
no associated variable store."

Instead of hitting an assert just skip this
question as there is no value to return.

Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
2024-06-06 05:41:00 +00:00
b45aff0dc9 OvmfPkg: add morlock support
Add dsc + fdf include files to add the MorLock drivers to the build.
Add the include files to OVMF build configurations.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2024-06-06 02:12:52 +00:00
10ab1c67c4 ArmVirtPkg: Remove the NorFlashQemuLib
The FdtNorFlashQemuLib has been enabled, remove ArmVirtPkg version.

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4770

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Chao Li <lichao@loongson.cn>
2024-06-05 21:50:38 +00:00
10cd8b45ce MdePkg: Remove non-ASCII characters from header file
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4775

Signed-off-by: Neo Hsueh <Hong-Chih.Hsueh@amd.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Jiangang He <jiangang.he@amd.com>
2024-06-05 12:22:53 +00:00
e2e09d8512 MdePkg: Add Ipmi Net Sensor Thresholds command defines.
Adding definitions for Ipmi Net Sensor Get/Set Thresholds commands and
structures as found in Ipmi specification v2.0

Signed-off-by: Aaron Pop <aaronpop@microsoft.com>
2024-06-05 03:35:32 +00:00
7772e339bd ArmVirtPkg: Enable the non-hardcode version FdtNorFlashQemuLib
Enable the non-hardcode version of FdtNorFlashQemuLib in ArmVirtQemu.dsc
and ArmVirtQemuKernel.dsc, and it can work rightly after enabling it.

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4770

Build-tested (with "ArmVirtQemu.dsc" and "ArmVirtQemuKernel.dsc").

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Chao Li <lichao@loongson.cn>
Co-authored-by: Xianglai Li <lixianglai@loongson.cn>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
2024-06-04 22:51:09 +00:00
cac1ea6c2a OvmfPkg: Add no hardcode version of FdtNorFlashQemuLib
This library is copied from ArmVirtPkg, in the Arm version, the value of
PcdFlashNvStorageVariableBase, PcdFlashNvStorageFtwWorkingBase and
PcdFlashNvStorageFtwSpareBase are hardcoded in INC file.

This version will calculate them from FDT resource and using the set PCD
to store when the NorFlashInitialise is called. By default, the first
available flash(not used for storage UEFI code) as NV variable storage
medium.

In this way, UEFI can better handle the change of flash base address,
which is suitable for different cpu architecture board implementation.

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=4770

Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Chao Li <lichao@loongson.cn>
Co-authored-by: Xianglai Li <lixianglai@loongson.cn>
Tested-by: Gerd Hoffmann <kraxel@redhat.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
2024-06-04 22:51:09 +00:00
de4cc40b8c MdeModulePkg/HiiDatabaseDxe: Avoid struct assignment
Struct assignments are not permitted in EDK2, as they may be converted
by the compiler into calls to the 'memcpy' intrinsic, which is not
guaranteed to be available in EDK2.

So replace the assignment with a call to CopyMem (), and -while at it-
replace the loop with a single CopyMem () call, as the loop operates on
items that are contiguous in memory.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2024-06-04 19:06:24 +00:00
839bd17973 UefiCpuPkg:fix issue when splitting paging entry
This patch is to fix issue when splitting leaf paging
entry in CpuPageTableLib code.

In previous code, before we assign the new child paging
structure address to the content of splitted paging entry,
PageTableLibSetPnle() is called to make sure the bit7 is
set to 0, which indicate the previous leaf entry is
changed to non-leaf entry now. There is a gap between
we change the bit7 and we assign the new child paging
structure address to the content of the splitted paging
entry. If the address of code execution or data access
happens to be in the range covered by the splitted paging
entry, this gap may cause issue.

In this patch, we prepare the new paging entry content
value in a local variable and assign the value to the
splitted paging entry at once. The volatile keyword
is used to ensure that no optimization will occur in
compilation.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Zhou Jianfeng <jianfeng.zhou@intel.com>
2024-06-04 12:38:54 +00:00
077760fec4 UefiCpuPkg: Remove GetAcpiCpuData() in CpuS3.c
Remove GetAcpiCpuData() in CpuS3.c. The mAcpiCpuData
is not needed in S3 boot anymore.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
e3b3e907e1 MdeModulePkg:Remove MpService2Ppi field in SMM_S3_RESUME_STATE
This MpService2Ppi field in SMM_S3_RESUME_STATE is used to
wakeup AP to do the CPU initialization during smm s3 boot when
the execution mode of PEI and DXE are the same.
Currently, in CpuS3.c of smm cpu driver, BSP doesn't need to
wakeup AP anymore. The initialization for AP will be done in
S3Resume.c before transfer to CpuS3.c of smm cpu driver.
So we can remove the MpService2Ppi field in SMM_S3_RESUME_STATE.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
2024-06-04 07:40:27 +00:00
d390b163f8 UefiCpuPkg: Remove unneeded MpService2Ppi assignment
Remove the unneeded assignment of MpService2Ppi field
in SmmS3ResumeState. Previously, when the execution
combination of PEI and DXE are the same, the pointer
of mpservice ppi will be passed to CpuS3.c in smm cpu
driver to wakeup all APs, instead of init-sipi-sipi.
Currently, CpuS3.c doesn't need to wakeup Aps anymore.
So remove the duplicated mpservice locate and assignment
to MpService2Ppi field in SmmS3ResumeState.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
341ee5c31b UefiCpuPkg:Remove code to wakeup AP and relocate ap
After the code to load mtrr setting, set register table,
handle APIC setting and Interrupt after INIT-SIPI-SIPI
is moved, the InitializeCpuProcedure() only contains
following code logic:
1.Bsp runs ExecuteFirstSmiInit().
2.Bsp transfers AP to safe hlt-loop

During S3 boot, since APs will be relocated to new safe
buffer by the callback of gEdkiiEndOfS3ResumeGuid in
PeiMpLib, Bsp doesn't need to transfer AP to safe hlt-loop
any more. SmmRestoreCpu() in CpuS3 only needs to runs the
ExecuteFirstSmiInit() on BSP. So remove code to wakeup
AP by INIT-SIPI-SIPI and remove code to relocate ap to
safe hlt-loop.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
525578bdd5 UefiCpuPkg:Remove code to handle APIC setting and Interrupt
Remove ProgramVirtualWireMode()/DisableLvtInterrupts()
since APs won't be waken by INIT-SIPI-SIPI in CpuS3.c
any more. The two functions has been executed in
MpInitLibInitialize() in PeiMplib.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
cdc1a88272 UefiCpuPkg:Relocate AP to new safe buffer in PeiMpLib
In this commit, change PeiMpLib to install callback
of gEdkiiEndOfS3ResumeGuid to relocate AP to new safe
buffer. The gEdkiiEndOfS3ResumeGuid is installed in
S3Resume.c before jmping to OS waking vector.

Previously, code in CpuS3.c of PiSmmCpuDxe driver will
prepare the new safe buffer for AP and place AP in hlt
loop state. With this code change, we can remove the
Machine Instructions of mApHltLoopCode in PiSmmCpuDxe.
Also we can reuse the related code in DxeMpLib for
PeiMpLib.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
669291db5a UefiCpuPkg: Install gEdkiiEndOfS3ResumeGuid in S3Resume
Install gEdkiiEndOfS3ResumeGuid in S3Resume to trigger
callback registered by PeiMpLib. The callback is to
relocate Ap to new safe memory before jump to OS waking
vector in S3 boot flow.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
fcd09b1edb UefiCpuPkg:Move some code in DxeMpLib to common place
Move some code in DxeMpLib.C to common MpLib.c.
The related code is to relocate Ap to new safe buffer
before booting into OS. In next commits, these code
also will be used by PeiMpLib. This commit doesn't
change any code functionality.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
68310cd56a UefiCpuPkg:Abstract some DxeMpLib code to function
Abstract some DxeMpLib code to function in this commit.
Some of these internal functions will be moved to common
MpLib.c in following commits. Then PeiMpLib can reuse
the code.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
ffb8481ba8 UefiCpuPkg: Disable PG in IA32 ApLoopCode
Disable paging in IA32 RelocateApLoop assembly
code to fix the issue that the AP page table is
unavailiable after boot OS under IA32 execution mode.

This issue exist in IA32 PEI + IA32 DXE normal boot
(also S3 boot with IA32 PEI after previous three commits
are accepted). In current MpLib code, the IA32 execution
mode code did not create page table in reserved memory
like what X64 code did. If PcdCpuStackGuard is TRUE, the
PG is enabled for AP in current RelocateApLoop assembly
code. And the page table for AP is unavailiable after
boot OS. This might cause potential issue. So disable PG
in IA32 RelocateApLoop.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
7421ea1f2a UefiCpuPkg: Remove code to set register table
Remove code to set register table in CpuS3.c.
In previous commit, PcdCpuFeaturesInitOnS3Resume
has been set to TRUE. So that CpuFeaturesPei PEIM
will initialize the CPU registers and perform CPU
features initialization.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
b7db4d895a UefiCpuPkg:Set PcdCpuFeaturesInitOnS3Resume to TRUE
Set PcdCpuFeaturesInitOnS3Resume to TRUE. So that
CpuFeaturesPei PEIM will initialize the CPU registers
and perform CPU features initialization.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
db4101c308 UefiCpuPkg: Remove code to load mtrr setting
Remove code to load mtrr setting in CpuS3.c.
In previous commits, before transferring to
CpuS3.c, MTRR setting has been loaded in
S3RestoreConfig2() for all CPU.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
ad245ffeff UefiCpuPkg: LoadMtrrData for all cpu in S3Resume
In this commit, S3Resume.c wakeup all Aps to run
LoadMtrrData for all cpu before transfer to CpuS3.c
in smm cpu driver. The MtrrSetting table can be restored
by gEdkiiS3MtrrSettingGuid which is saved by lockbox in
PEI phase. This can avoid waking up APs in CpuS3.c.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
3a516aa240 UefiCpuPkg: Save MTRR by lockbox in CpuS3DataDxe
Save MTRR by lockbox in CpuS3DataDxe. In S3 boot,
The MTRR setting will be restored in S3Resume.c
in following patches. Then S3Resume.c will wakeup
all APs to load the MTRR setting. This can avoid
waking up APs in CpuS3.c.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
32a9ee736e UefiCpuPkg: Add locbox lib instance in DSC
Add locbox lib instance in DSC. The SmmLockBoxDxeLib
will be consumed by CpuS3DataDxe driver

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
52a4bc65f6 OvmfPkg: Save MTRR by lockbox in CpuS3DataDxe
Save MTRR by lockbox in CpuS3DataDxe. In S3 boot,
The MTRR setting will be restored in S3Resume.c
in following patches. Then S3Resume.c will wakeup
all APs to load the MTRR setting. This can avoid
waking up APs in CpuS3.c.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
87f22f4b5c MdeModulePkg: Add gEdkiiS3MtrrSettingGuid
Add gEdkiiS3MtrrSettingGuid a new GUID for s3
MTRR setting. This GUID will be used to save
MTRR_SETTINGS at EndOfDxe by LockBox and restore
at S3 boot PEI phase for s3 usage.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-06-04 07:40:27 +00:00
27b044605c ArmPkg: Set BIOS Segment to 0 in SMBIOS Type 0 table
According to the SMBIOS specification, on UEFI systems the BIOS Segment
field in the Type 0 table isn't relevant and should be set to 0.

Signed-off-by: Rebecca Cran <rebecca@bsdio.com>
2024-06-03 14:28:45 -06:00
b0930e3f4e CryptoPkg/BaseCryptLib: Enable more functions for SMM/StandaloneMM
This facilitates RSA extension, PKCS7 sign, and bignum function to
broaden the range of algorithms available in SMM/StandaloneMM for
platform utilization.

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
2024-06-03 10:48:34 +00:00
de2330450f MdeModulePkg: Update GCD attribute conversion to support SP attribute
Add a new entry into GCD attribute conversion table to convert
EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE to EFI_MEMORY_SP.

Signed-off-by: Du Lin <du.lin@intel.com>
2024-06-02 01:58:12 +00:00
7339bfeffa OvmfPkg/VirtioRngDxe: check if device is ready
Add a 'Ready' boolean to the driver state struct, use it to track
whenever the device is ready to be used.  In case it is not ready
throw an EFI_DEVICE_ERROR instead of sending a request which will
never receive an answer.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2024-05-31 23:00:40 -07:00
3b36aa96de CryptoPkg: Remove deprecated code related to SHA-1
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4698

The default drbg type of randlib has been switched to aes_256_ctr in
openssl1.1.1, so sha1 is not really used in RandomSeed(). Remove related code
which do SHA-1 support checking in CryptRand.c and CryptRandTsc.c to avoid
potential compatibility errors.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Signed-off-by: Shang Qingyu <qingyu.shang@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
2024-05-31 15:54:23 +00:00
7c584bb048 CryptoPkg: Fix bug for correct return value checking when get X509Cert
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4509

CryptX509.c file has X509GetTBSCert() funtion and it is added Inf variable
to collect the return value of ASN1_get_object(), which return 0x80 in error
case. Supplement the return value check during the second function call
and correct the check logic.

Signed-off-by: Qingyu <qingyu.shang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
2024-05-31 12:24:38 +00:00
746cc5cc40 CryptoPkg: Add support for aes128-sha256 and aes256-sha256 cipher
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4739

AES256-SHA256 is a Tls1.2 suite we need to support, add it to deflt_ciphers
in OpensslStub.

Signed-off-by: Shang Qingyu <qingyu.shang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
2024-05-31 07:44:03 +00:00
5f68a363d0 pip: bump edk2-pytool-extensions from 0.26.4 to 0.27.5
Bumps [edk2-pytool-extensions](https://github.com/tianocore/edk2-pytool-extensions) from 0.26.4 to 0.27.5.
- [Release notes](https://github.com/tianocore/edk2-pytool-extensions/releases)
- [Commits](https://github.com/tianocore/edk2-pytool-extensions/compare/v0.26.4...v0.27.5)

---
updated-dependencies:
- dependency-name: edk2-pytool-extensions
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-31 02:07:59 +00:00
a8dc6bf73f pip: bump edk2-pytool-library from 0.20.0 to 0.21.5
Bumps [edk2-pytool-library](https://github.com/tianocore/edk2-pytool-library) from 0.20.0 to 0.21.5.
- [Release notes](https://github.com/tianocore/edk2-pytool-library/releases)
- [Commits](https://github.com/tianocore/edk2-pytool-library/compare/v0.20.0...v0.21.5)

---
updated-dependencies:
- dependency-name: edk2-pytool-library
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-30 22:43:30 +00:00
Sam
ced13b93af NetworkPkg TcpDxe: Fixed system stuck on PXE boot flow in iPXE environment
This bug fix is based on the following commit "NetworkPkg TcpDxe: SECURITY PATCH"
REF: 1904a64

Issue Description:
An "Invalid handle" error was detected during runtime when attempting to destroy a child instance of the hashing protocol. The problematic code segment was:

NetworkPkg\TcpDxe\TcpDriver.c
Status = Hash2ServiceBinding->DestroyChild(Hash2ServiceBinding, ​&mHash2ServiceHandle);

Root Cause Analysis:
The root cause of the error was the passing of an incorrect parameter type, a pointer to an EFI_HANDLE instead of an EFI_HANDLE itself, to the DestroyChild function. This mismatch resulted in the function receiving an invalid handle.

Implemented Solution:
To resolve this issue, the function call was corrected to pass mHash2ServiceHandle directly:

NetworkPkg\TcpDxe\TcpDriver.c
Status = Hash2ServiceBinding->DestroyChild(Hash2ServiceBinding, mHash2ServiceHandle);

This modification ensures the correct handle type is used, effectively rectifying the "Invalid handle" error.

Verification:
Testing has been conducted, confirming the efficacy of the fix. Additionally, the BIOS can boot into the OS in an iPXE environment.

Cc: Doug Flick [MSFT] <doug.edk2@gmail.com>

Signed-off-by: Sam Tsai [Wiwynn] <sam_tsai@wiwynn.com>
Reviewed-by: Saloni Kasbekar <saloni.kasbekar@intel.com>
2024-05-30 21:06:38 +00:00
e784848116 pip: bump regex from 2023.12.25 to 2024.5.15
Bumps [regex](https://github.com/mrabarnett/mrab-regex) from 2023.12.25 to 2024.5.15.
- [Changelog](https://github.com/mrabarnett/mrab-regex/blob/hg/changelog.txt)
- [Commits](https://github.com/mrabarnett/mrab-regex/compare/2023.12.25...2024.5.15)

---
updated-dependencies:
- dependency-name: regex
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-30 17:01:38 +00:00
9518d77eb8 OvmfPkg: Update VMM Hob list check to support new resource attributes
Encrypted and Special Purpose resource attributes are introduced in
PI 1.8 Specification. This patch is to update VMM Hob list integrity
check to recognize these resource attributes.

Signed-off-by: Du Lin <du.lin@intel.com>
2024-05-30 12:10:54 +00:00
c695e3182a MdePkg: Add Ipmi definitions header file for OEM net function
Add net function definitions for OEM/Non-IPMI group
request and response

Signed-off-by: Nickle Wang <nicklew@nvidia.com>
Cc: Abner Chang <abner.chang@amd.com>
Cc: Abdul Lateef Attar <AbdulLateef.Attar@amd.com>
Cc: Nick Ramirez <nramirez@nvidia.com>
Reviewed-by: Abner Chang <abner.chang@amd.com>
2024-05-30 08:13:01 +00:00
cd4cebabf5 UefiPayloadPkg: Update ReadMe.md to swig install
Update ReadMe.md for swig install process in
windows OS.

Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>

Signed-off-by: Gua Guo <gua.guo@intel.com>
Reviewed-by: Guo Dong <guo.dong@intel.com>
2024-05-30 05:17:27 +00:00
843f2d0964 EmulatorPkg: fix build error.
GasketSecSetTime is EMU_SET_TIME and returns EFI_STATUS.  Fix the
declaration accordingly.  Fixes build error with gcc 14.

    /home/kraxel/projects/edk2/EmulatorPkg/Unix/Host/EmuThunk.c:429:3: error: initialization of ‘EFI_STATUS (__attribute__((ms_abi)) *)(EFI_TIME *)’ {aka ‘long long unsigned int (__attribute__((ms_abi)) *)(EFI_TIME *)’} from incompatible pointer type ‘void (__attribute__((ms_abi)) *)(EFI_TIME *)’ [-Wincompatible-pointer-types]
      429 |   GasketSecSetTime,
          |   ^~~~~~~~~~~~~~~~

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
2024-05-30 04:18:49 +00:00
30b6d08e27 StandaloneMmPkg: Initialize 'WillReturn' variable
The local variable 'WillReturn' was being used without prior
initialization in some code paths.
This patch ensures that 'WillReturn' is properly initialized
to prevent undefined behavior.

Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2024-05-30 01:57:35 +00:00
b40c64ec25 MdeModulePkg/SMM: Initialize 'WillReturn' variable
The local variable 'WillReturn' was being used without prior
initialization in some code paths.
This patch ensures that 'WillReturn' is properly initialized
to prevent undefined behavior.

Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
2024-05-30 01:57:35 +00:00
79655e2768 SecurityPkg: Update libspdm submodule to use GitLab cmocka repo
As noted in https://github.com/DMTF/libspdm/issues/2707, the cmocka
submodule on cryptomilk is unreliable and impacting downstream
consumer builds of SecurityPkg. This is considered a regression in
that pre-existing workflows that clone and recursively initialize
the repo are now broken.

The cmocka host was switched to a more reliable gitlab host in
https://github.com/DMTF/libspdm/pull/2710. This change updates the
submodule in edk2 to use that commit so edk2 users are not blocked
by cryptomilk.org service issues.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
2024-05-30 08:16:35 +08:00
55f8bddade .github: Add PR template
Adds a pull request template with important information to note in
the PR description and guidance on how to classify the PR.

A simple GitHub action is present that applies three labels based
on the boxes checked in the PR template:

- `impact:breaking-change`
- `impact:security`
- `impact:testing`

These provide several purposes.

1. Bring attention to the impact of the PR both for reviewers and
   consumers that reference the PR in the future during debug
   or integration.
2. Allow automated tools like those that create release notes to
   be able to highlight important changes.
3. Similarly, to allow PR searches to conditionalize the search on
   PRs with these tags present.

Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com>
2024-05-29 00:40:36 +00:00
0e3189d406 BaseTools/Scripts: Remove Cc: tag check from PatchCheck.py
The commit message format requirements have been updated for
GitHub PR based code reviews and no longer required Cc: tags
for the maintainers and reviewers.  Remove the Cc: tag check
from PatchCheck.py.

Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
2024-05-28 20:23:14 +00:00
08281572aa Add SM3 functions with openssl for Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Because the Mbedlts 3.3.0 doesn't have Sm3, the Sm3
implementaion is based on Openssl.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
ed7a3143b7 CryptoPkg: Update *.inf in BaseCryptLibMbedTls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Update all *.inf in BaseCryptLibMbedTls based on new implementation.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
3096fcf81d CryptoPkg: Add ImageTimestampVerify based on Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Timestamp Countersignature Verification implementaion based on Mbedtls.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
27a7345882 CryptoPkg: Add AuthenticodeVerify based on Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Implement AuthenticodeVerify based on Mbedtls.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
b5412646db CryptoPkg: Add more RSA related functions based on Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Implement more RSA functions such as RsaPkcs1Sign based Mbedlts.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
e065735b1b CryptoPkg: Add Pkcs5 functions based on Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

PBKDF2 Key Derivation Function Wrapper Implementation over MbedTLS.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
acfd991b68 CryptoPkg: Add Pkcs7 related functions based on Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Because the current Mbedlts pkcs7 library doesn't support
authenticatedAttributes
and only support 0 or 1 certificates in Signed data,
the patch implement Pkcs7 by low Mbedtls Api.

And the implementation has pass unit_tes and integration test.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
40fa5cf299 CryptoPkg: Add X509 functions based on Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

X.509 Certificate Handler Wrapper Implementation over MbedTLS.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
f44cc28972 CryptoPkg: Add Pem APIs based on Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Implement Pem API based on Mbedtls.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
8deeda7ce0 CryptoPkg: Add rand function for BaseCryptLibMbedTls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

Add rand function for BaseCryptLibMbedTls.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
1d8fedb0cd CryptoPkg: Add AeadAesGcm based on Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177

AeadAesGcm implementation based on Mbedtls.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Yi Li <yi1.li@intel.com>
Signed-off-by: Wenxing Hou <wenxing.hou@intel.com>
Reviewed-by: Yi Li <yi1.li@intel.com>
Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
2024-05-27 17:24:30 +08:00
88a4de450f UefiCpuPkg/MpLib:Do not assume BSP is #0.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4778

MPInitlib have wrong expectation that BSP index should always be 0 in
MpInitLibInitialize(), SwitchBsp(),ApWakeupFunction().
That will cause the data mismatch, if the initial BSP is not 0.

Reviewed-by: Ray Ni <ray.ni@intel.com>
Signed-off-by: Ning Feng <ning.feng@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
2024-05-27 10:04:25 +08:00
97 changed files with 8884 additions and 1802 deletions

27
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,27 @@
# Description
<_Include a description of the change and why this change was made._>
<_For each item, place an "x" in between `[` and `]` if true. Example: `[x]` (you can also check items in GitHub UI)_>
<_Create the PR as a Draft PR if it is only created to run CI checks._>
<_Delete lines in \<\> tags before creating the PR._>
- [ ] Breaking change?
- **Breaking change** - Will this cause a break in build or boot behavior?
- Examples: Add a new library class or move a module to a different repo.
- [ ] Impacts security?
- **Security** - Does the change have a direct security impact?
- Examples: Crypto algorithm change or buffer overflow fix.
- [ ] Includes tests?
- **Tests** - Does the change include any explicit test code?
- Examples: Unit tests or integration tests.
## How This Was Tested
<_Describe the test(s) that were run to verify the changes._>
## Integration Instructions
<_Describe how these changes should be integrated. Use N/A if nothing is required._>

36
.github/workflows/pr-labeler.yml vendored Normal file
View File

@ -0,0 +1,36 @@
# This workflow automatically applies labels to pull requests based on regular expression matches against the content
# in the pull request.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# For more information, see:
# https://github.com/github/issue-labeler
name: Apply Labels Based on Message Content
on:
pull_request_target:
types:
- edited
- opened
- reopened
- synchronize
workflow_dispatch:
jobs:
sync:
name: Label PR from Description
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Apply Labels Based on PR Description
uses: github/issue-labeler@v3.1
with:
configuration-path: .github/workflows/pr-labeler/regex.yml
enable-versioned-regex: 0
repo-token: ${{ secrets.GITHUB_TOKEN }}

16
.github/workflows/pr-labeler/regex.yml vendored Normal file
View File

@ -0,0 +1,16 @@
# Specifies labels to apply to pull requests based on regular expressions.
#
# Copyright (c) Microsoft Corporation.
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# For more information, see:
# https://github.com/github/issue-labeler
impact:breaking-change:
- '\s*-\s*\[\s*[x|X]\s*\] Breaking change\?'
impact:security:
- '\s*-\s*\[\s*[x|X]\s*\] Impacts security\?'
impact:testing:
- '\s*-\s*\[\s*[x|X]\s*\] Includes tests\?'

View File

@ -78,7 +78,6 @@
gArmTokenSpaceGuid.PcdBaseBoardManufacturer
gArmTokenSpaceGuid.PcdBaseBoardProductName
gArmTokenSpaceGuid.PcdBaseBoardVersion
gArmTokenSpaceGuid.PcdFdBaseAddress
[Guids]
gEfiGenericVariableGuid

View File

@ -253,7 +253,7 @@ SMBIOS_MISC_TABLE_FUNCTION (MiscBiosVendor) {
(VOID)CopyMem (SmbiosRecord, InputData, sizeof (SMBIOS_TABLE_TYPE0));
SmbiosRecord->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE0);
SmbiosRecord->BiosSegment = (UINT16)(FixedPcdGet32 (PcdFdBaseAddress) / SIZE_64KB);
SmbiosRecord->BiosSegment = 0;
if (BiosPhysicalSize < SIZE_16MB) {
SmbiosRecord->BiosSize = Base2ToByteWith64KUnit (BiosPhysicalSize) - 1;
} else {

View File

@ -66,7 +66,7 @@
QemuLoadImageLib|OvmfPkg/Library/GenericQemuLoadImageLib/GenericQemuLoadImageLib.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
VirtNorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
VirtNorFlashPlatformLib|OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
@ -152,6 +152,9 @@
gArmTokenSpaceGuid.PcdVFPEnabled|1
!endif
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress|0x00000000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|$(FD_SIZE)
gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x4007c000
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
@ -231,6 +234,10 @@
# System Memory Size -- 128 MB initially, actual size will be fetched from DT
gArmTokenSpaceGuid.PcdSystemMemorySize|0x8000000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 0x40000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x40000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 0x40000
[PcdsFixedAtBuild.AARCH64]
# Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point,
# if the entry point version is >= 3.0. AARCH64 OSes cannot assume the
@ -243,6 +250,13 @@
[PcdsDynamicDefault.common]
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 | 0
## If TRUE, OvmfPkg/AcpiPlatformDxe will not wait for PCI
# enumeration to complete before installing ACPI tables.
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
@ -404,7 +418,10 @@
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
!endif
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf {
<LibraryClasses>
NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf
}
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf {

View File

@ -65,7 +65,7 @@
ArmVirtMemInfoLib|ArmVirtPkg/Library/QemuVirtMemInfoLib/QemuVirtMemInfoLib.inf
TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
VirtNorFlashPlatformLib|ArmVirtPkg/Library/NorFlashQemuLib/NorFlashQemuLib.inf
VirtNorFlashPlatformLib|OvmfPkg/Library/FdtNorFlashQemuLib/FdtNorFlashQemuLib.inf
CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
@ -120,6 +120,8 @@
gArmTokenSpaceGuid.PcdVFPEnabled|1
!endif
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress|0x00000000
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize|$(FD_SIZE)
gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x4000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
@ -181,6 +183,10 @@
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|3
gEfiShellPkgTokenSpaceGuid.PcdShellFileOperationSize|0x20000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize | 0x40000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize | 0x40000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize | 0x40000
[PcdsPatchableInModule.common]
# we need to provide a resolution for this PCD that supports PcdSet64()
# being called from ArmVirtPkg/Library/PlatformPeiLib/PlatformPeiLib.c,
@ -208,6 +214,13 @@
[PcdsDynamicDefault.common]
gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|3
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64 | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase | 0
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64 | 0
## If TRUE, OvmfPkg/AcpiPlatformDxe will not wait for PCI
# enumeration to complete before installing ACPI tables.
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
@ -313,7 +326,10 @@
MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
!endif
MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf {
<LibraryClasses>
NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedLib.inf
}
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf {

View File

@ -1,42 +0,0 @@
#/** @file
#
# Component description file for NorFlashQemuLib module
#
# Copyright (c) 2014, Linaro Ltd. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = NorFlashQemuLib
FILE_GUID = 339B7829-4C5F-4EFC-B2DD-5050E530DECE
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = VirtNorFlashPlatformLib
[Sources.common]
NorFlashQemuLib.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
ArmVirtPkg/ArmVirtPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
DebugLib
UefiBootServicesTableLib
[Protocols]
gFdtClientProtocolGuid ## CONSUMES
[Depex]
gFdtClientProtocolGuid
[Pcd]
gArmTokenSpaceGuid.PcdFvBaseAddress
gArmTokenSpaceGuid.PcdFvSize

View File

@ -10,7 +10,7 @@
##
[FD.QEMU_VARS]
BaseAddress = 0x04000000
BaseAddress = 0x00000000
Size = 0xc0000
ErasePolarity = 1
BlockSize = 0x40000
@ -18,7 +18,6 @@ NumBlocks = 3
0x00000000|0x00040000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
#NV_VARIABLE_STORE
DATA = {
## This is the EFI_FIRMWARE_VOLUME_HEADER
@ -57,7 +56,6 @@ DATA = {
0x00040000|0x00040000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
#NV_FTW_WORKING
DATA = {
# EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
@ -71,5 +69,4 @@ DATA = {
}
0x00080000|0x00040000
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
#NV_FTW_SPARE

View File

@ -234,8 +234,6 @@ class CommitMessageCheck:
def check_misc_signatures(self):
for sigtype in self.sig_types:
sigs = self.find_signatures(sigtype)
if sigtype == 'Cc' and len(sigs) == 0:
self.error('No Cc: tags for maintainers/reviewers found!')
cve_re = re.compile('CVE-[0-9]{4}-[0-9]{5}[^0-9]')

View File

@ -88,6 +88,7 @@
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
MbedTlsLib|CryptoPkg/Library/MbedTlsLib/MbedTlsLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf

View File

@ -2351,6 +2351,8 @@ Pkcs7FreeSigners (
unchained to the signer's certificates.
The input signed data could be wrapped in a ContentInfo structure.
Pkcs7GetCertificatesList has not been implemented in BaseCryptoLibMbedTls.
@param[in] P7Data Pointer to the PKCS#7 message.
@param[in] P7Length Length of the PKCS#7 message in bytes.
@param[out] SignerChainCerts Pointer to the certificates list chained to signer's
@ -3139,6 +3141,8 @@ DhComputeKey (
If Seed is NULL, then default seed is used.
If this interface is not supported, then return FALSE.
RandomSeed has not been implemented in BaseCryptoLibMbedTls.
@param[in] Seed Pointer to seed value.
If NULL, default seed is used.
@param[in] SeedSize Size of seed value.

View File

@ -839,17 +839,17 @@ X509GetTBSCert (
Length = 0;
Inf = ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)CertSize);
if (((Inf & 0x80) == 0x00) && (Asn1Tag != V_ASN1_SEQUENCE)) {
if (((Inf & 0x80) == 0x80) || (Asn1Tag != V_ASN1_SEQUENCE)) {
return FALSE;
}
*TBSCert = (UINT8 *)Temp;
ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)Length);
Inf = ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)Length);
//
// Verify the parsed TBSCertificate is one correct SEQUENCE data.
//
if (((Inf & 0x80) == 0x00) && (Asn1Tag != V_ASN1_SEQUENCE)) {
if (((Inf & 0x80) == 0x80) || (Asn1Tag != V_ASN1_SEQUENCE)) {
return FALSE;
}

View File

@ -42,14 +42,6 @@ RandomSeed (
return FALSE;
}
//
// The software PRNG implementation built in OpenSSL depends on message digest algorithm.
// Make sure SHA-1 digest algorithm is available here.
//
if (EVP_add_digest (EVP_sha1 ()) == 0) {
return FALSE;
}
//
// Seed the pseudorandom number generator with user-supplied value.
// NOTE: A cryptographic PRNG must be seeded with unpredictable data.

View File

@ -40,14 +40,6 @@ RandomSeed (
return FALSE;
}
//
// The software PRNG implementation built in OpenSSL depends on message digest algorithm.
// Make sure SHA-1 digest algorithm is available here.
//
if (EVP_add_digest (EVP_sha1 ()) == 0) {
return FALSE;
}
//
// Seed the pseudorandom number generator with user-supplied value.
// NOTE: A cryptographic PRNG must be seeded with unpredictable data.

View File

@ -48,10 +48,10 @@
Cipher/CryptAes.c
Cipher/CryptAeadAesGcmNull.c
Pk/CryptRsaBasic.c
Pk/CryptRsaExtNull.c
Pk/CryptRsaExt.c
Pk/CryptPkcs1Oaep.c
Pk/CryptPkcs5Pbkdf2.c
Pk/CryptPkcs7SignNull.c
Pk/CryptPkcs7Sign.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyBase.c
Pk/CryptPkcs7VerifyEku.c
@ -63,7 +63,7 @@
Pk/CryptRsaPssSignNull.c
Pk/CryptEcNull.c
Pem/CryptPem.c
Bn/CryptBnNull.c
Bn/CryptBn.c
SysCall/CrtWrapper.c
SysCall/ConstantTimeClock.c

View File

@ -27,34 +27,38 @@
[Sources]
InternalCryptLib.h
Cipher/CryptAeadAesGcmNull.c
Cipher/CryptAes.c
Hash/CryptMd5.c
Hash/CryptSha1.c
Hash/CryptSha256.c
Hash/CryptSha512.c
Hash/CryptParallelHashNull.c
Hash/CryptSm3Null.c
Hash/CryptMd5.c
Hash/CryptSha1.c
Hash/CryptSm3.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
Cipher/CryptAes.c
Cipher/CryptAeadAesGcm.c
Pk/CryptRsaBasic.c
Pk/CryptRsaExtNull.c
Pk/CryptRsaPss.c
Pk/CryptRsaPssSignNull.c
Bn/CryptBnNull.c
Pem/CryptPemNull.c
Pk/CryptRsaExt.c
Pk/CryptPkcs1Oaep.c
Pk/CryptPkcs5Pbkdf2.c
Pk/CryptPkcs7Sign.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyBase.c
Pk/CryptPkcs7VerifyEku.c
Pk/CryptDhNull.c
Pk/CryptX509.c
Pk/CryptAuthenticode.c
Pk/CryptTs.c
Pk/CryptRsaPss.c
Pk/CryptRsaPssSign.c
Pk/CryptEcNull.c
Pk/CryptPkcs1OaepNull.c
Pk/CryptPkcs5Pbkdf2Null.c
Pk/CryptPkcs7SignNull.c
Pk/CryptPkcs7VerifyNull.c
Pk/CryptPkcs7VerifyEkuNull.c
Pk/CryptX509Null.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
Rand/CryptRandNull.c
Pem/CryptPem.c
Bn/CryptBnNull.c
Rand/CryptRand.c
SysCall/CrtWrapper.c
SysCall/DummyOpensslSupport.c
SysCall/BaseMemAllocation.c
SysCall/TimerWrapper.c
[Packages]
@ -68,6 +72,7 @@
UefiRuntimeServicesTableLib
DebugLib
MbedTlsLib
OpensslLib
PrintLib
IntrinsicLib
RngLib

View File

@ -0,0 +1,227 @@
/** @file
AEAD (AES-GCM) Wrapper Implementation over MbedTLS.
RFC 5116 - An Interface and Algorithms for Authenticated Encryption
NIST SP800-38d - Cipher Modes of Operation: Galois / Counter Mode(GCM) and GMAC
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <mbedtls/gcm.h>
/**
Performs AEAD AES-GCM authenticated encryption on a data buffer and additional authenticated data (AAD).
IvSize must be 12, otherwise FALSE is returned.
KeySize must be 16, 24 or 32, otherwise FALSE is returned.
TagSize must be 12, 13, 14, 15, 16, otherwise FALSE is returned.
@param[in] Key Pointer to the encryption key.
@param[in] KeySize Size of the encryption key in bytes.
@param[in] Iv Pointer to the IV value.
@param[in] IvSize Size of the IV value in bytes.
@param[in] AData Pointer to the additional authenticated data (AAD).
@param[in] ADataSize Size of the additional authenticated data (AAD) in bytes.
@param[in] DataIn Pointer to the input data buffer to be encrypted.
@param[in] DataInSize Size of the input data buffer in bytes.
@param[out] TagOut Pointer to a buffer that receives the authentication tag output.
@param[in] TagSize Size of the authentication tag in bytes.
@param[out] DataOut Pointer to a buffer that receives the encryption output.
@param[out] DataOutSize Size of the output data buffer in bytes.
@retval TRUE AEAD AES-GCM authenticated encryption succeeded.
@retval FALSE AEAD AES-GCM authenticated encryption failed.
**/
BOOLEAN
EFIAPI
AeadAesGcmEncrypt (
IN CONST UINT8 *Key,
IN UINTN KeySize,
IN CONST UINT8 *Iv,
IN UINTN IvSize,
IN CONST UINT8 *AData,
IN UINTN ADataSize,
IN CONST UINT8 *DataIn,
IN UINTN DataInSize,
OUT UINT8 *TagOut,
IN UINTN TagSize,
OUT UINT8 *DataOut,
OUT UINTN *DataOutSize
)
{
mbedtls_gcm_context Ctx;
INT32 Ret;
if (DataInSize > INT_MAX) {
return FALSE;
}
if (ADataSize > INT_MAX) {
return FALSE;
}
if (IvSize != 12) {
return FALSE;
}
switch (KeySize) {
case 16:
case 24:
case 32:
break;
default:
return FALSE;
}
if ((TagSize != 12) && (TagSize != 13) && (TagSize != 14) && (TagSize != 15) && (TagSize != 16)) {
return FALSE;
}
if (DataOutSize != NULL) {
if ((*DataOutSize > INT_MAX) || (*DataOutSize < DataInSize)) {
return FALSE;
}
}
mbedtls_gcm_init (&Ctx);
Ret = mbedtls_gcm_setkey (&Ctx, MBEDTLS_CIPHER_ID_AES, Key, (UINT32)(KeySize * 8));
if (Ret != 0) {
return FALSE;
}
Ret = mbedtls_gcm_crypt_and_tag (
&Ctx,
MBEDTLS_GCM_ENCRYPT,
(UINT32)DataInSize,
Iv,
(UINT32)IvSize,
AData,
(UINT32)ADataSize,
DataIn,
DataOut,
TagSize,
TagOut
);
mbedtls_gcm_free (&Ctx);
if (Ret != 0) {
return FALSE;
}
if (DataOutSize != NULL) {
*DataOutSize = DataInSize;
}
return TRUE;
}
/**
Performs AEAD AES-GCM authenticated decryption on a data buffer and additional authenticated data (AAD).
IvSize must be 12, otherwise FALSE is returned.
KeySize must be 16, 24 or 32, otherwise FALSE is returned.
TagSize must be 12, 13, 14, 15, 16, otherwise FALSE is returned.
If additional authenticated data verification fails, FALSE is returned.
@param[in] Key Pointer to the encryption key.
@param[in] KeySize Size of the encryption key in bytes.
@param[in] Iv Pointer to the IV value.
@param[in] IvSize Size of the IV value in bytes.
@param[in] AData Pointer to the additional authenticated data (AAD).
@param[in] ADataSize Size of the additional authenticated data (AAD) in bytes.
@param[in] DataIn Pointer to the input data buffer to be decrypted.
@param[in] DataInSize Size of the input data buffer in bytes.
@param[in] Tag Pointer to a buffer that contains the authentication tag.
@param[in] TagSize Size of the authentication tag in bytes.
@param[out] DataOut Pointer to a buffer that receives the decryption output.
@param[out] DataOutSize Size of the output data buffer in bytes.
@retval TRUE AEAD AES-GCM authenticated decryption succeeded.
@retval FALSE AEAD AES-GCM authenticated decryption failed.
**/
BOOLEAN
EFIAPI
AeadAesGcmDecrypt (
IN CONST UINT8 *Key,
IN UINTN KeySize,
IN CONST UINT8 *Iv,
IN UINTN IvSize,
IN CONST UINT8 *AData,
IN UINTN ADataSize,
IN CONST UINT8 *DataIn,
IN UINTN DataInSize,
IN CONST UINT8 *Tag,
IN UINTN TagSize,
OUT UINT8 *DataOut,
OUT UINTN *DataOutSize
)
{
mbedtls_gcm_context Ctx;
INT32 Ret;
if (DataInSize > INT_MAX) {
return FALSE;
}
if (ADataSize > INT_MAX) {
return FALSE;
}
if (IvSize != 12) {
return FALSE;
}
switch (KeySize) {
case 16:
case 24:
case 32:
break;
default:
return FALSE;
}
if ((TagSize != 12) && (TagSize != 13) && (TagSize != 14) && (TagSize != 15) && (TagSize != 16)) {
return FALSE;
}
if (DataOutSize != NULL) {
if ((*DataOutSize > INT_MAX) || (*DataOutSize < DataInSize)) {
return FALSE;
}
}
mbedtls_gcm_init (&Ctx);
Ret = mbedtls_gcm_setkey (&Ctx, MBEDTLS_CIPHER_ID_AES, Key, (UINT32)(KeySize * 8));
if (Ret != 0) {
return FALSE;
}
Ret = mbedtls_gcm_auth_decrypt (
&Ctx,
(UINT32)DataInSize,
Iv,
(UINT32)IvSize,
AData,
(UINT32)ADataSize,
Tag,
(UINT32)TagSize,
DataIn,
DataOut
);
mbedtls_gcm_free (&Ctx);
if (Ret != 0) {
return FALSE;
}
if (DataOutSize != NULL) {
*DataOutSize = DataInSize;
}
return TRUE;
}

View File

@ -0,0 +1,235 @@
/** @file
SM3 Digest Wrapper Implementations over openssl.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include "internal/sm3.h"
/**
Retrieves the size, in bytes, of the context buffer required for SM3 hash operations.
@return The size, in bytes, of the context buffer required for SM3 hash operations.
**/
UINTN
EFIAPI
Sm3GetContextSize (
VOID
)
{
//
// Retrieves Openssl SM3 Context Size
//
return (UINTN)(sizeof (SM3_CTX));
}
/**
Initializes user-supplied memory pointed by Sm3Context as SM3 hash context for
subsequent use.
If Sm3Context is NULL, then return FALSE.
@param[out] Sm3Context Pointer to SM3 context being initialized.
@retval TRUE SM3 context initialization succeeded.
@retval FALSE SM3 context initialization failed.
**/
BOOLEAN
EFIAPI
Sm3Init (
OUT VOID *Sm3Context
)
{
//
// Check input parameters.
//
if (Sm3Context == NULL) {
return FALSE;
}
//
// Openssl SM3 Context Initialization
//
ossl_sm3_init ((SM3_CTX *)Sm3Context);
return TRUE;
}
/**
Makes a copy of an existing SM3 context.
If Sm3Context is NULL, then return FALSE.
If NewSm3Context is NULL, then return FALSE.
If this interface is not supported, then return FALSE.
@param[in] Sm3Context Pointer to SM3 context being copied.
@param[out] NewSm3Context Pointer to new SM3 context.
@retval TRUE SM3 context copy succeeded.
@retval FALSE SM3 context copy failed.
@retval FALSE This interface is not supported.
**/
BOOLEAN
EFIAPI
Sm3Duplicate (
IN CONST VOID *Sm3Context,
OUT VOID *NewSm3Context
)
{
//
// Check input parameters.
//
if ((Sm3Context == NULL) || (NewSm3Context == NULL)) {
return FALSE;
}
CopyMem (NewSm3Context, Sm3Context, sizeof (SM3_CTX));
return TRUE;
}
/**
Digests the input data and updates SM3 context.
This function performs SM3 digest on a data buffer of the specified size.
It can be called multiple times to compute the digest of long or discontinuous data streams.
SM3 context should be already correctly initialized by Sm3Init(), and should not be finalized
by Sm3Final(). Behavior with invalid context is undefined.
If Sm3Context is NULL, then return FALSE.
@param[in, out] Sm3Context Pointer to the SM3 context.
@param[in] Data Pointer to the buffer containing the data to be hashed.
@param[in] DataSize Size of Data buffer in bytes.
@retval TRUE SM3 data digest succeeded.
@retval FALSE SM3 data digest failed.
**/
BOOLEAN
EFIAPI
Sm3Update (
IN OUT VOID *Sm3Context,
IN CONST VOID *Data,
IN UINTN DataSize
)
{
//
// Check input parameters.
//
if (Sm3Context == NULL) {
return FALSE;
}
//
// Check invalid parameters, in case that only DataLength was checked in Openssl
//
if ((Data == NULL) && (DataSize != 0)) {
return FALSE;
}
//
// Openssl SM3 Hash Update
//
ossl_sm3_update ((SM3_CTX *)Sm3Context, Data, DataSize);
return TRUE;
}
/**
Completes computation of the SM3 digest value.
This function completes SM3 hash computation and retrieves the digest value into
the specified memory. After this function has been called, the SM3 context cannot
be used again.
SM3 context should be already correctly initialized by Sm3Init(), and should not be
finalized by Sm3Final(). Behavior with invalid SM3 context is undefined.
If Sm3Context is NULL, then return FALSE.
If HashValue is NULL, then return FALSE.
@param[in, out] Sm3Context Pointer to the SM3 context.
@param[out] HashValue Pointer to a buffer that receives the SM3 digest
value (32 bytes).
@retval TRUE SM3 digest computation succeeded.
@retval FALSE SM3 digest computation failed.
**/
BOOLEAN
EFIAPI
Sm3Final (
IN OUT VOID *Sm3Context,
OUT UINT8 *HashValue
)
{
//
// Check input parameters.
//
if ((Sm3Context == NULL) || (HashValue == NULL)) {
return FALSE;
}
//
// Openssl SM3 Hash Finalization
//
ossl_sm3_final (HashValue, (SM3_CTX *)Sm3Context);
return TRUE;
}
/**
Computes the SM3 message digest of a input data buffer.
This function performs the SM3 message digest of a given data buffer, and places
the digest value into the specified memory.
If this interface is not supported, then return FALSE.
@param[in] Data Pointer to the buffer containing the data to be hashed.
@param[in] DataSize Size of Data buffer in bytes.
@param[out] HashValue Pointer to a buffer that receives the SM3 digest
value (32 bytes).
@retval TRUE SM3 digest computation succeeded.
@retval FALSE SM3 digest computation failed.
@retval FALSE This interface is not supported.
**/
BOOLEAN
EFIAPI
Sm3HashAll (
IN CONST VOID *Data,
IN UINTN DataSize,
OUT UINT8 *HashValue
)
{
SM3_CTX Ctx;
//
// Check input parameters.
//
if (HashValue == NULL) {
return FALSE;
}
if ((Data == NULL) && (DataSize != 0)) {
return FALSE;
}
//
// SM3 Hash Computation.
//
ossl_sm3_init (&Ctx);
ossl_sm3_update (&Ctx, Data, DataSize);
ossl_sm3_final (HashValue, &Ctx);
return TRUE;
}

View File

@ -22,4 +22,53 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
//
#include <mbedtls/mbedtls_config.h>
/**
The MbedTLS function f_rng, which MbedtlsRand implements.
@param[in] RngState Not used, just for compatibility with mbedlts.
@param[out] Output Pointer to buffer to receive random value.
@param[in] Len Size of random bytes to generate.
@retval 0 Pseudorandom byte stream generated successfully.
@retval Non-0 Pseudorandom number generator fails to generate due to lack of entropy.
**/
INT32
MbedtlsRand (
VOID *RngState,
UINT8 *Output,
UINTN Len
);
/**
Check input P7Data is a wrapped ContentInfo structure or not. If not construct
a new structure to wrap P7Data.
Caution: This function may receive untrusted input.
UEFI Authenticated Variable is external input, so this function will do basic
check for PKCS#7 data structure.
@param[in] P7Data Pointer to the PKCS#7 message to verify.
@param[in] P7Length Length of the PKCS#7 message in bytes.
@param[out] WrapFlag If TRUE P7Data is a ContentInfo structure, otherwise
return FALSE.
@param[out] WrapData If return status of this function is TRUE:
1) when WrapFlag is TRUE, pointer to P7Data.
2) when WrapFlag is FALSE, pointer to a new ContentInfo
structure. It's caller's responsibility to free this
buffer.
@param[out] WrapDataSize Length of ContentInfo structure in bytes.
@retval TRUE The operation is finished successfully.
@retval FALSE The operation is failed due to lack of resources.
**/
BOOLEAN
WrapPkcs7Data (
IN CONST UINT8 *P7Data,
IN UINTN P7Length,
OUT BOOLEAN *WrapFlag,
OUT UINT8 **WrapData,
OUT UINTN *WrapDataSize
);
#endif

View File

@ -38,31 +38,35 @@
Hash/CryptMd5.c
Hash/CryptSha1.c
Hash/CryptSha256.c
Hash/CryptSm3Null.c
Hash/CryptSha512.c
Hash/CryptParallelHashNull.c
Hash/CryptSm3.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
Cipher/CryptAes.c
Cipher/CryptAeadAesGcmNull.c
Pk/CryptRsaBasic.c
Pk/CryptRsaExtNull.c
Pk/CryptRsaPss.c
Pk/CryptRsaPssSignNull.c
Bn/CryptBnNull.c
Pem/CryptPemNull.c
Pk/CryptDhNull.c
Pk/CryptEcNull.c
Pk/CryptPkcs1OaepNull.c
Pk/CryptPkcs5Pbkdf2Null.c
Pk/CryptPkcs7SignNull.c
Pk/CryptPkcs7VerifyNull.c
Pk/CryptPkcs7VerifyEkuNull.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyBase.c
Pk/CryptPkcs7VerifyEku.c
Pk/CryptDhNull.c
Pk/CryptX509Null.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
Pk/CryptRsaPss.c
Pk/CryptRsaPssSignNull.c
Pk/CryptEcNull.c
Pem/CryptPemNull.c
Rand/CryptRandNull.c
Bn/CryptBnNull.c
SysCall/CrtWrapper.c
SysCall/DummyOpensslSupport.c
SysCall/BaseMemAllocation.c
SysCall/ConstantTimeClock.c
[Packages]
@ -75,6 +79,7 @@
MemoryAllocationLib
DebugLib
MbedTlsLib
OpensslLib
IntrinsicLib
PrintLib
PeiServicesTablePointerLib

View File

@ -0,0 +1,138 @@
/** @file
PEM (Privacy Enhanced Mail) Format Handler Wrapper Implementation over MbedTLS.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <mbedtls/pem.h>
#include <mbedtls/pk.h>
#include <mbedtls/rsa.h>
#include <mbedtls/ecp.h>
#include <mbedtls/ecdh.h>
#include <mbedtls/ecdsa.h>
/**
Retrieve the RSA Private Key from the password-protected PEM key data.
@param[in] PemData Pointer to the PEM-encoded key data to be retrieved.
@param[in] PemSize Size of the PEM key data in bytes.
@param[in] Password NULL-terminated passphrase used for encrypted PEM key data.
@param[out] RsaContext Pointer to new-generated RSA context which contain the retrieved
RSA private key component. Use RsaFree() function to free the
resource.
If PemData is NULL, then return FALSE.
If RsaContext is NULL, then return FALSE.
@retval TRUE RSA Private Key was retrieved successfully.
@retval FALSE Invalid PEM key data or incorrect password.
**/
BOOLEAN
EFIAPI
RsaGetPrivateKeyFromPem (
IN CONST UINT8 *PemData,
IN UINTN PemSize,
IN CONST CHAR8 *Password,
OUT VOID **RsaContext
)
{
INT32 Ret;
mbedtls_pk_context Pk;
mbedtls_rsa_context *Rsa;
UINT8 *NewPemData;
UINTN PasswordLen;
if ((PemData == NULL) || (RsaContext == NULL) || (PemSize > INT_MAX)) {
return FALSE;
}
NewPemData = NULL;
if (PemData[PemSize - 1] != 0) {
NewPemData = AllocateZeroPool (PemSize + 1);
if (NewPemData == NULL) {
return FALSE;
}
CopyMem (NewPemData, PemData, PemSize + 1);
NewPemData[PemSize] = 0;
PemData = NewPemData;
PemSize += 1;
}
mbedtls_pk_init (&Pk);
if (Password != NULL) {
PasswordLen = AsciiStrLen (Password);
} else {
PasswordLen = 0;
}
Ret = mbedtls_pk_parse_key (&Pk, PemData, PemSize, (CONST UINT8 *)Password, PasswordLen, NULL, NULL);
if (NewPemData != NULL) {
FreePool (NewPemData);
NewPemData = NULL;
}
if (Ret != 0) {
mbedtls_pk_free (&Pk);
return FALSE;
}
if (mbedtls_pk_get_type (&Pk) != MBEDTLS_PK_RSA) {
mbedtls_pk_free (&Pk);
return FALSE;
}
Rsa = RsaNew ();
if (Rsa == NULL) {
mbedtls_pk_free (&Pk);
return FALSE;
}
Ret = mbedtls_rsa_copy (Rsa, mbedtls_pk_rsa (Pk));
if (Ret != 0) {
RsaFree (Rsa);
mbedtls_pk_free (&Pk);
return FALSE;
}
mbedtls_pk_free (&Pk);
*RsaContext = Rsa;
return TRUE;
}
/**
Retrieve the EC Private Key from the password-protected PEM key data.
@param[in] PemData Pointer to the PEM-encoded key data to be retrieved.
@param[in] PemSize Size of the PEM key data in bytes.
@param[in] Password NULL-terminated passphrase used for encrypted PEM key data.
@param[out] EcContext Pointer to new-generated EC DSA context which contain the retrieved
EC private key component. Use EcFree() function to free the
resource.
If PemData is NULL, then return FALSE.
If EcContext is NULL, then return FALSE.
@retval TRUE EC Private Key was retrieved successfully.
@retval FALSE Invalid PEM key data or incorrect password.
**/
BOOLEAN
EFIAPI
EcGetPrivateKeyFromPem (
IN CONST UINT8 *PemData,
IN UINTN PemSize,
IN CONST CHAR8 *Password,
OUT VOID **EcContext
)
{
ASSERT (FALSE);
return FALSE;
}

View File

@ -0,0 +1,214 @@
/** @file
Authenticode Portable Executable Signature Verification which does not provide
real capabilities.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <mbedtls/pkcs7.h>
//
// OID ASN.1 Value for SPC_INDIRECT_DATA_OBJID
//
GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mSpcIndirectOidValue[] = {
0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x04
};
/**
Verifies the validity of a PE/COFF Authenticode Signature as described in "Windows
Authenticode Portable Executable Signature Format".
Return FALSE to indicate this interface is not supported.
@param[in] AuthData Pointer to the Authenticode Signature retrieved from signed
PE/COFF image to be verified.
@param[in] DataSize Size of the Authenticode Signature in bytes.
@param[in] TrustedCert Pointer to a trusted/root certificate encoded in DER, which
is used for certificate chain verification.
@param[in] CertSize Size of the trusted certificate in bytes.
@param[in] ImageHash Pointer to the original image file hash value. The procedure
for calculating the image hash value is described in Authenticode
specification.
@param[in] HashSize Size of Image hash value in bytes.
@retval FALSE This interface is not supported.
**/
BOOLEAN
EFIAPI
AuthenticodeVerify (
IN CONST UINT8 *AuthData,
IN UINTN DataSize,
IN CONST UINT8 *TrustedCert,
IN UINTN CertSize,
IN CONST UINT8 *ImageHash,
IN UINTN HashSize
)
{
BOOLEAN Status;
CONST UINT8 *OrigAuthData;
UINT8 *SpcIndirectDataContent;
UINT8 Asn1Byte;
UINTN ContentSize;
CONST UINT8 *SpcIndirectDataOid;
UINT8 *Ptr;
UINT8 *End;
INT32 Len;
UINTN ObjLen;
OrigAuthData = AuthData;
//
// Check input parameters.
//
if ((AuthData == NULL) || (TrustedCert == NULL) || (ImageHash == NULL)) {
return FALSE;
}
if ((DataSize > INT_MAX) || (CertSize > INT_MAX) || (HashSize > INT_MAX)) {
return FALSE;
}
if (DataSize <= HashSize) {
return FALSE;
}
Ptr = (UINT8 *)(UINTN)AuthData;
Len = (UINT32)DataSize;
End = Ptr + Len;
// ContentInfo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// ContentType
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
return FALSE;
}
Ptr += ObjLen;
// content
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
return FALSE;
}
End = Ptr + ObjLen;
// signedData
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// version
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
return FALSE;
}
Ptr += ObjLen;
// digestAlgo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
return FALSE;
}
Ptr += ObjLen;
// encapContentInfo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
End = Ptr + ObjLen;
// eContentType
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
return FALSE;
}
Status = FALSE;
SpcIndirectDataOid = Ptr;
if ((ObjLen != sizeof (mSpcIndirectOidValue)) ||
(CompareMem (
SpcIndirectDataOid,
mSpcIndirectOidValue,
sizeof (mSpcIndirectOidValue)
) != 0))
{
//
// Un-matched SPC_INDIRECT_DATA_OBJID.
//
goto _Exit;
}
Ptr += ObjLen;
// eContent
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
return FALSE;
}
SpcIndirectDataContent = Ptr;
//
// Retrieve the SEQUENCE data size from ASN.1-encoded SpcIndirectDataContent.
//
Asn1Byte = *(SpcIndirectDataContent + 1);
if ((Asn1Byte & 0x80) == 0) {
//
// Short Form of Length Encoding (Length < 128)
//
ContentSize = (UINTN)(Asn1Byte & 0x7F);
//
// Skip the SEQUENCE Tag;
//
SpcIndirectDataContent += 2;
} else if ((Asn1Byte & 0x81) == 0x81) {
//
// Long Form of Length Encoding (128 <= Length < 255, Single Octet)
//
ContentSize = (UINTN)(*(UINT8 *)(SpcIndirectDataContent + 2));
//
// Skip the SEQUENCE Tag;
//
SpcIndirectDataContent += 3;
} else if ((Asn1Byte & 0x82) == 0x82) {
//
// Long Form of Length Encoding (Length > 255, Two Octet)
//
ContentSize = (UINTN)(*(UINT8 *)(SpcIndirectDataContent + 2));
ContentSize = (ContentSize << 8) + (UINTN)(*(UINT8 *)(SpcIndirectDataContent + 3));
//
// Skip the SEQUENCE Tag;
//
SpcIndirectDataContent += 4;
} else {
goto _Exit;
}
//
// Compare the original file hash value to the digest retrieve from SpcIndirectDataContent
// defined in Authenticode
// NOTE: Need to double-check HashLength here!
//
if (ContentSize < HashSize) {
return FALSE;
}
if (CompareMem (SpcIndirectDataContent + ContentSize - HashSize, ImageHash, HashSize) != 0) {
//
// Un-matched PE/COFF Hash Value
//
goto _Exit;
}
//
// Verifies the PKCS#7 Signed Data in PE/COFF Authenticode Signature
//
Status = (BOOLEAN)Pkcs7Verify (OrigAuthData, DataSize, TrustedCert, CertSize, SpcIndirectDataContent, ContentSize);
_Exit:
return Status;
}

View File

@ -0,0 +1,278 @@
/** @file
This file contains UEFI wrapper functions for RSA PKCS1v2 OAEP encryption routines.
SPDX-License-Identifier: BSD-2-Clause-Patent
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
**/
#include "InternalCryptLib.h"
#include <mbedtls/rsa.h>
#include <mbedtls/x509_crt.h>
#include <Library/MemoryAllocationLib.h>
/**
Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the
encrypted message in a newly allocated buffer.
Things that can cause a failure include:
- X509 key size does not match any known key size.
- Fail to parse X509 certificate.
- Fail to allocate an intermediate buffer.
- Null pointer provided for a non-optional parameter.
- Data size is too large for the provided key size (max size is a function of key size
and hash digest size).
@param[in] PublicKey A pointer to the DER-encoded X509 certificate that
will be used to encrypt the data.
@param[in] PublicKeySize Size of the X509 cert buffer.
@param[in] InData Data to be encrypted.
@param[in] InDataSize Size of the data buffer.
@param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer
to be used when initializing the PRNG. NULL otherwise.
@param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.
0 otherwise.
@param[out] EncryptedData Pointer to an allocated buffer containing the encrypted
message.
@param[out] EncryptedDataSize Size of the encrypted message buffer.
@retval TRUE Encryption was successful.
@retval FALSE Encryption failed.
**/
BOOLEAN
EFIAPI
Pkcs1v2Encrypt (
IN CONST UINT8 *PublicKey,
IN UINTN PublicKeySize,
IN UINT8 *InData,
IN UINTN InDataSize,
IN CONST UINT8 *PrngSeed OPTIONAL,
IN UINTN PrngSeedSize OPTIONAL,
OUT UINT8 **EncryptedData,
OUT UINTN *EncryptedDataSize
)
{
BOOLEAN Result;
UINT32 Ret;
UINT8 *OutData;
mbedtls_x509_crt CertContext;
mbedtls_rsa_context RsaContext;
//
// Check input parameters.
//
if ((PublicKey == NULL) || (InData == NULL) ||
(EncryptedData == NULL) || (EncryptedDataSize == NULL))
{
return FALSE;
}
//
// Check public key size.
//
if (PublicKeySize > UINT_MAX) {
//
// Public key size is too large for implementation.
//
return FALSE;
}
*EncryptedData = NULL;
*EncryptedDataSize = 0;
Result = FALSE;
OutData = NULL;
mbedtls_x509_crt_init (&CertContext);
if (mbedtls_x509_crt_parse_der (&CertContext, PublicKey, (UINT32)PublicKeySize) != 0) {
goto _Exit;
}
if (mbedtls_pk_get_type (&CertContext.pk) != MBEDTLS_PK_RSA) {
goto _Exit;
}
mbedtls_rsa_init (&RsaContext);
if (mbedtls_rsa_set_padding (&RsaContext, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_NONE) != 0) {
goto _Exit;
}
Ret = mbedtls_rsa_copy (&RsaContext, mbedtls_pk_rsa (CertContext.pk));
if (Ret != 0) {
goto _Exit;
}
*EncryptedDataSize = RsaContext.len;
//
// Allocate a buffer for the output data.
//
OutData = AllocateZeroPool (*EncryptedDataSize);
if (OutData == NULL) {
//
// Fail to allocate the output buffer.
//
goto _Exit;
}
Ret = mbedtls_rsa_pkcs1_encrypt (
&RsaContext,
MbedtlsRand,
NULL,
InDataSize,
InData,
OutData
);
if (Ret != 0) {
FreePool (OutData);
OutData = NULL;
goto _Exit;
}
*EncryptedData = OutData;
Result = TRUE;
_Exit:
//
// Release Resources
//
if (&CertContext != NULL) {
mbedtls_x509_crt_free (&CertContext);
}
if (&RsaContext != NULL) {
mbedtls_rsa_free (&RsaContext);
}
return Result;
}
/**
Encrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the
encrypted message in a newly allocated buffer.
Things that can cause a failure include:
- X509 key size does not match any known key size.
- Fail to allocate an intermediate buffer.
- Null pointer provided for a non-optional parameter.
- Data size is too large for the provided key size (max size is a function of key size
and hash digest size).
@param[in] RsaContext A pointer to an RSA context created by RsaNew() and
provisioned with a public key using RsaSetKey().
@param[in] InData Data to be encrypted.
@param[in] InDataSize Size of the data buffer.
@param[in] PrngSeed [Optional] If provided, a pointer to a random seed buffer
to be used when initializing the PRNG. NULL otherwise.
@param[in] PrngSeedSize [Optional] If provided, size of the random seed buffer.
0 otherwise.
@param[in] DigestLen [Optional] If provided, size of the hash used:
SHA1_DIGEST_SIZE
SHA256_DIGEST_SIZE
SHA384_DIGEST_SIZE
SHA512_DIGEST_SIZE
0 to use default (SHA1)
@param[out] EncryptedData Pointer to an allocated buffer containing the encrypted
message.
@param[out] EncryptedDataSize Size of the encrypted message buffer.
@retval TRUE Encryption was successful.
@retval FALSE Encryption failed.
**/
BOOLEAN
EFIAPI
RsaOaepEncrypt (
IN VOID *RsaContext,
IN UINT8 *InData,
IN UINTN InDataSize,
IN CONST UINT8 *PrngSeed OPTIONAL,
IN UINTN PrngSeedSize OPTIONAL,
IN UINT16 DigestLen OPTIONAL,
OUT UINT8 **EncryptedData,
OUT UINTN *EncryptedDataSize
)
{
ASSERT (FALSE);
return FALSE;
}
/**
Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the
decrypted message in a newly allocated buffer.
Things that can cause a failure include:
- Fail to parse private key.
- Fail to allocate an intermediate buffer.
- Null pointer provided for a non-optional parameter.
@param[in] PrivateKey A pointer to the DER-encoded private key.
@param[in] PrivateKeySize Size of the private key buffer.
@param[in] EncryptedData Data to be decrypted.
@param[in] EncryptedDataSize Size of the encrypted buffer.
@param[out] OutData Pointer to an allocated buffer containing the encrypted
message.
@param[out] OutDataSize Size of the encrypted message buffer.
@retval TRUE Encryption was successful.
@retval FALSE Encryption failed.
**/
BOOLEAN
EFIAPI
Pkcs1v2Decrypt (
IN CONST UINT8 *PrivateKey,
IN UINTN PrivateKeySize,
IN UINT8 *EncryptedData,
IN UINTN EncryptedDataSize,
OUT UINT8 **OutData,
OUT UINTN *OutDataSize
)
{
ASSERT (FALSE);
return FALSE;
}
/**
Decrypts a blob using PKCS1v2 (RSAES-OAEP) schema. On success, will return the
decrypted message in a newly allocated buffer.
Things that can cause a failure include:
- Fail to parse private key.
- Fail to allocate an intermediate buffer.
- Null pointer provided for a non-optional parameter.
@param[in] RsaContext A pointer to an RSA context created by RsaNew() and
provisioned with a private key using RsaSetKey().
@param[in] EncryptedData Data to be decrypted.
@param[in] EncryptedDataSize Size of the encrypted buffer.
@param[in] DigestLen [Optional] If provided, size of the hash used:
SHA1_DIGEST_SIZE
SHA256_DIGEST_SIZE
SHA384_DIGEST_SIZE
SHA512_DIGEST_SIZE
0 to use default (SHA1)
@param[out] OutData Pointer to an allocated buffer containing the encrypted
message.
@param[out] OutDataSize Size of the encrypted message buffer.
@retval TRUE Encryption was successful.
@retval FALSE Encryption failed.
**/
BOOLEAN
EFIAPI
RsaOaepDecrypt (
IN VOID *RsaContext,
IN UINT8 *EncryptedData,
IN UINTN EncryptedDataSize,
IN UINT16 DigestLen OPTIONAL,
OUT UINT8 **OutData,
OUT UINTN *OutDataSize
)
{
ASSERT (FALSE);
return FALSE;
}

View File

@ -0,0 +1,100 @@
/** @file
PBKDF2 Key Derivation Function Wrapper Implementation over MbedTLS.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <mbedtls/pkcs5.h>
/**
Derives a key from a password using a salt and iteration count, based on PKCS#5 v2.0
password based encryption key derivation function PBKDF2, as specified in RFC 2898.
If Password or Salt or OutKey is NULL, then return FALSE.
If the hash algorithm could not be determined, then return FALSE.
@param[in] PasswordLength Length of input password in bytes.
@param[in] Password Pointer to the array for the password.
@param[in] SaltLength Size of the Salt in bytes.
@param[in] Salt Pointer to the Salt.
@param[in] IterationCount Number of iterations to perform. Its value should be
greater than or equal to 1.
@param[in] DigestSize Size of the message digest to be used (eg. SHA256_DIGEST_SIZE).
NOTE: DigestSize will be used to determine the hash algorithm.
Only SHA1_DIGEST_SIZE or SHA256_DIGEST_SIZE is supported.
@param[in] KeyLength Size of the derived key buffer in bytes.
@param[out] OutKey Pointer to the output derived key buffer.
@retval TRUE A key was derived successfully.
@retval FALSE One of the pointers was NULL or one of the sizes was too large.
@retval FALSE The hash algorithm could not be determined from the digest size.
@retval FALSE The key derivation operation failed.
**/
BOOLEAN
EFIAPI
Pkcs5HashPassword (
IN UINTN PasswordLength,
IN CONST CHAR8 *Password,
IN UINTN SaltLength,
IN CONST UINT8 *Salt,
IN UINTN IterationCount,
IN UINTN DigestSize,
IN UINTN KeyLength,
OUT UINT8 *OutKey
)
{
mbedtls_md_type_t HashAlg;
//
// Parameter Checking.
//
if ((Password == NULL) || (Salt == NULL) || (OutKey == NULL)) {
return FALSE;
}
if ((PasswordLength == 0) || (PasswordLength > INT_MAX) ||
(SaltLength == 0) || (SaltLength > INT_MAX) ||
(KeyLength == 0) || (KeyLength > INT_MAX) ||
(IterationCount < 1) || (IterationCount > INT_MAX))
{
return FALSE;
}
//
// Make sure the digest algorithm is supported.
//
switch (DigestSize) {
case SHA1_DIGEST_SIZE:
HashAlg = MBEDTLS_MD_SHA1;
break;
case SHA256_DIGEST_SIZE:
HashAlg = MBEDTLS_MD_SHA256;
break;
default:
return FALSE;
break;
}
//
// Perform password-based key derivation routines.
//
if (mbedtls_pkcs5_pbkdf2_hmac_ext (
HashAlg,
(CONST UINT8 *)Password,
(int)PasswordLength,
(CONST UINT8 *)Salt,
(int)SaltLength,
(int)IterationCount,
(int)KeyLength,
(UINT8 *)OutKey
) != 0)
{
return FALSE;
} else {
return TRUE;
}
}

View File

@ -4,7 +4,7 @@
RFC 2315 - PKCS #7: Cryptographic Message Syntax Version 1.5
Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2023-2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -31,10 +31,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#define MBEDTLS_OID_PKCS7_DIGESTED_DATA MBEDTLS_OID_PKCS7 "\x05"
#define MBEDTLS_OID_PKCS7_ENCRYPTED_DATA MBEDTLS_OID_PKCS7 "\x06"
typedef mbedtls_asn1_buf MBEDTLSPKCS7BUF;
typedef mbedtls_asn1_named_data MBEDTLSPKCS7NAME;
typedef mbedtls_asn1_sequence MBEDTLSPKCS7SEQUENCE;
///
/// PKCS7 SignerInfo type
/// https://tools.ietf.org/html/rfc2315#section-9.2
@ -48,8 +44,8 @@ typedef struct MbedtlsPkcs7SignerInfo {
mbedtls_x509_buf SigAlgIdentifier;
mbedtls_x509_buf AuthAttr;
mbedtls_x509_buf Sig;
struct MBEDTLSPKCS7SIGNERINFO *Next;
} MBEDTLSPKCS7SIGNERINFO;
struct MbedtlsPkcs7SignerInfo *Next;
} MbedtlsPkcs7SignerInfo;
///
/// PKCS7 signed data attached data format
@ -57,7 +53,7 @@ typedef struct MbedtlsPkcs7SignerInfo {
typedef struct MbedtlsPkcs7Data {
mbedtls_asn1_buf Oid;
mbedtls_asn1_buf Data;
} MBEDTLSPKCS7DATA;
} MbedtlsPkcs7Data;
///
/// Signed Data
@ -66,18 +62,27 @@ typedef struct MbedtlsPkcs7Data {
typedef struct MbedtlsPkcs7SignedData {
INT32 Version;
mbedtls_asn1_buf DigestAlgorithms;
struct MBEDTLSPKCS7DATA ContentInfo;
struct MbedtlsPkcs7Data ContentInfo;
mbedtls_x509_crt Certificates;
mbedtls_x509_crl Crls;
struct MbedtlsPkcs7SignerInfo SignerInfos;
} MBEDTLSPKCS7SIGNEDDATA;
} MbedtlsPkcs7SignedData;
///
/// PKCS7 struct, only support SignedData
///
typedef struct MbedtlsPkcs7 {
mbedtls_asn1_buf ContentTypeOid;
struct MBEDTLSPKCS7SIGNEDDATA SignedData;
} MBEDTLSPKCS7;
struct MbedtlsPkcs7SignedData SignedData;
} MbedtlsPkcs7;
#define EDKII_ASN1_CHK_ADD(g, f) \
do \
{ \
if( ( Ret = (f) ) < 0 ) \
return( Ret ); \
else \
(g) += Ret; \
} while( 0 )
#endif

View File

@ -0,0 +1,635 @@
/** @file
PKCS#7 SignedData Sign Wrapper and PKCS#7 SignedData Verification Wrapper
Implementation over mbedtls.
RFC 8422 - Elliptic Curve Cryptography (ECC) Cipher Suites
FIPS 186-4 - Digital Signature Standard (DSS)
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "CryptPkcs7Internal.h"
#include <mbedtls/ecdh.h>
///
/// Enough to store any signature generated by PKCS7
///
#define MAX_SIGNATURE_SIZE 1024
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 MbedtlsOidDigestAlgSha256[] = MBEDTLS_OID_DIGEST_ALG_SHA256;
GLOBAL_REMOVE_IF_UNREFERENCED UINT8 MbedtlsOidPkcs1Rsa[] = MBEDTLS_OID_PKCS1_RSA;
/**
Write DigestAlgorithmIdentifier.
@param[in, out] Ptr The reference to the current position pointer.
@param[in] Start The start of the buffer, for bounds-checking.
@param[in] DigestType Digest Type
@retval number The number of bytes written to p on success.
@retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteDigestAlgorithm (
UINT8 **Ptr,
UINT8 *Start,
mbedtls_md_type_t DigestType
)
{
UINT8 *OidPtr;
UINTN OidLen;
INT32 Ret;
Ret = mbedtls_oid_get_oid_by_md (DigestType, (CONST CHAR8 **)&OidPtr, &OidLen);
if (Ret == 0) {
return mbedtls_asn1_write_oid (Ptr, (CONST UINT8 *)Start, (CONST CHAR8 *)OidPtr, OidLen);
}
return 0;
}
/**
DigestAlgorithmIdentifiers ::=
SET OF DigestAlgorithmIdentifier.
@param[in, out] Ptr The reference to the current position pointer.
@param[in] Start The start of the buffer, for bounds-checking.
@param[in] DigestTypes Digest Type array.
@param[in] Count The index for Digest Type.
@retval number The number of bytes written to p on success.
@retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteDigestAlgorithmSet (
UINT8 **Ptr,
UINT8 *Start,
mbedtls_md_type_t *DigestTypes,
INTN Count
)
{
INTN Idx;
INT32 Len;
INT32 Ret;
Len = 0;
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_null (Ptr, Start));
for (Idx = 0; Idx < Count; Idx++) {
EDKII_ASN1_CHK_ADD (
Len,
MbedTlsPkcs7WriteDigestAlgorithm (Ptr, Start, DigestTypes[Idx])
);
}
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, (UINTN)Len));
EDKII_ASN1_CHK_ADD (
Len,
mbedtls_asn1_write_tag (
Ptr,
Start,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE)
)
);
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, (UINTN)Len));
EDKII_ASN1_CHK_ADD (
Len,
mbedtls_asn1_write_tag (
Ptr,
Start,
(MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET)
)
);
return Len;
}
/**
ContentInfo ::= SEQUENCE {
contentType ContentType,
content
[0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }.
@param[in, out] Ptr The reference to the current position pointer.
@param[in] Start The start of the buffer, for bounds-checking.
@param[in] Content ContentInfo.
@param[in] ContentLen Size of ContentInfo.
@retval number The number of bytes written to p on success.
@retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteContentInfo (
UINT8 **Ptr,
UINT8 *Start,
UINT8 *Content,
INTN ContentLen
)
{
INT32 Ret;
INT32 Len;
Len = 0;
if (Content != NULL) {
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_octet_string (Ptr, Start, Content, ContentLen));
}
EDKII_ASN1_CHK_ADD (
Len,
mbedtls_asn1_write_oid (
Ptr,
Start,
MBEDTLS_OID_PKCS7_DATA,
sizeof (MBEDTLS_OID_PKCS7_DATA) - 1
)
);
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
return Len;
}
/**
certificates :: SET OF ExtendedCertificateOrCertificate,
ExtendedCertificateOrCertificate ::= CHOICE {
certificate Certificate -- x509,
extendedCertificate[0] IMPLICIT ExtendedCertificate }.
@param[in, out] Ptr The reference to the current position pointer.
@param[in] Start The start of the buffer, for bounds-checking.
@param[in] Cert Certificate.
@param[in] OtherCerts Ohter Certificate.
@retval number The number of bytes written to p on success.
@retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteCertificates (
UINT8 **Ptr,
UINT8 *Start,
mbedtls_x509_crt *Cert,
mbedtls_x509_crt *OtherCerts
)
{
INT32 Ret;
INT32 Len;
mbedtls_x509_crt *TmpCert;
Len = 0;
/// Write OtherCerts
TmpCert = OtherCerts;
while (TmpCert != NULL) {
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, TmpCert->raw.p, TmpCert->raw.len));
TmpCert = TmpCert->next;
}
/// Write Cert
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, Cert->raw.p, Cert->raw.len));
/// Write NextContext
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC));
return Len;
}
/**
write Pkcs7 Int.
@param[in, out] Ptr The reference to the current position pointer.
@param[in] Start The start of the buffer, for bounds-checking.
@param[in] SerialRaw SerialRaw.
@param[in] SerialRawLen Size of SerialRaw.
@retval number The number of bytes written to p on success.
@retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteInt (
UINT8 **Ptr,
UINT8 *Start,
UINT8 *SerialRaw,
INTN SerialRawLen
)
{
INT32 Ret;
UINT8 *Pt;
INT32 Len;
Len = 0;
Pt = SerialRaw + SerialRawLen;
while (Pt > SerialRaw) {
*--(*Ptr) = *--Pt;
Len++;
}
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_INTEGER));
return Len;
}
/**
write Pkcs7 Issuer And SerialNumber.
@param[in, out] Ptr The reference to the current position pointer.
@param[in] Start The start of the buffer, for bounds-checking.
@param[in] Serial Serial.
@param[in] SerialLen Size of Serial.
@param[in] IssuerRaw IssuerRawLen.
@param[in] IssuerRawLen Size of IssuerRawLen.
@retval number The number of bytes written to p on success.
@retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteIssuerAndSerialNumber (
UINT8 **Ptr,
UINT8 *Start,
UINT8 *Serial,
INTN SerialLen,
UINT8 *IssuerRaw,
INTN IssuerRawLen
)
{
INT32 Ret;
INT32 Len;
Len = 0;
EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteInt (Ptr, Start, Serial, SerialLen));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_raw_buffer (Ptr, Start, IssuerRaw, IssuerRawLen));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
return Len;
}
/**
SignerInfo ::= SEQUENCE {
version Version;
issuerAndSerialNumber IssuerAndSerialNumber,
digestAlgorithm DigestAlgorithmIdentifier,
authenticatedAttributes
[0] IMPLICIT Attributes OPTIONAL,
digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
encryptedDigest EncryptedDigest,
unauthenticatedAttributes
[1] IMPLICIT Attributes OPTIONAL.
@param[in, out] Ptr The reference to the current position pointer.
@param[in] Start The start of the buffer, for bounds-checking.
@param[in] SignerInfo SignerInfo.
@retval number The number of bytes written to p on success.
@retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteSignerInfo (
UINT8 **Ptr,
UINT8 *Start,
MbedtlsPkcs7SignerInfo *SignerInfo
)
{
INT32 Ret;
INT32 Len;
Len = 0;
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_octet_string (Ptr, Start, SignerInfo->Sig.p, SignerInfo->Sig.len));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_algorithm_identifier (Ptr, Start, (CONST CHAR8 *)SignerInfo->SigAlgIdentifier.p, SignerInfo->SigAlgIdentifier.len, 0));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_algorithm_identifier (Ptr, Start, (CONST CHAR8 *)SignerInfo->AlgIdentifier.p, SignerInfo->AlgIdentifier.len, 0));
EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteIssuerAndSerialNumber (Ptr, Start, SignerInfo->Serial.p, SignerInfo->Serial.len, SignerInfo->IssuerRaw.p, SignerInfo->IssuerRaw.len));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_int (Ptr, Start, SignerInfo->Version));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
return Len;
}
/**
write Pkcs7 Signers Info Set.
@param[in, out] Ptr The reference to the current position pointer.
@param[in] Start The start of the buffer, for bounds-checking.
@param[in] SignersSet SignerInfo Set.
@retval number The number of bytes written to p on success.
@retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteSignersInfoSet (
UINT8 **Ptr,
UINT8 *Start,
MbedtlsPkcs7SignerInfo *SignersSet
)
{
MbedtlsPkcs7SignerInfo *SignerInfo;
INT32 Ret;
INT32 Len;
SignerInfo = SignersSet;
Len = 0;
while (SignerInfo != NULL) {
EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteSignerInfo (Ptr, Start, SignerInfo));
// move to next
SignerInfo = SignerInfo->Next;
}
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET));
return Len;
}
/**
Signed Data Type
SignedData ::= SEQUENCE {
version Version,
digestAlgorithms DigestAlgorithmIdentifiers,
contentInfo ContentInfo,
certificates
[0] IMPLICIT ExtendedCertificatesAndCertificates
OPTIONAL,
crls
[1] IMPLICIT CertificateRevocationLists OPTIONAL,
signerInfos SignerInfos }
DigestAlgorithmIdentifiers ::=
SET OF DigestAlgorithmIdentifier
SignerInfos ::= SET OF SignerInfo.
@param[in, out] Ptr The reference to the current position pointer.
@param[in] Start The start of the buffer, for bounds-checking.
@param[in] Pkcs7 MbedtlsPkcs7
@retval number The number of bytes written to p on success.
@retval negative A negative MBEDTLS_ERR_ASN1_XXX error code on failure.
**/
STATIC
INT32
MbedTlsPkcs7WriteDer (
UINT8 **Ptr,
UINT8 *Start,
MbedtlsPkcs7 *Pkcs7
)
{
INT32 Ret;
INT32 Len;
mbedtls_md_type_t DigestAlg[1];
DigestAlg[0] = MBEDTLS_MD_SHA256;
Len = 0;
EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteSignersInfoSet (Ptr, Start, &(Pkcs7->SignedData.SignerInfos)));
EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteCertificates (Ptr, Start, &(Pkcs7->SignedData.Certificates), Pkcs7->SignedData.Certificates.next));
EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteContentInfo (Ptr, Start, NULL, 0));
EDKII_ASN1_CHK_ADD (Len, MbedTlsPkcs7WriteDigestAlgorithmSet (Ptr, Start, DigestAlg, 1));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_int (Ptr, Start, Pkcs7->SignedData.Version));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_len (Ptr, Start, Len));
EDKII_ASN1_CHK_ADD (Len, mbedtls_asn1_write_tag (Ptr, Start, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE));
return Len;
}
/**
Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message
Syntax Standard, version 1.5". This interface is only intended to be used for
application to perform PKCS#7 functionality validation.
If this interface is not supported, then return FALSE.
@param[in] PrivateKey Pointer to the PEM-formatted private key data for
data signing.
@param[in] PrivateKeySize Size of the PEM private key data in bytes.
@param[in] KeyPassword NULL-terminated passphrase used for encrypted PEM
key data.
@param[in] InData Pointer to the content to be signed.
@param[in] InDataSize Size of InData in bytes.
@param[in] SignCert Pointer to signer's DER-encoded certificate to sign with.
@param[in] OtherCerts Pointer to an optional additional set of certificates to
include in the PKCS#7 signedData (e.g. any intermediate
CAs in the chain).
@param[out] SignedData Pointer to output PKCS#7 signedData. It's caller's
responsibility to free the buffer with FreePool().
@param[out] SignedDataSize Size of SignedData in bytes.
@retval TRUE PKCS#7 data signing succeeded.
@retval FALSE PKCS#7 data signing failed.
@retval FALSE This interface is not supported.
**/
BOOLEAN
EFIAPI
Pkcs7Sign (
IN CONST UINT8 *PrivateKey,
IN UINTN PrivateKeySize,
IN CONST UINT8 *KeyPassword,
IN UINT8 *InData,
IN UINTN InDataSize,
IN UINT8 *SignCert,
IN UINT8 *OtherCerts OPTIONAL,
OUT UINT8 **SignedData,
OUT UINTN *SignedDataSize
)
{
BOOLEAN Status;
INT32 Ret;
mbedtls_pk_context Pkey;
UINT8 HashValue[SHA256_DIGEST_SIZE];
UINT8 Signature[MAX_SIGNATURE_SIZE];
UINTN SignatureLen;
UINT8 *NewPrivateKey;
mbedtls_x509_crt *Crt;
MbedtlsPkcs7 Pkcs7;
MbedtlsPkcs7SignerInfo SignerInfo;
UINT8 *Buffer;
INTN BufferSize;
UINT8 *Ptr;
INT32 Len;
//
// Check input parameters.
//
if ((PrivateKey == NULL) || (KeyPassword == NULL) || (InData == NULL) ||
(SignCert == NULL) || (SignedData == NULL) || (SignedDataSize == NULL) || (InDataSize > INT_MAX))
{
return FALSE;
}
BufferSize = 4096;
SignatureLen = MAX_SIGNATURE_SIZE;
Crt = (mbedtls_x509_crt *)SignCert;
NewPrivateKey = NULL;
if (PrivateKey[PrivateKeySize - 1] != 0) {
NewPrivateKey = AllocateZeroPool (PrivateKeySize + 1);
if (NewPrivateKey == NULL) {
return FALSE;
}
CopyMem (NewPrivateKey, PrivateKey, PrivateKeySize);
NewPrivateKey[PrivateKeySize] = 0;
PrivateKeySize++;
} else {
NewPrivateKey = AllocateZeroPool (PrivateKeySize);
if (NewPrivateKey == NULL) {
return FALSE;
}
CopyMem (NewPrivateKey, PrivateKey, PrivateKeySize);
}
mbedtls_pk_init (&Pkey);
Ret = mbedtls_pk_parse_key (
&Pkey,
NewPrivateKey,
PrivateKeySize,
KeyPassword,
KeyPassword == NULL ? 0 : AsciiStrLen ((CONST CHAR8 *)KeyPassword),
NULL,
NULL
);
if (Ret != 0) {
Status = FALSE;
goto Cleanup;
}
/// Calculate InData Digest
ZeroMem (HashValue, SHA256_DIGEST_SIZE);
Status = Sha256HashAll (InData, InDataSize, HashValue);
if (!Status) {
goto Cleanup;
}
/// Pk Sign
ZeroMem (Signature, MAX_SIGNATURE_SIZE);
Ret = mbedtls_pk_sign (
&Pkey,
MBEDTLS_MD_SHA256,
HashValue,
SHA256_DIGEST_SIZE,
Signature,
MAX_SIGNATURE_SIZE,
&SignatureLen,
MbedtlsRand,
NULL
);
if (Ret != 0) {
Status = FALSE;
goto Cleanup;
}
ZeroMem (&Pkcs7, sizeof (MbedtlsPkcs7));
Pkcs7.SignedData.Version = 1;
Crt->next = (mbedtls_x509_crt *)OtherCerts;
Pkcs7.SignedData.Certificates = *Crt;
SignerInfo.Next = NULL;
SignerInfo.Sig.p = Signature;
SignerInfo.Sig.len = SignatureLen;
SignerInfo.Version = 1;
SignerInfo.AlgIdentifier.p = MbedtlsOidDigestAlgSha256;
SignerInfo.AlgIdentifier.len = sizeof (MBEDTLS_OID_DIGEST_ALG_SHA256) - 1;
if (mbedtls_pk_get_type (&Pkey) == MBEDTLS_PK_RSA) {
SignerInfo.SigAlgIdentifier.p = MbedtlsOidPkcs1Rsa;
SignerInfo.SigAlgIdentifier.len = sizeof (MBEDTLS_OID_PKCS1_RSA) - 1;
} else {
Ret = mbedtls_oid_get_oid_by_sig_alg (MBEDTLS_PK_ECDSA, MBEDTLS_MD_SHA256, (CONST CHAR8 **)&SignerInfo.SigAlgIdentifier.p, &SignerInfo.SigAlgIdentifier.len);
if (Ret != 0) {
Status = FALSE;
goto Cleanup;
}
}
SignerInfo.Serial = ((mbedtls_x509_crt *)SignCert)->serial;
SignerInfo.IssuerRaw = ((mbedtls_x509_crt *)SignCert)->issuer_raw;
Pkcs7.SignedData.SignerInfos = SignerInfo;
Buffer = AllocateZeroPool (BufferSize);
if (Buffer == NULL) {
Status = FALSE;
goto Cleanup;
}
Ptr = Buffer + BufferSize;
Len = MbedTlsPkcs7WriteDer (&Ptr, Buffer, &Pkcs7);
/// Enlarge buffer if buffer is too small
while (Len == MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) {
BufferSize = BufferSize * 2;
Ptr = Buffer + BufferSize;
FreePool (Buffer);
Buffer = AllocateZeroPool (BufferSize);
if (Buffer == NULL) {
Status = FALSE;
goto Cleanup;
}
Ptr = Buffer + BufferSize;
Len = MbedTlsPkcs7WriteDer (&Ptr, Buffer, &Pkcs7);
}
if (Len <= 0) {
Status = FALSE;
goto Cleanup;
}
*SignedData = AllocateZeroPool (Len);
if (*SignedData == NULL) {
Status = FALSE;
goto Cleanup;
}
*SignedDataSize = Len;
CopyMem (*SignedData, Ptr, Len);
Status = TRUE;
Cleanup:
if (&Pkey != NULL) {
mbedtls_pk_free (&Pkey);
}
if (NewPrivateKey != NULL) {
memset (NewPrivateKey, 0, PrivateKeySize);
FreePool (NewPrivateKey);
}
if (Buffer != NULL) {
memset (Buffer, 0, BufferSize);
FreePool (Buffer);
}
return Status;
}

View File

@ -0,0 +1,113 @@
/** @file
Non-runtime specific implementation of PKCS#7 SignedData Verification Wrapper.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <mbedtls/pkcs7.h>
/**
Extracts the attached content from a PKCS#7 signed data if existed. The input signed
data could be wrapped in a ContentInfo structure.
If P7Data, Content, or ContentSize is NULL, then return FALSE. If P7Length overflow,
then return FALSE. If the P7Data is not correctly formatted, then return FALSE.
Caution: This function may receive untrusted input. So this function will do
basic check for PKCS#7 data structure.
@param[in] P7Data Pointer to the PKCS#7 signed data to process.
@param[in] P7Length Length of the PKCS#7 signed data in bytes.
@param[out] Content Pointer to the extracted content from the PKCS#7 signedData.
It's caller's responsibility to free the buffer with FreePool().
@param[out] ContentSize The size of the extracted content in bytes.
@retval TRUE The P7Data was correctly formatted for processing.
@retval FALSE The P7Data was not correctly formatted for processing.
**/
BOOLEAN
EFIAPI
Pkcs7GetAttachedContent (
IN CONST UINT8 *P7Data,
IN UINTN P7Length,
OUT VOID **Content,
OUT UINTN *ContentSize
)
{
BOOLEAN Status;
UINT8 *SignedData;
UINTN SignedDataSize;
BOOLEAN Wrapped;
INTN Ret;
mbedtls_pkcs7 Pkcs7;
mbedtls_pkcs7_data *MbedtlsContent;
mbedtls_pkcs7_init (&Pkcs7);
//
// Check input parameter.
//
if ((P7Data == NULL) || (P7Length > INT_MAX) || (Content == NULL) || (ContentSize == NULL)) {
return FALSE;
}
*Content = NULL;
SignedData = NULL;
Status = WrapPkcs7Data (P7Data, P7Length, &Wrapped, &SignedData, &SignedDataSize);
if (!Status || (SignedDataSize > INT_MAX)) {
goto _Exit;
}
Status = FALSE;
Ret = mbedtls_pkcs7_parse_der (&Pkcs7, SignedData, (INT32)SignedDataSize);
//
// The type of Pkcs7 must be signedData
//
if (Ret != MBEDTLS_PKCS7_SIGNED_DATA) {
goto _Exit;
}
//
// Check for detached or attached content
//
MbedtlsContent = &(Pkcs7.signed_data.content);
if (MbedtlsContent == NULL) {
//
// No Content supplied for PKCS7 detached signedData
//
*Content = NULL;
*ContentSize = 0;
} else {
//
// Retrieve the attached content in PKCS7 signedData
//
if ((MbedtlsContent->data.len > 0) && (MbedtlsContent->data.p != NULL)) {
*ContentSize = MbedtlsContent->data.len;
*Content = AllocateZeroPool (*ContentSize);
if (*Content == NULL) {
*ContentSize = 0;
goto _Exit;
}
CopyMem (*Content, MbedtlsContent->data.p, *ContentSize);
}
}
Status = TRUE;
_Exit:
//
// Release Resources
//
mbedtls_pkcs7_free (&Pkcs7);
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,689 @@
/** @file
This module verifies that Enhanced Key Usages (EKU's) are present within
a PKCS7 signature blob using MbedTLS.
Copyright (C) Microsoft Corporation. All Rights Reserved.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <Base.h>
#include "InternalCryptLib.h"
#include <mbedtls/pkcs7.h>
#include <mbedtls/asn1write.h>
GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 EkuOID[] = { 0x55, 0x1D, 0x25 };
/*leaf Cert basic_constraints case1: CA: false and CA object is excluded */
GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 gBasicConstraintsCase1[] = { 0x30, 0x00 };
/*leaf Cert basic_constraints case2: CA: false */
GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 gBasicConstraintsCase2[] = { 0x30, 0x06, 0x01, 0x01, 0xFF, 0x02, 0x01, 0x00 };
GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 gOidBasicConstraints[] = { 0x55, 0x1D, 0x13 };
/**
Find first Extension data match with given OID
@param[in] Start Pointer to the DER-encoded extensions data
@param[in] End extensions data size in bytes
@param[in ] Oid OID for match
@param[in ] OidSize OID size in bytes
@param[out] FindExtensionData output matched extension data.
@param[out] FindExtensionDataLen matched extension data size.
**/
STATIC
BOOLEAN
InternalX509FindExtensionData (
UINT8 *Start,
UINT8 *End,
CONST UINT8 *Oid,
UINTN OidSize,
UINT8 **FindExtensionData,
UINTN *FindExtensionDataLen
)
{
UINT8 *Ptr;
UINT8 *ExtensionPtr;
UINTN ObjLen;
INT32 Ret;
BOOLEAN Status;
UINTN FindExtensionLen;
UINTN HeaderLen;
/*If no Extension entry match Oid*/
Status = FALSE;
Ptr = Start;
Ret = 0;
while (TRUE) {
//
// Extension ::= SEQUENCE {
// extnID OBJECT IDENTIFIER,
// critical BOOLEAN DEFAULT FALSE,
// extnValue OCTET STRING }
//
ExtensionPtr = Ptr;
Ret = mbedtls_asn1_get_tag (
&Ptr,
End,
&ObjLen,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE
);
if (Ret == 0) {
HeaderLen = (UINTN)(Ptr - ExtensionPtr);
FindExtensionLen = ObjLen;
/* Get Object Identifier*/
Ret = mbedtls_asn1_get_tag (
&Ptr,
End,
&ObjLen,
MBEDTLS_ASN1_OID
);
} else {
break;
}
if ((Ret == 0) && !CompareMem (Ptr, Oid, OidSize)) {
Ptr += ObjLen;
Ret = mbedtls_asn1_get_tag (
&Ptr,
End,
&ObjLen,
MBEDTLS_ASN1_BOOLEAN
);
if (Ret == 0) {
Ptr += ObjLen;
}
Ret = mbedtls_asn1_get_tag (
&Ptr,
End,
&ObjLen,
MBEDTLS_ASN1_OCTET_STRING
);
} else {
Ret = 1;
}
if (Ret == 0) {
*FindExtensionData = Ptr;
*FindExtensionDataLen = ObjLen;
Status = TRUE;
break;
}
/* move to next*/
Ptr = ExtensionPtr + HeaderLen + FindExtensionLen;
Ret = 0;
}
return Status;
}
/**
Retrieve Extension data from one X.509 certificate.
@param[in] Cert Pointer to the X509 certificate.
@param[in] Oid Object identifier buffer
@param[in] OidSize Object identifier buffer size
@param[out] ExtensionData Extension bytes.
@param[in, out] ExtensionDataSize Extension bytes size.
@retval RETURN_SUCCESS The certificate Extension data retrieved successfully.
@retval RETURN_INVALID_PARAMETER If Cert is NULL.
If ExtensionDataSize is NULL.
If ExtensionData is not NULL and *ExtensionDataSize is 0.
If Certificate is invalid.
@retval RETURN_NOT_FOUND If no Extension entry match Oid.
@retval RETURN_BUFFER_TOO_SMALL If the ExtensionData is NULL. The required buffer size
is returned in the ExtensionDataSize parameter.
@retval RETURN_UNSUPPORTED The operation is not supported.
**/
STATIC
BOOLEAN
GetExtensionData (
CONST mbedtls_x509_crt *Cert,
CONST UINT8 *Oid,
UINTN OidSize,
UINT8 *ExtensionData,
UINTN *ExtensionDataSize
)
{
CONST mbedtls_x509_crt *Crt;
INT32 Ret;
BOOLEAN Status;
UINT8 *Ptr;
UINT8 *End;
UINTN ObjLen;
Ptr = NULL;
End = NULL;
ObjLen = 0;
if ((Cert == NULL) || (Oid == NULL) || (OidSize == 0) ||
(ExtensionDataSize == NULL))
{
return FALSE;
}
Status = FALSE;
Crt = Cert;
Ptr = Crt->v3_ext.p;
End = Crt->v3_ext.p + Crt->v3_ext.len;
Ret = mbedtls_asn1_get_tag (
&Ptr,
End,
&ObjLen,
MBEDTLS_ASN1_CONSTRUCTED |
MBEDTLS_ASN1_SEQUENCE
);
if (Ret == 0) {
Status = InternalX509FindExtensionData (
Ptr,
End,
Oid,
OidSize,
&Ptr,
&ObjLen
);
}
if (Status) {
if (*ExtensionDataSize < ObjLen) {
*ExtensionDataSize = ObjLen;
Status = FALSE;
goto Cleanup;
}
if (Oid != NULL) {
if (ExtensionData == NULL) {
return FALSE;
}
CopyMem (ExtensionData, Ptr, ObjLen);
}
*ExtensionDataSize = ObjLen;
} else {
*ExtensionDataSize = 0;
}
Cleanup:
return Status;
}
/**
Determines if the specified EKU represented in ASN1 form is present
in a given certificate.
@param[in] Cert The certificate to check.
@param[in] EKU The EKU to look for.
@param[in] EkuLen The size of EKU.
@retval EFI_SUCCESS We successfully identified the signing type.
@retval EFI_INVALID_PARAMETER A parameter was invalid.
@retval EFI_NOT_FOUND One or more EKU's were not found in the signature.
**/
STATIC
EFI_STATUS
IsEkuInCertificate (
IN CONST mbedtls_x509_crt *Cert,
IN UINT8 *EKU,
IN UINTN EkuLen
)
{
EFI_STATUS Status;
BOOLEAN Ret;
UINT8 *Buffer;
UINTN Index;
UINTN Len;
if ((Cert == NULL) || (EKU == NULL)) {
Status = EFI_INVALID_PARAMETER;
return Status;
}
Len = 0;
Buffer = NULL;
Ret = GetExtensionData (
Cert,
(CONST UINT8 *)EkuOID,
sizeof (EkuOID),
NULL,
&Len
);
if (Len == 0) {
Status = EFI_NOT_FOUND;
goto Exit;
}
Buffer = AllocateZeroPool (Len);
if (Buffer == NULL) {
Status = EFI_NOT_FOUND;
goto Exit;
}
Ret = GetExtensionData (
Cert,
(CONST UINT8 *)EkuOID,
sizeof (EkuOID),
Buffer,
&Len
);
if ((Len == 0) || (!Ret)) {
Status = EFI_NOT_FOUND;
goto Exit;
}
Status = EFI_NOT_FOUND;
/*find the spdm hardware identity OID*/
for (Index = 0; Index <= Len - EkuLen; Index++) {
if (!CompareMem (Buffer + Index, EKU, EkuLen)) {
// check sub EKU
if (Index == Len - EkuLen) {
Status = EFI_SUCCESS;
break;
// Ensure that the OID is complete
} else if (Buffer[Index + EkuLen] == 0x06) {
Status = EFI_SUCCESS;
break;
} else {
break;
}
}
}
Exit:
if (Buffer != NULL) {
FreePool (Buffer);
}
return Status;
}
/**
Get OID from txt.
@param[in] RequiredEKUs Array of null-terminated strings listing OIDs of
required EKUs that must be present in the signature.
@param[in] RequiredEKUsSize Number of elements in the RequiredEKUs string array.
@param[in,out] CheckOid OID.
@param[out] OidLen The size of OID.
**/
VOID
GetOidFromTxt (
IN CONST CHAR8 *RequiredEKUs,
IN UINTN RequiredEKUsSize,
IN OUT UINT8 *CheckOid,
OUT UINT8 *OidLen
)
{
UINT8 *Ptr;
UINT16 Index;
UINT32 Data;
UINT8 OidIndex;
UINTN EKUsSize;
EKUsSize = RequiredEKUsSize;
// https://learn.microsoft.com/en-us/windows/win32/seccertenroll/about-object-identifier?redirectedfrom=MSDN
CheckOid[0] = (UINT8)((RequiredEKUs[0] - '0') * 40 + (RequiredEKUs[2] - '0'));
EKUsSize = EKUsSize - 4;
Ptr = (UINT8 *)(RequiredEKUs + 4);
OidIndex = 1;
while (EKUsSize) {
Index = 0;
Data = 0;
while ((*Ptr != '.') && (*Ptr != '\0')) {
Index++;
Ptr++;
EKUsSize--;
}
while (Index) {
Data = 10 * Data + (*(Ptr - Index) - '0');
Index--;
}
if (EKUsSize != 0) {
Ptr++;
EKUsSize--;
}
if (Data < 128) {
CheckOid[OidIndex] = (UINT8)Data;
OidIndex++;
} else {
CheckOid[OidIndex + 1] = (UINT8)(Data & 0xFF);
CheckOid[OidIndex] = (UINT8)(((((Data & 0xFF00) << 1) | 0x8000) >> 8) & 0xFF);
OidIndex = OidIndex + 2;
}
}
*OidLen = OidIndex;
}
/**
Verify the Cert is signer cert
@param[in] Start Pointer to the DER-encoded certificate data Start.
@param[in] End Pointer to the DER-encoded certificate data End.
@retval true verify pass
@retval false verify fail
**/
STATIC
BOOLEAN
IsCertSignerCert (
UINT8 *Start,
UINT8 *End
)
{
BOOLEAN Status;
UINT8 *Buffer;
UINTN Len;
mbedtls_x509_crt Cert;
UINTN ObjLen;
mbedtls_x509_crt_init (&Cert);
ObjLen = End - Start;
if (mbedtls_x509_crt_parse_der (&Cert, Start, ObjLen) != 0) {
return FALSE;
}
Len = 0;
Buffer = NULL;
Status = GetExtensionData (
&Cert,
(CONST UINT8 *)gOidBasicConstraints,
sizeof (gOidBasicConstraints),
NULL,
&Len
);
if (Len == 0) {
/* basic constraints is not present in Cert */
return TRUE;
}
Buffer = AllocateZeroPool (Len);
if (Buffer == NULL) {
return FALSE;
}
Status = GetExtensionData (
&Cert,
(CONST UINT8 *)gOidBasicConstraints,
sizeof (gOidBasicConstraints),
Buffer,
&Len
);
if (Len == 0) {
/* basic constraints is not present in Cert */
Status = TRUE;
goto Exit;
} else if (!Status) {
Status = FALSE;
goto Exit;
}
if ((Len == sizeof (gBasicConstraintsCase1)) &&
(!CompareMem (Buffer, gBasicConstraintsCase1, sizeof (gBasicConstraintsCase1))))
{
Status = TRUE;
goto Exit;
}
if ((Len == sizeof (gBasicConstraintsCase2)) &&
(!CompareMem (Buffer, gBasicConstraintsCase2, sizeof (gBasicConstraintsCase2))))
{
Status = TRUE;
goto Exit;
}
Status = FALSE;
Exit:
mbedtls_x509_crt_free (&Cert);
if (Buffer != NULL) {
FreePool (Buffer);
}
return Status;
}
/**
Determines if the specified EKUs are present in a signing certificate.
@param[in] SignerCert The certificate to check.
@param[in] RequiredEKUs The EKUs to look for.
@param[in] RequiredEKUsSize The number of EKUs
@param[in] RequireAllPresent If TRUE, then all the specified EKUs
must be present in the certificate.
@retval EFI_SUCCESS We successfully identified the signing type.
@retval EFI_INVALID_PARAMETER A parameter was invalid.
@retval EFI_NOT_FOUND One or more EKU's were not found in the signature.
**/
STATIC
EFI_STATUS
CheckEKUs (
IN CONST mbedtls_x509_crt *SignerCert,
IN CONST CHAR8 *RequiredEKUs[],
IN CONST UINT32 RequiredEKUsSize,
IN BOOLEAN RequireAllPresent
)
{
EFI_STATUS Status;
UINT32 NumEkusFound;
UINT32 Index;
UINT8 *EKU;
UINTN EkuLen;
UINT8 CheckOid[20];
UINT8 OidLen;
Status = EFI_SUCCESS;
NumEkusFound = 0;
if ((SignerCert == NULL) || (RequiredEKUs == NULL) || (RequiredEKUsSize == 0)) {
Status = EFI_INVALID_PARAMETER;
goto Exit;
}
for (Index = 0; Index < RequiredEKUsSize; Index++) {
//
// Finding required EKU in Cert.
//
GetOidFromTxt (RequiredEKUs[Index], strlen (RequiredEKUs[Index]), CheckOid, &OidLen);
EKU = CheckOid;
EkuLen = OidLen;
Status = IsEkuInCertificate (SignerCert, EKU, EkuLen);
if (Status == EFI_SUCCESS) {
NumEkusFound++;
if (!RequireAllPresent) {
//
// Found at least one, so we are done.
//
goto Exit;
}
} else {
//
// Fail to find Eku in Cert
break;
}
}
Exit:
if (RequireAllPresent &&
(NumEkusFound == RequiredEKUsSize))
{
//
// Found all required EKUs in certificate.
//
Status = EFI_SUCCESS;
}
return Status;
}
/**
This function receives a PKCS#7 formatted signature blob,
looks for the EKU SEQUENCE blob, and if found then looks
for all the required EKUs. This function was created so that
the Surface team can cut down on the number of Certificate
Authorities (CA's) by checking EKU's on leaf signers for
a specific product. This prevents one product's certificate
from signing another product's firmware or unlock blobs.
Note that this function does not validate the certificate chain.
That needs to be done before using this function.
@param[in] Pkcs7Signature The PKCS#7 signed information content block. An array
containing the content block with both the signature,
the signer's certificate, and any necessary intermediate
certificates.
@param[in] Pkcs7SignatureSize Number of bytes in Pkcs7Signature.
@param[in] RequiredEKUs Array of null-terminated strings listing OIDs of
required EKUs that must be present in the signature.
@param[in] RequiredEKUsSize Number of elements in the RequiredEKUs string array.
@param[in] RequireAllPresent If this is TRUE, then all of the specified EKU's
must be present in the leaf signer. If it is
FALSE, then we will succeed if we find any
of the specified EKU's.
@retval EFI_SUCCESS The required EKUs were found in the signature.
@retval EFI_INVALID_PARAMETER A parameter was invalid.
@retval EFI_NOT_FOUND One or more EKU's were not found in the signature.
**/
EFI_STATUS
EFIAPI
VerifyEKUsInPkcs7Signature (
IN CONST UINT8 *Pkcs7Signature,
IN CONST UINT32 SignatureSize,
IN CONST CHAR8 *RequiredEKUs[],
IN CONST UINT32 RequiredEKUsSize,
IN BOOLEAN RequireAllPresent
)
{
EFI_STATUS Status;
mbedtls_x509_crt Cert;
UINT8 *Ptr;
UINT8 *End;
INT32 Len;
UINTN ObjLen;
UINT8 *OldEnd;
//
// Check input parameter.
//
if ((RequiredEKUs == NULL) || (Pkcs7Signature == NULL)) {
Status = EFI_INVALID_PARAMETER;
return Status;
}
mbedtls_x509_crt_init (&Cert);
Ptr = (UINT8 *)(UINTN)Pkcs7Signature;
Len = (UINT32)SignatureSize;
End = Ptr + Len;
// Cert
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// tbscert
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
return FALSE;
}
Ptr += ObjLen;
// signature algo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
return FALSE;
}
Ptr += ObjLen;
// signature
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
Ptr += ObjLen;
OldEnd = Ptr;
// Cert
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
return FALSE;
}
End = Ptr + ObjLen;
// leaf Cert
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
Ptr += ObjLen;
while ((Ptr != End) && (Ptr < End)) {
if (IsCertSignerCert (OldEnd, Ptr)) {
break;
}
OldEnd = Ptr;
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
Ptr += ObjLen;
}
if (Ptr != End) {
return FALSE;
} else {
Ptr = End - ObjLen;
}
// leaf Cert
ObjLen += Ptr - OldEnd;
Ptr = OldEnd;
if (mbedtls_x509_crt_parse_der (&Cert, Ptr, ObjLen) != 0) {
return FALSE;
}
Status = CheckEKUs (&Cert, RequiredEKUs, RequiredEKUsSize, RequireAllPresent);
if (Status != EFI_SUCCESS) {
goto Exit;
}
Exit:
//
// Release Resources
//
mbedtls_x509_crt_free (&Cert);
return Status;
}

View File

@ -0,0 +1,352 @@
/** @file
RSA Asymmetric Cipher Wrapper Implementation over MbedTLS.
This file implements following APIs which provide more capabilities for RSA:
1) RsaGetKey
2) RsaGenerateKey
3) RsaCheckKey
4) RsaPkcs1Sign
RFC 8017 - PKCS #1: RSA Cryptography Specifications Version 2.2
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <mbedtls/rsa.h>
/**
Gets the tag-designated RSA key component from the established RSA context.
This function retrieves the tag-designated RSA key component from the
established RSA context as a non-negative integer (octet string format
represented in RSA PKCS#1).
If specified key component has not been set or has been cleared, then returned
BnSize is set to 0.
If the BigNumber buffer is too small to hold the contents of the key, FALSE
is returned and BnSize is set to the required buffer size to obtain the key.
If RsaContext is NULL, then return FALSE.
If BnSize is NULL, then return FALSE.
If BnSize is large enough but BigNumber is NULL, then return FALSE.
@param[in, out] RsaContext Pointer to RSA context being set.
@param[in] KeyTag Tag of RSA key component being set.
@param[out] BigNumber Pointer to octet integer buffer.
@param[in, out] BnSize On input, the size of big number buffer in bytes.
On output, the size of data returned in big number buffer in bytes.
@retval TRUE RSA key component was retrieved successfully.
@retval FALSE Invalid RSA key component tag.
@retval FALSE BnSize is too small.
**/
BOOLEAN
EFIAPI
RsaGetKey (
IN OUT VOID *RsaContext,
IN RSA_KEY_TAG KeyTag,
OUT UINT8 *BigNumber,
IN OUT UINTN *BnSize
)
{
mbedtls_rsa_context *RsaKey;
INT32 Ret;
mbedtls_mpi Value;
UINTN Size;
//
// Check input parameters.
//
if ((RsaContext == NULL) || (*BnSize > INT_MAX)) {
return FALSE;
}
//
// Init mbedtls_mpi
//
mbedtls_mpi_init (&Value);
Size = *BnSize;
*BnSize = 0;
RsaKey = (mbedtls_rsa_context *)RsaContext;
switch (KeyTag) {
case RsaKeyN:
Ret = mbedtls_rsa_export (RsaKey, &Value, NULL, NULL, NULL, NULL);
break;
case RsaKeyE:
Ret = mbedtls_rsa_export (RsaKey, NULL, NULL, NULL, NULL, &Value);
break;
case RsaKeyD:
Ret = mbedtls_rsa_export (RsaKey, NULL, NULL, NULL, &Value, NULL);
break;
case RsaKeyQ:
Ret = mbedtls_rsa_export (RsaKey, NULL, NULL, &Value, NULL, NULL);
break;
case RsaKeyP:
Ret = mbedtls_rsa_export (RsaKey, NULL, &Value, NULL, NULL, NULL);
break;
case RsaKeyDp:
case RsaKeyDq:
case RsaKeyQInv:
default:
Ret = -1;
break;
}
if (Ret != 0) {
goto End;
}
if (mbedtls_mpi_size (&Value) == 0) {
Ret = 0;
goto End;
}
*BnSize = Size;
Size = mbedtls_mpi_size (&Value);
if (*BnSize < Size) {
Ret = 1;
*BnSize = Size;
goto End;
}
if (BigNumber == NULL) {
Ret = 0;
*BnSize = Size;
goto End;
}
if ((BigNumber != NULL) && (Ret == 0)) {
Ret = mbedtls_mpi_write_binary (&Value, BigNumber, Size);
*BnSize = Size;
}
End:
mbedtls_mpi_free (&Value);
return Ret == 0;
}
/**
Generates RSA key components.
This function generates RSA key components. It takes RSA public exponent Pe and
length in bits of RSA modulus N as input, and generates all key components.
If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used.
Before this function can be invoked, pseudorandom number generator must be correctly
initialized by RandomSeed().
If RsaContext is NULL, then return FALSE.
@param[in, out] RsaContext Pointer to RSA context being set.
@param[in] ModulusLength Length of RSA modulus N in bits.
@param[in] PublicExponent Pointer to RSA public exponent.
@param[in] PublicExponentSize Size of RSA public exponent buffer in bytes.
@retval TRUE RSA key component was generated successfully.
@retval FALSE Invalid RSA key component tag.
**/
BOOLEAN
EFIAPI
RsaGenerateKey (
IN OUT VOID *RsaContext,
IN UINTN ModulusLength,
IN CONST UINT8 *PublicExponent,
IN UINTN PublicExponentSize
)
{
INT32 Ret;
mbedtls_rsa_context *Rsa;
INT32 Pe;
//
// Check input parameters.
//
if ((RsaContext == NULL) || (ModulusLength > INT_MAX) || (PublicExponentSize > INT_MAX)) {
return FALSE;
}
Rsa = (mbedtls_rsa_context *)RsaContext;
if (PublicExponent == NULL) {
Pe = 0x10001;
} else {
if (PublicExponentSize == 0) {
return FALSE;
}
switch (PublicExponentSize) {
case 1:
Pe = PublicExponent[0];
break;
case 2:
Pe = PublicExponent[0] << 8 | PublicExponent[1];
break;
case 3:
Pe = PublicExponent[0] << 16 | PublicExponent[1] << 8 |
PublicExponent[2];
break;
case 4:
Pe = PublicExponent[0] << 24 | PublicExponent[1] << 16 |
PublicExponent[2] << 8 | PublicExponent[3];
break;
default:
return FALSE;
}
}
Ret = mbedtls_rsa_gen_key (
Rsa,
MbedtlsRand,
NULL,
(UINT32)ModulusLength,
Pe
);
return Ret == 0;
}
/**
Validates key components of RSA context.
NOTE: This function performs integrity checks on all the RSA key material, so
the RSA key structure must contain all the private key data.
This function validates key components of RSA context in following aspects:
- Whether p is a prime
- Whether q is a prime
- Whether n = p * q
- Whether d*e = 1 mod lcm(p-1,q-1)
If RsaContext is NULL, then return FALSE.
@param[in] RsaContext Pointer to RSA context to check.
@retval TRUE RSA key components are valid.
@retval FALSE RSA key components are not valid.
**/
BOOLEAN
EFIAPI
RsaCheckKey (
IN VOID *RsaContext
)
{
if (RsaContext == NULL) {
return FALSE;
}
UINT32 Ret;
Ret = mbedtls_rsa_complete (RsaContext);
if (Ret == 0) {
Ret = mbedtls_rsa_check_privkey (RsaContext);
}
return Ret == 0;
}
/**
Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme.
This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in
RSA PKCS#1.
If the Signature buffer is too small to hold the contents of signature, FALSE
is returned and SigSize is set to the required buffer size to obtain the signature.
If RsaContext is NULL, then return FALSE.
If MessageHash is NULL, then return FALSE.
If HashSize is not equal to the size of MD5, SHA-1, SHA-256, SHA-384 or SHA-512 digest, then return FALSE.
If SigSize is large enough but Signature is NULL, then return FALSE.
@param[in] RsaContext Pointer to RSA context for signature generation.
@param[in] MessageHash Pointer to octet message hash to be signed.
@param[in] HashSize Size of the message hash in bytes.
@param[out] Signature Pointer to buffer to receive RSA PKCS1-v1_5 signature.
@param[in, out] SigSize On input, the size of Signature buffer in bytes.
On output, the size of data returned in Signature buffer in bytes.
@retval TRUE Signature successfully generated in PKCS1-v1_5.
@retval FALSE Signature generation failed.
@retval FALSE SigSize is too small.
**/
BOOLEAN
EFIAPI
RsaPkcs1Sign (
IN VOID *RsaContext,
IN CONST UINT8 *MessageHash,
IN UINTN HashSize,
OUT UINT8 *Signature,
IN OUT UINTN *SigSize
)
{
INT32 Ret;
mbedtls_md_type_t MdAlg;
if ((RsaContext == NULL) || (MessageHash == NULL)) {
return FALSE;
}
if (mbedtls_rsa_complete ((mbedtls_rsa_context *)RsaContext) != 0) {
return FALSE;
}
switch (HashSize) {
#ifndef DISABLE_SHA1_DEPRECATED_INTERFACES
case SHA1_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA1;
break;
#endif
case SHA256_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA256;
break;
case SHA384_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA384;
break;
case SHA512_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA512;
break;
default:
return FALSE;
}
if (mbedtls_rsa_get_len (RsaContext) > *SigSize) {
*SigSize = mbedtls_rsa_get_len (RsaContext);
return FALSE;
}
if (Signature == NULL) {
return FALSE;
}
Ret = mbedtls_rsa_set_padding (RsaContext, MBEDTLS_RSA_PKCS_V15, MdAlg);
if (Ret != 0) {
return FALSE;
}
Ret = mbedtls_rsa_pkcs1_sign (
RsaContext,
MbedtlsRand,
NULL,
MdAlg,
(UINT32)HashSize,
MessageHash,
Signature
);
if (Ret != 0) {
return FALSE;
}
*SigSize = mbedtls_rsa_get_len (RsaContext);
return TRUE;
}

View File

@ -0,0 +1,140 @@
/** @file
RSA PSS Asymmetric Cipher Wrapper Implementation over MbedTLS.
This file implements following APIs which provide basic capabilities for RSA:
1) RsaPssSign
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <mbedtls/rsa.h>
#include <mbedtls/sha256.h>
#include <mbedtls/sha512.h>
/**
Carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme.
This function carries out the RSA-SSA signature generation with EMSA-PSS encoding scheme defined in
RFC 8017.
Mask generation function is the same as the message digest algorithm.
If the Signature buffer is too small to hold the contents of signature, FALSE
is returned and SigSize is set to the required buffer size to obtain the signature.
If RsaContext is NULL, then return FALSE.
If Message is NULL, then return FALSE.
If MsgSize is zero or > INT_MAX, then return FALSE.
If DigestLen is NOT 32, 48 or 64, return FALSE.
If SaltLen is not equal to DigestLen, then return FALSE.
If SigSize is large enough but Signature is NULL, then return FALSE.
If this interface is not supported, then return FALSE.
@param[in] RsaContext Pointer to RSA context for signature generation.
@param[in] Message Pointer to octet message to be signed.
@param[in] MsgSize Size of the message in bytes.
@param[in] DigestLen Length of the digest in bytes to be used for RSA signature operation.
@param[in] SaltLen Length of the salt in bytes to be used for PSS encoding.
@param[out] Signature Pointer to buffer to receive RSA PSS signature.
@param[in, out] SigSize On input, the size of Signature buffer in bytes.
On output, the size of data returned in Signature buffer in bytes.
@retval TRUE Signature successfully generated in RSASSA-PSS.
@retval FALSE Signature generation failed.
@retval FALSE SigSize is too small.
@retval FALSE This interface is not supported.
**/
BOOLEAN
EFIAPI
RsaPssSign (
IN VOID *RsaContext,
IN CONST UINT8 *Message,
IN UINTN MsgSize,
IN UINT16 DigestLen,
IN UINT16 SaltLen,
OUT UINT8 *Signature,
IN OUT UINTN *SigSize
)
{
INT32 Ret;
mbedtls_md_type_t MdAlg;
UINT8 HashValue[SHA512_DIGEST_SIZE];
if (RsaContext == NULL) {
return FALSE;
}
if (mbedtls_rsa_complete ((mbedtls_rsa_context *)RsaContext) != 0) {
return FALSE;
}
if ((Message == NULL) || (MsgSize == 0) || (MsgSize > INT_MAX)) {
return FALSE;
}
if (SaltLen != DigestLen) {
return FALSE;
}
ZeroMem (HashValue, DigestLen);
switch (DigestLen) {
case SHA256_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA256;
if (mbedtls_sha256 (Message, MsgSize, HashValue, FALSE) != 0) {
return FALSE;
}
break;
case SHA384_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA384;
if (mbedtls_sha512 (Message, MsgSize, HashValue, TRUE) != 0) {
return FALSE;
}
break;
case SHA512_DIGEST_SIZE:
MdAlg = MBEDTLS_MD_SHA512;
if (mbedtls_sha512 (Message, MsgSize, HashValue, FALSE) != 0) {
return FALSE;
}
break;
default:
return FALSE;
}
if (Signature == NULL) {
//
// If Signature is NULL, return safe SignatureSize
//
*SigSize = MBEDTLS_MPI_MAX_SIZE;
return FALSE;
}
Ret = mbedtls_rsa_set_padding (RsaContext, MBEDTLS_RSA_PKCS_V21, MdAlg);
if (Ret != 0) {
return FALSE;
}
Ret = mbedtls_rsa_rsassa_pss_sign (
RsaContext,
MbedtlsRand,
NULL,
MdAlg,
(UINT32)DigestLen,
HashValue,
Signature
);
if (Ret != 0) {
return FALSE;
}
*SigSize = ((mbedtls_rsa_context *)RsaContext)->len;
return TRUE;
}

View File

@ -0,0 +1,381 @@
/** @file
RFC3161 Timestamp Countersignature Verification Wrapper Implementation which does
not provide real capabilities.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <mbedtls/asn1.h>
//
// OID ASN.1 Value for SPC_RFC3161_OBJID ("1.3.6.1.4.1.311.3.3.1")
//
GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mSpcRFC3161OidValue[] = {
0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x03, 0x03, 0x01
};
/**
Convert ASN.1 GeneralizedTime to EFI Time.
@param[in] Ptr Pointer to the ASN.1 GeneralizedTime to be converted.
@param[out] EfiTime Return the corresponding EFI Time.
@retval TRUE The time conversion succeeds.
@retval FALSE Invalid parameters.
**/
STATIC
BOOLEAN
ConvertAsn1TimeToEfiTime (
IN UINT8 *Ptr,
OUT EFI_TIME *EfiTime
)
{
CONST CHAR8 *Str;
UINTN Index;
if ((Ptr == NULL) || (EfiTime == NULL)) {
return FALSE;
}
Str = (CONST CHAR8 *)Ptr;
SetMem (EfiTime, sizeof (EFI_TIME), 0);
Index = 0;
/* four digit year */
EfiTime->Year = (Str[Index++] - '0') * 1000;
EfiTime->Year += (Str[Index++] - '0') * 100;
EfiTime->Year += (Str[Index++] - '0') * 10;
EfiTime->Year += (Str[Index++] - '0');
if ((EfiTime->Year < 1900) || (EfiTime->Year > 9999)) {
return FALSE;
}
EfiTime->Month = (Str[Index++] - '0') * 10;
EfiTime->Month += (Str[Index++] - '0');
if ((EfiTime->Month < 1) || (EfiTime->Month > 12)) {
return FALSE;
}
EfiTime->Day = (Str[Index++] - '0') * 10;
EfiTime->Day += (Str[Index++] - '0');
if ((EfiTime->Day < 1) || (EfiTime->Day > 31)) {
return FALSE;
}
EfiTime->Hour = (Str[Index++] - '0') * 10;
EfiTime->Hour += (Str[Index++] - '0');
if (EfiTime->Hour > 23) {
return FALSE;
}
EfiTime->Minute = (Str[Index++] - '0') * 10;
EfiTime->Minute += (Str[Index++] - '0');
if (EfiTime->Minute > 59) {
return FALSE;
}
EfiTime->Second = (Str[Index++] - '0') * 10;
EfiTime->Second += (Str[Index++] - '0');
if (EfiTime->Second > 59) {
return FALSE;
}
/* Note: we did not adjust the time based on time zone information */
return TRUE;
}
/**
Verifies the validity of a RFC3161 Timestamp CounterSignature embedded in PE/COFF Authenticode
signature.
Return FALSE to indicate this interface is not supported.
@param[in] AuthData Pointer to the Authenticode Signature retrieved from signed
PE/COFF image to be verified.
@param[in] DataSize Size of the Authenticode Signature in bytes.
@param[in] TsaCert Pointer to a trusted/root TSA certificate encoded in DER, which
is used for TSA certificate chain verification.
@param[in] CertSize Size of the trusted certificate in bytes.
@param[out] SigningTime Return the time of timestamp generation time if the timestamp
signature is valid.
@retval FALSE This interface is not supported.
**/
BOOLEAN
EFIAPI
ImageTimestampVerify (
IN CONST UINT8 *AuthData,
IN UINTN DataSize,
IN CONST UINT8 *TsaCert,
IN UINTN CertSize,
OUT EFI_TIME *SigningTime
)
{
BOOLEAN Status;
UINT8 *Ptr;
UINT8 *End;
INT32 Len;
UINTN ObjLen;
UINT8 *TempPtr;
//
// Initializations
//
if (SigningTime != NULL) {
SetMem (SigningTime, sizeof (EFI_TIME), 0);
}
//
// Input Parameters Checking.
//
if ((AuthData == NULL) || (TsaCert == NULL)) {
return FALSE;
}
if ((DataSize > INT_MAX) || (CertSize > INT_MAX)) {
return FALSE;
}
Ptr = (UINT8 *)(UINTN)AuthData;
Len = (UINT32)DataSize;
End = Ptr + Len;
// ContentInfo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// ContentType
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
return FALSE;
}
Ptr += ObjLen;
// content
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
return FALSE;
}
End = Ptr + ObjLen;
// signedData
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// version
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
return FALSE;
}
Ptr += ObjLen;
// digestAlgo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
return FALSE;
}
Ptr += ObjLen;
// encapContentInfo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
Ptr += ObjLen;
// cert
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
return FALSE;
}
Ptr += ObjLen;
TempPtr = Ptr;
// OPTIONAL CRLs
if (mbedtls_asn1_get_tag (&TempPtr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) == 0) {
Ptr = TempPtr + ObjLen;
}
// signerInfo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
return FALSE;
}
// sub parse
// signerInfo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
End = Ptr + ObjLen;
// version
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
return FALSE;
}
Ptr += ObjLen;
// sid
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
Ptr += ObjLen;
// digestalgo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
Ptr += ObjLen;
// OPTIONAL AuthenticatedAttributes
TempPtr = Ptr;
if (mbedtls_asn1_get_tag (&TempPtr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) == 0) {
Ptr = TempPtr + ObjLen;
}
// signaturealgo
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
Ptr += ObjLen;
// signature
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OCTET_STRING) != 0) {
return FALSE;
}
Ptr += ObjLen;
// OPTIONAL UnauthenticatedAttributes
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, 0xA1) != 0) {
return FALSE;
}
// Attribute
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// type
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
return FALSE;
}
if (CompareMem (Ptr, mSpcRFC3161OidValue, sizeof (mSpcRFC3161OidValue)) != 0) {
return FALSE;
}
Ptr += ObjLen;
// values
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
return FALSE;
}
// values
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// signedData OID
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
return FALSE;
}
Ptr += ObjLen;
// [0]
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
return FALSE;
}
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// integer
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
return FALSE;
}
Ptr += ObjLen;
// SET
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
return FALSE;
}
Ptr += ObjLen;
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// tST OID
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
return FALSE;
}
Ptr += ObjLen;
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
return FALSE;
}
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OCTET_STRING) != 0) {
return FALSE;
}
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
// Integer
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
return FALSE;
}
Ptr += ObjLen;
// policy OID
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
return FALSE;
}
Ptr += ObjLen;
// sequence
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
return FALSE;
}
Ptr += ObjLen;
// Integer
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
return FALSE;
}
Ptr += ObjLen;
// GeneralizedTime
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_GENERALIZED_TIME) != 0) {
return FALSE;
}
//
// Retrieve the signing time from TS_TST_INFO structure.
//
if (SigningTime != NULL) {
SetMem (SigningTime, sizeof (EFI_TIME), 0);
Status = ConvertAsn1TimeToEfiTime (Ptr, SigningTime);
}
return Status;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
/** @file
Pseudorandom Number Generator Wrapper Implementation over MbedTLS.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <Library/RngLib.h>
/**
Sets up the seed value for the pseudorandom number generator.
This function sets up the seed value for the pseudorandom number generator.
If Seed is not NULL, then the seed passed in is used.
If Seed is NULL, then default seed is used.
@param[in] Seed Pointer to seed value.
If NULL, default seed is used.
@param[in] SeedSize Size of seed value.
If Seed is NULL, this parameter is ignored.
@retval TRUE Pseudorandom number generator has enough entropy for random generation.
@retval FALSE Pseudorandom number generator does not have enough entropy for random generation.
**/
BOOLEAN
EFIAPI
RandomSeed (
IN CONST UINT8 *Seed OPTIONAL,
IN UINTN SeedSize
)
{
return TRUE;
}
/**
Generates a pseudorandom byte stream of the specified size.
If Output is NULL, then return FALSE.
@param[out] Output Pointer to buffer to receive random value.
@param[in] Size Size of random bytes to generate.
@retval TRUE Pseudorandom byte stream generated successfully.
@retval FALSE Pseudorandom number generator fails to generate due to lack of entropy.
**/
BOOLEAN
EFIAPI
RandomBytes (
OUT UINT8 *Output,
IN UINTN Size
)
{
BOOLEAN Ret;
volatile UINT64 TempRand;
//
// Check input parameters.
//
if ((Output == NULL) || (Size > INT_MAX)) {
return FALSE;
}
Ret = FALSE;
while (Size > 0) {
// Use RngLib to get random number
Ret = GetRandomNumber64 ((UINT64 *)&TempRand);
if (!Ret) {
TempRand = 0;
return Ret;
}
if (Size >= sizeof (TempRand)) {
*((UINT64 *)Output) = TempRand;
Output += sizeof (UINT64);
Size -= sizeof (TempRand);
} else {
CopyMem (Output, (VOID *)&TempRand, Size);
Size = 0;
}
}
TempRand = 0;
return Ret;
}
/**
The MbedTLS function f_rng, which MbedtlsRand implements.
@param[in] RngState Not used, just for compatibility with mbedlts.
@param[out] Output Pointer to buffer to receive random value.
@param[in] Len Size of random bytes to generate.
@retval 0 Pseudorandom byte stream generated successfully.
@retval Non-0 Pseudorandom number generator fails to generate due to lack of entropy.
**/
INT32
MbedtlsRand (
VOID *RngState,
UINT8 *Output,
UINTN Len
)
{
BOOLEAN Result;
Result = RandomBytes (Output, Len);
return Result ? 0 : -1;
}

View File

@ -0,0 +1,114 @@
/** @file
Pseudorandom Number Generator Wrapper Implementation over MbedTLS.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "InternalCryptLib.h"
#include <Library/RngLib.h>
/**
Sets up the seed value for the pseudorandom number generator.
This function sets up the seed value for the pseudorandom number generator.
If Seed is not NULL, then the seed passed in is used.
If Seed is NULL, then default seed is used.
@param[in] Seed Pointer to seed value.
If NULL, default seed is used.
@param[in] SeedSize Size of seed value.
If Seed is NULL, this parameter is ignored.
@retval TRUE Pseudorandom number generator has enough entropy for random generation.
@retval FALSE Pseudorandom number generator does not have enough entropy for random generation.
**/
BOOLEAN
EFIAPI
RandomSeed (
IN CONST UINT8 *Seed OPTIONAL,
IN UINTN SeedSize
)
{
return TRUE;
}
/**
Generates a pseudorandom byte stream of the specified size.
If Output is NULL, then return FALSE.
@param[out] Output Pointer to buffer to receive random value.
@param[in] Size Size of random bytes to generate.
@retval TRUE Pseudorandom byte stream generated successfully.
@retval FALSE Pseudorandom number generator fails to generate due to lack of entropy.
**/
BOOLEAN
EFIAPI
RandomBytes (
OUT UINT8 *Output,
IN UINTN Size
)
{
BOOLEAN Ret;
volatile UINT64 TempRand;
//
// Check input parameters.
//
if ((Output == NULL) || (Size > INT_MAX)) {
return FALSE;
}
Ret = FALSE;
while (Size > 0) {
// Use RngLib to get random number
Ret = GetRandomNumber64 ((UINT64 *)&TempRand);
if (!Ret) {
TempRand = 0;
return Ret;
}
if (Size >= sizeof (TempRand)) {
*((UINT64 *)Output) = TempRand;
Output += sizeof (UINT64);
Size -= sizeof (TempRand);
} else {
CopyMem (Output, (VOID *)&TempRand, Size);
Size = 0;
}
}
TempRand = 0;
return Ret;
}
/**
The MbedTLS function f_rng, which MbedtlsRand implements.
@param[in] RngState Not used, just for compatibility with mbedlts.
@param[out] Output Pointer to buffer to receive random value.
@param[in] Len Size of random bytes to generate.
@retval 0 Pseudorandom byte stream generated successfully.
@retval Non-0 Pseudorandom number generator fails to generate due to lack of entropy.
**/
INT32
MbedtlsRand (
VOID *RngState,
UINT8 *Output,
UINTN Len
)
{
BOOLEAN Result;
Result = RandomBytes (Output, Len);
return Result ? 0 : -1;
}

View File

@ -37,32 +37,35 @@
Hash/CryptMd5.c
Hash/CryptSha1.c
Hash/CryptSha256.c
Hash/CryptSm3Null.c
Hash/CryptSha512.c
Hash/CryptParallelHashNull.c
Hash/CryptSm3.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
Cipher/CryptAes.c
Cipher/CryptAeadAesGcmNull.c
Pk/CryptRsaBasic.c
Pk/CryptRsaExtNull.c
Pk/CryptRsaPssNull.c
Pk/CryptRsaPssSignNull.c
Bn/CryptBnNull.c
Pem/CryptPemNull.c
Pk/CryptDhNull.c
Pk/CryptEcNull.c
Pk/CryptPkcs1OaepNull.c
Pk/CryptPkcs5Pbkdf2Null.c
Pk/CryptPkcs7SignNull.c
Pk/CryptPkcs7VerifyNull.c
Pk/CryptPkcs7VerifyEkuNull.c
Pk/CryptX509Null.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyRuntime.c
Pk/CryptPkcs7VerifyEkuRuntime.c
Pk/CryptDhNull.c
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
Rand/CryptRandNull.c
Pk/CryptRsaPssNull.c
Pk/CryptRsaPssSignNull.c
Pk/CryptEcNull.c
Pem/CryptPem.c
Bn/CryptBnNull.c
Rand/CryptRand.c
SysCall/CrtWrapper.c
SysCall/TimerWrapper.c
SysCall/DummyOpensslSupport.c
SysCall/RuntimeMemAllocation.c
[Packages]
@ -75,8 +78,10 @@
UefiRuntimeServicesTableLib
DebugLib
MbedTlsLib
OpensslLib
IntrinsicLib
PrintLib
RngLib
#
# Remove these [BuildOptions] after this library is cleaned up

View File

@ -29,7 +29,6 @@
[Sources]
InternalCryptLib.h
Hash/CryptSha512.c
Hash/CryptMd5Null.c
Hash/CryptSha1Null.c
Hash/CryptSha256Null.c

View File

@ -36,31 +36,35 @@
Hash/CryptMd5.c
Hash/CryptSha1.c
Hash/CryptSha256.c
Hash/CryptSm3Null.c
Hash/CryptSha512.c
Hash/CryptParallelHashNull.c
Hash/CryptSm3.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
Cipher/CryptAes.c
Cipher/CryptAeadAesGcmNull.c
Pk/CryptRsaBasic.c
Pk/CryptRsaExtNull.c
Pk/CryptRsaPss.c
Pk/CryptRsaPssSignNull.c
Bn/CryptBnNull.c
Pem/CryptPemNull.c
Pk/CryptDhNull.c
Pk/CryptEcNull.c
Pk/CryptPkcs1OaepNull.c
Pk/CryptPkcs5Pbkdf2Null.c
Pk/CryptPkcs1Oaep.c
Pk/CryptPkcs5Pbkdf2.c
Pk/CryptPkcs7SignNull.c
Pk/CryptPkcs7VerifyNull.c
Pk/CryptPkcs7VerifyEkuNull.c
Pk/CryptX509Null.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyBase.c
Pk/CryptPkcs7VerifyEku.c
Pk/CryptDhNull.c
Pk/CryptX509.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
Rand/CryptRandNull.c
Pk/CryptRsaPss.c
Pk/CryptRsaPssSignNull.c
Pk/CryptEcNull.c
Pem/CryptPem.c
Bn/CryptBnNull.c
Rand/CryptRand.c
SysCall/CrtWrapper.c
SysCall/DummyOpensslSupport.c
SysCall/BaseMemAllocation.c
SysCall/ConstantTimeClock.c
[Packages]
@ -72,9 +76,11 @@
BaseMemoryLib
MemoryAllocationLib
MbedTlsLib
OpensslLib
IntrinsicLib
PrintLib
MmServicesTableLib
RngLib
SynchronizationLib
#

View File

@ -0,0 +1,122 @@
/** @file
Base Memory Allocation Routines Wrapper for Crypto library over OpenSSL
during PEI & DXE phases.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <CrtLibSupport.h>
#include <Library/MemoryAllocationLib.h>
//
// Extra header to record the memory buffer size from malloc routine.
//
#define CRYPTMEM_HEAD_SIGNATURE SIGNATURE_32('c','m','h','d')
typedef struct {
UINT32 Signature;
UINT32 Reserved;
UINTN Size;
} CRYPTMEM_HEAD;
#define CRYPTMEM_OVERHEAD sizeof(CRYPTMEM_HEAD)
//
// -- Memory-Allocation Routines --
//
/* Allocates memory blocks */
void *
malloc (
size_t size
)
{
CRYPTMEM_HEAD *PoolHdr;
UINTN NewSize;
VOID *Data;
//
// Adjust the size by the buffer header overhead
//
NewSize = (UINTN)(size) + CRYPTMEM_OVERHEAD;
Data = AllocatePool (NewSize);
if (Data != NULL) {
PoolHdr = (CRYPTMEM_HEAD *)Data;
//
// Record the memory brief information
//
PoolHdr->Signature = CRYPTMEM_HEAD_SIGNATURE;
PoolHdr->Size = size;
return (VOID *)(PoolHdr + 1);
} else {
//
// The buffer allocation failed.
//
return NULL;
}
}
/* Reallocate memory blocks */
void *
realloc (
void *ptr,
size_t size
)
{
CRYPTMEM_HEAD *OldPoolHdr;
CRYPTMEM_HEAD *NewPoolHdr;
UINTN OldSize;
UINTN NewSize;
VOID *Data;
NewSize = (UINTN)size + CRYPTMEM_OVERHEAD;
Data = AllocatePool (NewSize);
if (Data != NULL) {
NewPoolHdr = (CRYPTMEM_HEAD *)Data;
NewPoolHdr->Signature = CRYPTMEM_HEAD_SIGNATURE;
NewPoolHdr->Size = size;
if (ptr != NULL) {
//
// Retrieve the original size from the buffer header.
//
OldPoolHdr = (CRYPTMEM_HEAD *)ptr - 1;
ASSERT (OldPoolHdr->Signature == CRYPTMEM_HEAD_SIGNATURE);
OldSize = OldPoolHdr->Size;
//
// Duplicate the buffer content.
//
CopyMem ((VOID *)(NewPoolHdr + 1), ptr, MIN (OldSize, size));
FreePool ((VOID *)OldPoolHdr);
}
return (VOID *)(NewPoolHdr + 1);
} else {
//
// The buffer allocation failed.
//
return NULL;
}
}
/* De-allocates or frees a memory block */
void
free (
void *ptr
)
{
CRYPTMEM_HEAD *PoolHdr;
//
// In Standard C, free() handles a null pointer argument transparently. This
// is not true of FreePool() below, so protect it.
//
if (ptr != NULL) {
PoolHdr = (CRYPTMEM_HEAD *)ptr - 1;
ASSERT (PoolHdr->Signature == CRYPTMEM_HEAD_SIGNATURE);
FreePool (PoolHdr);
}
}

View File

@ -0,0 +1,571 @@
/**
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <CrtLibSupport.h>
int errno = 0;
FILE *stderr = NULL;
FILE *stdin = NULL;
FILE *stdout = NULL;
typedef
int
(*SORT_COMPARE)(
IN VOID *Buffer1,
IN VOID *Buffer2
);
//
// Duplicated from EDKII BaseSortLib for qsort() wrapper
//
STATIC
VOID
QuickSortWorker (
IN OUT VOID *BufferToSort,
IN CONST UINTN Count,
IN CONST UINTN ElementSize,
IN SORT_COMPARE CompareFunction,
IN VOID *Buffer
)
{
VOID *Pivot;
UINTN LoopCount;
UINTN NextSwapLocation;
ASSERT (BufferToSort != NULL);
ASSERT (CompareFunction != NULL);
ASSERT (Buffer != NULL);
if ((Count < 2) || (ElementSize < 1)) {
return;
}
NextSwapLocation = 0;
//
// Pick a pivot (we choose last element)
//
Pivot = ((UINT8 *)BufferToSort + ((Count - 1) * ElementSize));
//
// Now get the pivot such that all on "left" are below it
// and everything "right" are above it
//
for (LoopCount = 0; LoopCount < Count - 1; LoopCount++) {
//
// If the element is less than the pivot
//
if (CompareFunction ((VOID *)((UINT8 *)BufferToSort + ((LoopCount) * ElementSize)), Pivot) <= 0) {
//
// Swap
//
CopyMem (Buffer, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), (UINT8 *)BufferToSort + ((LoopCount) * ElementSize), ElementSize);
CopyMem ((UINT8 *)BufferToSort + ((LoopCount) * ElementSize), Buffer, ElementSize);
//
// Increment NextSwapLocation
//
NextSwapLocation++;
}
}
//
// Swap pivot to its final position (NextSwapLocation)
//
CopyMem (Buffer, Pivot, ElementSize);
CopyMem (Pivot, (UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), ElementSize);
CopyMem ((UINT8 *)BufferToSort + (NextSwapLocation * ElementSize), Buffer, ElementSize);
//
// Now recurse on 2 partial lists. Neither of these will have the 'pivot' element.
// IE list is sorted left half, pivot element, sorted right half...
//
QuickSortWorker (
BufferToSort,
NextSwapLocation,
ElementSize,
CompareFunction,
Buffer
);
QuickSortWorker (
(UINT8 *)BufferToSort + (NextSwapLocation + 1) * ElementSize,
Count - NextSwapLocation - 1,
ElementSize,
CompareFunction,
Buffer
);
return;
}
// ---------------------------------------------------------
// Standard C Run-time Library Interface Wrapper
// ---------------------------------------------------------
//
// -- String Manipulation Routines --
//
/* Scan a string for the last occurrence of a character */
char *
strrchr (
const char *str,
int c
)
{
char *save;
for (save = NULL; ; ++str) {
if (*str == c) {
save = (char *)str;
}
if (*str == 0) {
return (save);
}
}
}
/* Compare first n bytes of string s1 with string s2, ignoring case */
int
strncasecmp (
const char *s1,
const char *s2,
size_t n
)
{
int Val;
ASSERT (s1 != NULL);
ASSERT (s2 != NULL);
if (n != 0) {
do {
Val = tolower (*s1) - tolower (*s2);
if (Val != 0) {
return Val;
}
++s1;
++s2;
if (*s1 == '\0') {
break;
}
} while (--n != 0);
}
return 0;
}
/* Read formatted data from a string */
int
sscanf (
const char *buffer,
const char *format,
...
)
{
//
// Null sscanf() function implementation to satisfy the linker, since
// no direct functionality logic dependency in present UEFI cases.
//
return 0;
}
/* Maps errnum to an error-message string */
char *
strerror (
int errnum
)
{
return NULL;
}
/* Computes the length of the maximum initial segment of the string pointed to by s1
which consists entirely of characters from the string pointed to by s2. */
size_t
strspn (
const char *s1,
const char *s2
)
{
UINT8 Map[32];
UINT32 Index;
size_t Count;
for (Index = 0; Index < 32; Index++) {
Map[Index] = 0;
}
while (*s2) {
Map[*s2 >> 3] |= (1 << (*s2 & 7));
s2++;
}
if (*s1) {
Count = 0;
while (Map[*s1 >> 3] & (1 << (*s1 & 7))) {
Count++;
s1++;
}
return Count;
}
return 0;
}
/* Computes the length of the maximum initial segment of the string pointed to by s1
which consists entirely of characters not from the string pointed to by s2. */
size_t
strcspn (
const char *s1,
const char *s2
)
{
UINT8 Map[32];
UINT32 Index;
size_t Count;
for (Index = 0; Index < 32; Index++) {
Map[Index] = 0;
}
while (*s2) {
Map[*s2 >> 3] |= (1 << (*s2 & 7));
s2++;
}
Map[0] |= 1;
Count = 0;
while (!(Map[*s1 >> 3] & (1 << (*s1 & 7)))) {
Count++;
s1++;
}
return Count;
}
char *
strcpy (
char *strDest,
const char *strSource
)
{
// AsciiStrCpyS (strDest, MAX_STRING_SIZE, strSource);
// return strDest;
return NULL;
}
//
// -- Character Classification Routines --
//
/* Determines if a particular character is a decimal-digit character */
int
isdigit (
int c
)
{
//
// <digit> ::= [0-9]
//
return (('0' <= (c)) && ((c) <= '9'));
}
/* Determine if an integer represents character that is a hex digit */
int
isxdigit (
int c
)
{
//
// <hexdigit> ::= [0-9] | [a-f] | [A-F]
//
return ((('0' <= (c)) && ((c) <= '9')) ||
(('a' <= (c)) && ((c) <= 'f')) ||
(('A' <= (c)) && ((c) <= 'F')));
}
/* Determines if a particular character represents a space character */
int
isspace (
int c
)
{
//
// <space> ::= [ ]
//
return ((c) == ' ');
}
/* Determine if a particular character is an alphanumeric character */
int
isalnum (
int c
)
{
//
// <alnum> ::= [0-9] | [a-z] | [A-Z]
//
return ((('0' <= (c)) && ((c) <= '9')) ||
(('a' <= (c)) && ((c) <= 'z')) ||
(('A' <= (c)) && ((c) <= 'Z')));
}
/* Determines if a particular character is in upper case */
int
isupper (
int c
)
{
//
// <uppercase letter> := [A-Z]
//
return (('A' <= (c)) && ((c) <= 'Z'));
}
//
// -- Data Conversion Routines --
//
/* Convert strings to a long-integer value */
long
strtol (
const char *nptr,
char **endptr,
int base
)
{
//
// Null strtol() function implementation to satisfy the linker, since there is
// no direct functionality logic dependency in present UEFI cases.
//
return 0;
}
/* Convert strings to an unsigned long-integer value */
unsigned long
strtoul (
const char *nptr,
char **endptr,
int base
)
{
//
// Null strtoul() function implementation to satisfy the linker, since there is
// no direct functionality logic dependency in present UEFI cases.
//
return 0;
}
/* Convert character to lowercase */
int
tolower (
int c
)
{
if (('A' <= (c)) && ((c) <= 'Z')) {
return (c - ('A' - 'a'));
}
return (c);
}
//
// -- Searching and Sorting Routines --
//
/* Performs a quick sort */
void
qsort (
void *base,
size_t num,
size_t width,
int ( *compare )(const void *, const void *)
)
{
VOID *Buffer;
ASSERT (base != NULL);
ASSERT (compare != NULL);
//
// Use CRT-style malloc to cover BS and RT memory allocation.
//
Buffer = malloc (width);
ASSERT (Buffer != NULL);
//
// Re-use PerformQuickSort() function Implementation in EDKII BaseSortLib.
//
QuickSortWorker (base, (UINTN)num, (UINTN)width, (SORT_COMPARE)compare, Buffer);
free (Buffer);
return;
}
//
// -- Process and Environment Control Routines --
//
/* Get a value from the current environment */
char *
getenv (
const char *varname
)
{
//
// Null getenv() function implementation to satisfy the linker, since there is
// no direct functionality logic dependency in present UEFI cases.
//
return NULL;
}
/* Get a value from the current environment */
char *
secure_getenv (
const char *varname
)
{
//
// Null secure_getenv() function implementation to satisfy the linker, since
// there is no direct functionality logic dependency in present UEFI cases.
//
// From the secure_getenv() manual: 'just like getenv() except that it
// returns NULL in cases where "secure execution" is required'.
//
return NULL;
}
//
// -- Stream I/O Routines --
//
/* Write data to a stream */
size_t
fwrite (
const void *buffer,
size_t size,
size_t count,
FILE *stream
)
{
return 0;
}
#ifdef __GNUC__
typedef
VOID
(EFIAPI *NoReturnFuncPtr)(
VOID
) __attribute__ ((__noreturn__));
STATIC
VOID
EFIAPI
NopFunction (
VOID
)
{
}
void
abort (
void
)
{
NoReturnFuncPtr NoReturnFunc;
NoReturnFunc = (NoReturnFuncPtr)NopFunction;
NoReturnFunc ();
}
#else
void
abort (
void
)
{
// Do nothing
}
#endif
int
fclose (
FILE *f
)
{
return 0;
}
FILE *
fopen (
const char *c,
const char *m
)
{
return NULL;
}
size_t
fread (
void *b,
size_t c,
size_t i,
FILE *f
)
{
return 0;
}
uid_t
getuid (
void
)
{
return 0;
}
uid_t
geteuid (
void
)
{
return 0;
}
gid_t
getgid (
void
)
{
return 0;
}
gid_t
getegid (
void
)
{
return 0;
}
int
printf (
char const *fmt,
...
)
{
return 0;
}

View File

@ -0,0 +1,63 @@
/** @file
C Run-Time Libraries (CRT) Wrapper Implementation for OpenSSL-based
Cryptographic Library.
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <stdio.h>
#include <Base.h>
#include <Library/DebugLib.h>
/* Read formatted data from a string */
int
sscanf (
const char *buffer,
const char *format,
...
)
{
//
// Null sscanf() function implementation to satisfy the linker, since
// no direct functionality logic dependency in present UEFI cases.
//
return 0;
}
uid_t
getuid (
void
)
{
return 0;
}
uid_t
geteuid (
void
)
{
return 0;
}
gid_t
getgid (
void
)
{
return 0;
}
gid_t
getegid (
void
)
{
return 0;
}
int errno = 0;

View File

@ -27,33 +27,36 @@
[Sources]
InternalCryptLib.h
Cipher/CryptAeadAesGcmNull.c
Cipher/CryptAes.c
Hash/CryptSha256.c
Hash/CryptSha512.c
Hash/CryptSm3Null.c
Hash/CryptMd5.c
Hash/CryptSha1.c
Hash/CryptSha256.c
Hash/CryptSha512.c
Hash/CryptSm3.c
Hash/CryptParallelHashNull.c
Hmac/CryptHmac.c
Kdf/CryptHkdf.c
Cipher/CryptAes.c
Cipher/CryptAeadAesGcm.c
Pk/CryptRsaBasic.c
Pk/CryptRsaExtNull.c
Pk/CryptRsaPss.c
Pk/CryptRsaPssSignNull.c
Bn/CryptBnNull.c
Pem/CryptPemNull.c
Pk/CryptRsaExt.c
Pk/CryptPkcs1Oaep.c
Pk/CryptPkcs5Pbkdf2.c
Pk/CryptPkcs7Sign.c
Pk/CryptPkcs7VerifyCommon.c
Pk/CryptPkcs7VerifyBase.c
Pk/CryptPkcs7VerifyEku.c
Pk/CryptDhNull.c
Pk/CryptX509.c
Pk/CryptAuthenticode.c
Pk/CryptTs.c
Pem/CryptPem.c
Pk/CryptRsaPss.c
Pk/CryptRsaPssSign.c
Bn/CryptBnNull.c
Pk/CryptEcNull.c
Pk/CryptPkcs1OaepNull.c
Pk/CryptPkcs5Pbkdf2Null.c
Pk/CryptPkcs7SignNull.c
Pk/CryptPkcs7VerifyNull.c
Pk/CryptPkcs7VerifyEkuNull.c
Pk/CryptX509Null.c
Pk/CryptAuthenticodeNull.c
Pk/CryptTsNull.c
Rand/CryptRandNull.c
Rand/CryptRand.c
SysCall/CrtWrapper.c
SysCall/UnitTestHostCrtWrapper.c
[Packages]
MdePkg/MdePkg.dec
@ -66,6 +69,7 @@
UefiRuntimeServicesTableLib
DebugLib
MbedTlsLib
OpensslLib
PrintLib
RngLib

View File

@ -141,6 +141,17 @@ static const OSSL_ALGORITHM_CAPABLE deflt_ciphers[] = {
ALG(PROV_NAMES_AES_192_GCM, ossl_aes192gcm_functions),
ALG(PROV_NAMES_AES_128_GCM, ossl_aes128gcm_functions),
ALGC (
PROV_NAMES_AES_128_CBC_HMAC_SHA256,
ossl_aes128cbc_hmac_sha256_functions,
ossl_cipher_capable_aes_cbc_hmac_sha256
),
ALGC (
PROV_NAMES_AES_256_CBC_HMAC_SHA256,
ossl_aes256cbc_hmac_sha256_functions,
ossl_cipher_capable_aes_cbc_hmac_sha256
),
{ { NULL, NULL, NULL }, NULL }
};
static OSSL_ALGORITHM exported_ciphers[OSSL_NELEM(deflt_ciphers)];

View File

@ -140,7 +140,7 @@ GasketSecGetTime (
OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
);
VOID
EFI_STATUS
EFIAPI
GasketSecSetTime (
IN EFI_TIME *Time

View File

@ -92,6 +92,7 @@ GCD_ATTRIBUTE_CONVERSION_ENTRY mAttributeConversionTable[] = {
{ EFI_RESOURCE_ATTRIBUTE_TESTED, EFI_MEMORY_TESTED, FALSE },
{ EFI_RESOURCE_ATTRIBUTE_PERSISTABLE, EFI_MEMORY_NV, TRUE },
{ EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE, EFI_MEMORY_MORE_RELIABLE, TRUE },
{ EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE, EFI_MEMORY_SP, TRUE },
{ 0, 0, FALSE }
};

View File

@ -152,6 +152,7 @@ SmiManage (
PERF_FUNCTION_BEGIN ();
mSmiManageCallingDepth++;
WillReturn = FALSE;
Status = EFI_NOT_FOUND;
ReturnStatus = Status;
if (HandlerType == NULL) {

View File

@ -1,7 +1,7 @@
/** @file
Definitions for data structures used in S3 resume.
Copyright (c) 2011 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2011 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -30,7 +30,6 @@ typedef struct {
EFI_PHYSICAL_ADDRESS ReturnContext1;
EFI_PHYSICAL_ADDRESS ReturnContext2;
EFI_PHYSICAL_ADDRESS ReturnStackPointer;
EFI_PHYSICAL_ADDRESS MpService2Ppi;
EFI_PHYSICAL_ADDRESS Smst;
} SMM_S3_RESUME_STATE;

View File

@ -4,7 +4,7 @@
# and libraries instances, which are used for those modules.
#
# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved.
# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
# (C) Copyright 2016 - 2019 Hewlett Packard Enterprise Development LP<BR>
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
@ -465,6 +465,9 @@
gEdk2JedecSfdpSpiDxeDriverGuid = { 0xBE71701E, 0xB63C, 0x4574, { 0x9C, 0x5C, 0x36, 0x29, 0xE8, 0xEA, 0xC4, 0x14 }}
gEdk2JedecSfdpSpiSmmDriverGuid = { 0x95A1E915, 0x195C, 0x477C, { 0x92, 0x6F, 0x7E, 0x24, 0x67, 0xC1, 0xB3, 0x1F }}
## This GUID will be used to save MTRR_SETTINGS at EndOfDxe by LockBox and restore at S3 boot PEI phase for s3 usage.
gEdkiiS3MtrrSettingGuid = { 0xd77baa84, 0xb332, 0x4463, { 0x9f, 0x1d, 0xce, 0x81, 0x00, 0xfe, 0x7f, 0x35 }}
[Ppis]
## Include/Ppi/FirmwareVolumeShadowPpi.h
gEdkiiPeiFirmwareVolumeShadowPpiGuid = { 0x7dfe756c, 0xed8d, 0x4d77, {0x9e, 0xc4, 0x39, 0x9a, 0x8a, 0x81, 0x51, 0x16 } }

View File

@ -2101,8 +2101,9 @@ ExtractConfigRequest (
//
// Header->VarStoreId == 0 means no storage for this question.
//
ASSERT (Header->VarStoreId != 0);
DEBUG ((DEBUG_INFO, "Varstore Id: 0x%x\n", Header->VarStoreId));
if (Header->VarStoreId == 0) {
continue;
}
Storage = FindStorageFromVarId (FormPackage, Header->VarStoreId);
ASSERT (Storage != NULL);

View File

@ -1288,7 +1288,6 @@ HiiDrawImage (
UINTN BufferLen;
UINT16 Width;
UINT16 Height;
UINTN Xpos;
UINTN Ypos;
UINTN OffsetY1;
UINTN OffsetY2;
@ -1390,9 +1389,11 @@ HiiDrawImage (
for (Ypos = 0; Ypos < Height; Ypos++) {
OffsetY1 = Image->Width * Ypos;
OffsetY2 = Width * Ypos;
for (Xpos = 0; Xpos < Width; Xpos++) {
BltBuffer[OffsetY2 + Xpos] = Image->Bitmap[OffsetY1 + Xpos];
}
CopyMem (
&BltBuffer[OffsetY2],
&Image->Bitmap[OffsetY1],
Width * sizeof (*BltBuffer)
);
}
}

View File

@ -0,0 +1,18 @@
/** @file
IPMI 2.0 definitions from the IPMI Specification Version 2.0, Revision 1.1.
Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#ifndef IPMI_NET_FN_OEM_H_
#define IPMI_NET_FN_OEM_H_
//
// Net function definition for OEM/Group command
//
#define IPMI_NETFN_OEM 0x2E
#define IPMI_NETFN_OEM_GROUP 0x2F
#endif

View File

@ -10,6 +10,7 @@
and Appendix H, Sub-function Assignments.
Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -42,5 +43,50 @@ typedef struct {
UINT8 OEMEvData3;
} IPMI_PLATFORM_EVENT_MESSAGE_DATA_REQUEST;
//
// Definitions for Set Sensor Thresholds command
//
#define IPMI_SENSOR_SET_SENSOR_THRESHOLDS 0x26
typedef union {
struct _SENSOR_BITS {
UINT8 LowerNonCriticalThreshold : 1;
UINT8 LowerCriticalThreshold : 1;
UINT8 LowerNonRecoverableThreshold : 1;
UINT8 UpperNonCriticalThreshold : 1;
UINT8 UpperCriticalThreshold : 1;
UINT8 UpperNonRecoverableThreshold : 1;
UINT8 Reserved : 2;
} Bits;
UINT8 Uint8;
} SENSOR_BITS;
typedef struct _IPMI_SENSOR_SET_SENSOR_THRESHOLD_REQUEST_DATA {
UINT8 SensorNumber;
SENSOR_BITS SetBitEnable;
UINT8 LowerNonCriticalThreshold;
UINT8 LowerCriticalThreshold;
UINT8 LowerNonRecoverableThreshold;
UINT8 UpperNonCriticalThreshold;
UINT8 UpperCriticalThreshold;
UINT8 UpperNonRecoverableThreshold;
} IPMI_SENSOR_SET_SENSOR_THRESHOLD_REQUEST_DATA;
//
// Definitions for Get Sensor Thresholds command
//
#define IPMI_SENSOR_GET_SENSOR_THRESHOLDS 0x27
typedef struct _IPMI_SENSOR_GET_SENSOR_THRESHOLD_RESPONSE_DATA {
UINT8 CompletionCode;
SENSOR_BITS GetBitEnable;
UINT8 LowerNonCriticalThreshold;
UINT8 LowerCriticalThreshold;
UINT8 LowerNonRecoverableThreshold;
UINT8 UpperNonCriticalThreshold;
UINT8 UpperCriticalThreshold;
UINT8 UpperNonRecoverableThreshold;
} IPMI_SENSOR_GET_SENSOR_THRESHOLD_RESPONSE_DATA;
#pragma pack()
#endif

View File

@ -46,9 +46,9 @@ CPUID Signature Information
CPUID Extended Topology Enumeration
@note
Reference: AMD64 Architecture Programmers Manual Volume 3: General-Purpose and System Instructions,
Reference: AMD64 Architecture Programmer's Manual Volume 3: General-Purpose and System Instructions,
Revision 3.35 Appendix E,
E.4.24 Function 8000_0026Extended CPU Topology:
E.4.24 Function 8000_0026-Extended CPU Topology:
CPUID Fn8000_0026 reports extended topology information for logical processors, including
asymmetric and heterogenous topology descriptions. Individual logical processors may report
different values in systems with asynchronous and heterogeneous topologies.

View File

@ -5733,9 +5733,9 @@ typedef union {
/// [Bit 7:4] TME Policy/Encryption Algorithm: Only algorithms enumerated in
/// IA32_TME_CAPABILITY are allowed.
/// For example:
/// 0000 AES-XTS-128.
/// 0001 AES-XTS-128 with integrity.
/// 0010 AES-XTS-256.
/// 0000 - AES-XTS-128.
/// 0001 - AES-XTS-128 with integrity.
/// 0010 - AES-XTS-256.
/// Other values are invalid.
///
UINT32 TmePolicy : 4;
@ -5756,7 +5756,7 @@ typedef union {
/// Similar to enumeration, this is an encoded value.
/// Writing a value greater than MK_TME_MAX_KEYID_BITS will result in #GP.
/// Writing a non-zero value to this field will #GP if bit 1 of EAX (Hardware
/// Encryption Enable) is not also set to 1, as encryption hardware must be
/// Encryption Enable) is not also set to 1, as encryption hardware must be
/// enabled to use MKTME.
/// Example: To support 255 keys, this field would be set to a value of 8.
///

View File

@ -509,7 +509,7 @@ TcpDestroyService (
//
// Destroy the instance of the hashing protocol for this controller.
//
Status = Hash2ServiceBinding->DestroyChild (Hash2ServiceBinding, &mHash2ServiceHandle);
Status = Hash2ServiceBinding->DestroyChild (Hash2ServiceBinding, mHash2ServiceHandle);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}

View File

@ -9,7 +9,7 @@ number of CPUs reported by the MP Services Protocol, so this module does not
support hot plug CPUs. This module can be copied into a CPU specific package
and customized if these additional features are required.
Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015 - 2020, Red Hat, Inc.
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -26,6 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/MemoryAllocationLib.h>
#include <Library/MtrrLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/LockBoxLib.h>
#include <Protocol/MpService.h>
#include <Guid/EventGroup.h>
@ -130,6 +131,16 @@ CpuS3DataOnEndOfDxe (
DEBUG ((DEBUG_VERBOSE, "%a\n", __func__));
MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable);
//
// Save MTRR in lockbox
//
Status = SaveLockBox (
&gEdkiiS3MtrrSettingGuid,
&AcpiCpuDataEx->MtrrTable,
sizeof (MTRR_SETTINGS)
);
ASSERT_EFI_ERROR (Status);
//
// Close event, so it will not be invoked again.
//

View File

@ -9,7 +9,7 @@
# support hot plug CPUs. This module can be copied into a CPU specific package
# and customized if these additional features are required.
#
# Copyright (c) 2013-2016, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2013-2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2015-2020, Red Hat, Inc.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@ -46,9 +46,11 @@
MtrrLib
UefiBootServicesTableLib
UefiDriverEntryPoint
LockBoxLib
[Guids]
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
gEdkiiS3MtrrSettingGuid
[Protocols]
gEfiMpServiceProtocolGuid ## CONSUMES

View File

@ -0,0 +1,10 @@
##
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# MorLock support
##
SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
!if $(SMM_REQUIRE) == TRUE
SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf
!endif

View File

@ -0,0 +1,10 @@
##
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
# MorLock support
##
INF SecurityPkg/Tcg/MemoryOverwriteControl/TcgMor.inf
!if $(SMM_REQUIRE) == TRUE
INF SecurityPkg/Tcg/MemoryOverwriteRequestControlLock/TcgMorLockSmm.inf
!endif

View File

@ -643,6 +643,8 @@ ValidateHobList (
EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |
EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |
EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |
EFI_RESOURCE_ATTRIBUTE_ENCRYPTED|
EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE |
EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)
{
DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));

View File

@ -1,10 +1,11 @@
/** @file
Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.<BR>
Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.<BR>
Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
**/
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
@ -12,10 +13,12 @@
#include <Library/VirtNorFlashPlatformLib.h>
#include <Protocol/FdtClient.h>
#include <stdbool.h>
#define QEMU_NOR_BLOCK_SIZE SIZE_256KB
#define MAX_FLASH_BANKS 4
#define MAX_FLASH_BANKS 4
STATIC VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS];
EFI_STATUS
VirtNorFlashPlatformInitialization (
@ -25,8 +28,6 @@ VirtNorFlashPlatformInitialization (
return EFI_SUCCESS;
}
STATIC VIRT_NOR_FLASH_DESCRIPTION mNorFlashDevices[MAX_FLASH_BANKS];
EFI_STATUS
VirtNorFlashPlatformGetDevices (
OUT VIRT_NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
@ -42,6 +43,7 @@ VirtNorFlashPlatformGetDevices (
UINT32 Num;
UINT64 Base;
UINT64 Size;
BOOLEAN Found;
Status = gBS->LocateProtocol (
&gFdtClientProtocolGuid,
@ -50,7 +52,8 @@ VirtNorFlashPlatformGetDevices (
);
ASSERT_EFI_ERROR (Status);
Num = 0;
Num = 0;
Found = FALSE;
for (FindNodeStatus = FdtClient->FindCompatibleNode (
FdtClient,
"cfi-flash",
@ -94,8 +97,8 @@ VirtNorFlashPlatformGetDevices (
// Disregard any flash devices that overlap with the primary FV.
// The firmware is not updatable from inside the guest anyway.
//
if ((PcdGet64 (PcdFvBaseAddress) + PcdGet32 (PcdFvSize) > Base) &&
((Base + Size) > PcdGet64 (PcdFvBaseAddress)))
if ((PcdGet32 (PcdOvmfFdBaseAddress) + PcdGet32 (PcdOvmfFirmwareFdSize) > Base) &&
((Base + Size) > PcdGet32 (PcdOvmfFdBaseAddress)))
{
continue;
}
@ -105,6 +108,32 @@ VirtNorFlashPlatformGetDevices (
mNorFlashDevices[Num].Size = (UINTN)Size;
mNorFlashDevices[Num].BlockSize = QEMU_NOR_BLOCK_SIZE;
Num++;
if (!Found) {
//
// By default, the second available flash is stored as a non-volatile variable.
//
Status = PcdSet32S (PcdFlashNvStorageVariableBase, Base);
ASSERT_EFI_ERROR (Status);
//
// The Base is the value of PcdFlashNvStorageVariableBase,
// PcdFlashNvStorageFtwWorkingBase can be got by
// PcdFlashNvStorageVariableBase + PcdFlashNvStorageVariableSize
//
Base += PcdGet32 (PcdFlashNvStorageVariableSize);
Status = PcdSet32S (PcdFlashNvStorageFtwWorkingBase, Base);
ASSERT_EFI_ERROR (Status);
//
// Now, the Base is the value of PcdFlashNvStorageFtwWorkingBase,
// PcdFlashNvStorageFtwSpareBase can be got by
// PcdFlashNvStorageFtwWorkingBase + PcdFlashNvStorageFtwWorkingSize.
//
Base += PcdGet32 (PcdFlashNvStorageFtwWorkingSize);
Status = PcdSet32S (PcdFlashNvStorageFtwSpareBase, Base);
ASSERT_EFI_ERROR (Status);
Found = TRUE;
}
}
//

View File

@ -0,0 +1,46 @@
## @file
#
# Copyright (c) 2014-2018, Linaro Ltd. All rights reserved.<BR>
# Copyright (c) 2024 Loongson Technology Corporation Limited. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
[Defines]
INF_VERSION = 1.29
BASE_NAME = NorFlashQemuLib
FILE_GUID = E225C90F-6CB9-8AF3-095B-2668FC633A57
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NorFlashQemuLib|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER UEFI_APPLICATION
[Sources]
FdtNorFlashQemuLib.c
[Packages]
EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
DebugLib
UefiBootServicesTableLib
[Protocols]
gFdtClientProtocolGuid ## CONSUMES
[Depex]
gFdtClientProtocolGuid
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFdBaseAddress
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFirmwareFdSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase

View File

@ -633,6 +633,7 @@ PlatformAddressWidthFromCpuid (
{
UINT32 RegEax, RegEbx, RegEcx, RegEdx, Max;
UINT8 PhysBits;
UINT8 GuestPhysBits;
CHAR8 Signature[13];
IA32_CR4 Cr4;
BOOLEAN Valid = FALSE;
@ -655,13 +656,17 @@ PlatformAddressWidthFromCpuid (
if (Max >= 0x80000008) {
AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
PhysBits = (UINT8)RegEax;
PhysBits = (UINT8)RegEax;
GuestPhysBits = (UINT8)(RegEax >> 16);
} else {
PhysBits = 36;
PhysBits = 36;
GuestPhysBits = 0;
}
if (!QemuQuirk) {
Valid = TRUE;
} else if (GuestPhysBits) {
Valid = TRUE;
} else if (PhysBits >= 41) {
Valid = TRUE;
} else if (AsciiStrCmp (Signature, "GenuineIntel") == 0) {
@ -678,15 +683,21 @@ PlatformAddressWidthFromCpuid (
DEBUG ((
DEBUG_INFO,
"%a: Signature: '%a', PhysBits: %d, QemuQuirk: %a, la57: %a, Valid: %a\n",
"%a: Signature: '%a', PhysBits: %d, GuestPhysBits: %d, QemuQuirk: %a, la57: %a, Valid: %a\n",
__func__,
Signature,
PhysBits,
GuestPhysBits,
QemuQuirk ? "On" : "Off",
Cr4.Bits.LA57 ? "On" : "Off",
Valid ? "Yes" : "No"
));
if (GuestPhysBits && (PhysBits > GuestPhysBits)) {
DEBUG ((DEBUG_INFO, "%a: limit PhysBits to %d (GuestPhysBits)\n", __func__, GuestPhysBits));
PhysBits = GuestPhysBits;
}
if (Valid) {
/*
* Due to the sign extension we can use only the lower half of the
@ -695,7 +706,7 @@ PlatformAddressWidthFromCpuid (
* and a 56 bit wide address space with 5 paging levels.
*/
if (Cr4.Bits.LA57) {
if (PhysBits > 48) {
if ((PhysBits > 48) && !GuestPhysBits) {
/*
* Some Intel CPUs support 5-level paging, have more than 48
* phys-bits but support only 4-level EPT, which effectively
@ -705,11 +716,11 @@ PlatformAddressWidthFromCpuid (
* problem: They can handle guest phys-bits larger than 48
* only in case the host runs in 5-level paging mode.
*
* Until we have some way to communicate that kind of
* limitations from hypervisor to guest, limit phys-bits
* to 48 unconditionally.
* GuestPhysBits is used to communicate that kind of
* limitations from hypervisor to guest. If GuestPhysBits is
* not set play safe and limit phys-bits to 48.
*/
DEBUG ((DEBUG_INFO, "%a: limit PhysBits to 48 (5-level paging)\n", __func__));
DEBUG ((DEBUG_INFO, "%a: limit PhysBits to 48 (5-level paging, no GuestPhysBits)\n", __func__));
PhysBits = 48;
}
} else {

View File

@ -881,6 +881,7 @@
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
!include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc
!include OvmfPkg/Include/Dsc/MorLock.dsc.inc
!if $(SECURE_BOOT_ENABLE) == TRUE
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf

View File

@ -359,6 +359,7 @@ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
!include OvmfPkg/Include/Fdf/OvmfTpmDxe.fdf.inc
!include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc
!include OvmfPkg/Include/Fdf/MorLock.fdf.inc
!if $(LOAD_X64_ON_IA32_ENABLE) == TRUE
INF OvmfPkg/CompatImageLoaderDxe/CompatImageLoaderDxe.inf

View File

@ -895,6 +895,7 @@
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
!include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc
!include OvmfPkg/Include/Dsc/MorLock.dsc.inc
!if $(SECURE_BOOT_ENABLE) == TRUE
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf

View File

@ -366,6 +366,7 @@ INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
!include OvmfPkg/Include/Fdf/OvmfTpmDxe.fdf.inc
!include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc
!include OvmfPkg/Include/Fdf/MorLock.fdf.inc
################################################################################

View File

@ -963,6 +963,7 @@
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
!include OvmfPkg/Include/Dsc/ShellComponents.dsc.inc
!include OvmfPkg/Include/Dsc/MorLock.dsc.inc
!if $(SECURE_BOOT_ENABLE) == TRUE
SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf

View File

@ -406,6 +406,7 @@ INF OvmfPkg/Tcg/TdTcg2Dxe/TdTcg2Dxe.inf
!include OvmfPkg/Include/Fdf/OvmfTpmDxe.fdf.inc
!include OvmfPkg/Include/Fdf/ShellDxe.fdf.inc
!include OvmfPkg/Include/Fdf/MorLock.fdf.inc
################################################################################

View File

@ -156,6 +156,11 @@ VirtioRngGetRNG (
}
Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (This);
if (!Dev->Ready) {
DEBUG ((DEBUG_INFO, "%a: not ready\n", __func__));
return EFI_DEVICE_ERROR;
}
//
// Map Buffer's system physical address to device address
//
@ -382,6 +387,7 @@ VirtioRngInit (
//
Dev->Rng.GetInfo = VirtioRngGetInfo;
Dev->Rng.GetRNG = VirtioRngGetRNG;
Dev->Ready = TRUE;
return EFI_SUCCESS;
@ -414,8 +420,8 @@ VirtioRngUninit (
// VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
// the old comms area.
//
Dev->Ready = FALSE;
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
@ -435,7 +441,7 @@ VirtioRngExitBoot (
{
VIRTIO_RNG_DEV *Dev;
DEBUG ((DEBUG_VERBOSE, "%a: Context=0x%p\n", __func__, Context));
DEBUG ((DEBUG_INFO, "%a: Context=0x%p\n", __func__, Context));
//
// Reset the device. This causes the hypervisor to forget about the virtio
// ring.
@ -443,7 +449,8 @@ VirtioRngExitBoot (
// We allocated said ring in EfiBootServicesData type memory, and code
// executing after ExitBootServices() is permitted to overwrite it.
//
Dev = Context;
Dev = Context;
Dev->Ready = FALSE;
Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
}

View File

@ -33,6 +33,7 @@ typedef struct {
VRING Ring; // VirtioRingInit 2
EFI_RNG_PROTOCOL Rng; // VirtioRngInit 1
VOID *RingMap; // VirtioRingMap 2
BOOLEAN Ready;
} VIRTIO_RNG_DEV;
#define VIRTIO_ENTROPY_SOURCE_FROM_RNG(RngPointer) \

View File

@ -174,6 +174,7 @@ MmiManage (
EFI_STATUS Status;
mMmiManageCallingDepth++;
WillReturn = FALSE;
Status = EFI_NOT_FOUND;
ReturnStatus = Status;
if (HandlerType == NULL) {

View File

@ -9,7 +9,7 @@ number of CPUs reported by the MP Services Protocol, so this module does not
support hot plug CPUs. This module can be copied into a CPU specific package
and customized if these additional features are required.
Copyright (c) 2013 - 2021, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2013 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015, Red Hat, Inc.
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -26,6 +26,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <Library/DebugLib.h>
#include <Library/MtrrLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/LockBoxLib.h>
#include <Protocol/MpService.h>
#include <Guid/EventGroup.h>
@ -130,6 +131,16 @@ CpuS3DataOnEndOfDxe (
DEBUG ((DEBUG_VERBOSE, "%a\n", __func__));
MtrrGetAllMtrrs (&AcpiCpuDataEx->MtrrTable);
//
// Save MTRR in lockbox
//
Status = SaveLockBox (
&gEdkiiS3MtrrSettingGuid,
&AcpiCpuDataEx->MtrrTable,
sizeof (MTRR_SETTINGS)
);
ASSERT_EFI_ERROR (Status);
//
// Close event, so it will not be invoked again.
//

View File

@ -9,7 +9,7 @@
# support hot plug CPUs. This module can be copied into a CPU specific package
# and customized if these additional features are required.
#
# Copyright (c) 2013-2016, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2013-2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2015, Red Hat, Inc.
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@ -46,9 +46,11 @@
BaseLib
MtrrLib
MemoryAllocationLib
LockBoxLib
[Guids]
gEfiEndOfDxeEventGroupGuid ## CONSUMES ## Event
gEdkiiS3MtrrSettingGuid
[Protocols]
gEfiMpServiceProtocolGuid ## CONSUMES

View File

@ -342,6 +342,7 @@ PageTableLibMapInLevel (
UINT64 PhysicalAddrInAttr;
IA32_PAGING_ENTRY OriginalParentPagingEntry;
IA32_PAGING_ENTRY OriginalCurrentPagingEntry;
IA32_PAGING_ENTRY TempPagingEntry;
ASSERT (Level != 0);
ASSERT ((Attribute != NULL) && (Mask != NULL));
@ -359,6 +360,8 @@ PageTableLibMapInLevel (
OriginalParentPagingEntry.Uint64 = ParentPagingEntry->Uint64;
OneOfPagingEntry.Uint64 = 0;
TempPagingEntry.Uint64 = 0;
//
// RegionLength: 256T (1 << 48) 512G (1 << 39), 1G (1 << 30), 2M (1 << 21) or 4K (1 << 12).
//
@ -441,8 +444,10 @@ PageTableLibMapInLevel (
// Non-leaf entry doesn't have PAT bit. So use ~IA32_PE_BASE_ADDRESS_MASK_40 is to make sure PAT bit
// (bit12) in original big-leaf entry is not assigned to PageTableBaseAddress field of non-leaf entry.
//
PageTableLibSetPnle (&ParentPagingEntry->Pnle, &NopAttribute, &AllOneMask);
ParentPagingEntry->Uint64 = ((UINTN)(VOID *)PagingEntry) | (ParentPagingEntry->Uint64 & (~IA32_PE_BASE_ADDRESS_MASK_40));
TempPagingEntry.Uint64 = ParentPagingEntry->Uint64;
PageTableLibSetPnle (&TempPagingEntry.Pnle, &NopAttribute, &AllOneMask);
TempPagingEntry.Uint64 = ((UINTN)(VOID *)PagingEntry) | (TempPagingEntry.Uint64 & (~IA32_PE_BASE_ADDRESS_MASK_40));
*(volatile UINT64 *)&(ParentPagingEntry->Uint64) = TempPagingEntry.Uint64;
}
} else {
//

View File

@ -1,7 +1,7 @@
/** @file
MP initialize support functions for DXE phase.
Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -20,15 +20,11 @@
#define AP_SAFE_STACK_SIZE 128
CPU_MP_DATA *mCpuMpData = NULL;
EFI_EVENT mCheckAllApsEvent = NULL;
EFI_EVENT mMpInitExitBootServicesEvent = NULL;
EFI_EVENT mLegacyBootEvent = NULL;
volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
RELOCATE_AP_LOOP_ENTRY mReservedApLoop;
UINTN mReservedTopOfApStack;
volatile UINT32 mNumberToFinish = 0;
UINTN mApPageTable;
CPU_MP_DATA *mCpuMpData = NULL;
EFI_EVENT mCheckAllApsEvent = NULL;
EFI_EVENT mMpInitExitBootServicesEvent = NULL;
EFI_EVENT mLegacyBootEvent = NULL;
volatile BOOLEAN mStopCheckAllApsStatus = TRUE;
//
// Begin wakeup buffer allocation below 0x88000
@ -369,57 +365,58 @@ GetProtectedModeCS (
}
/**
Do sync on APs.
Allocate buffer for ApLoopCode.
@param[in, out] Buffer Pointer to private data buffer.
@param[in] Pages Number of pages to allocate.
@param[in, out] Address Pointer to the allocated buffer.
**/
VOID
EFIAPI
RelocateApLoop (
IN OUT VOID *Buffer
AllocateApLoopCodeBuffer (
IN UINTN Pages,
IN OUT EFI_PHYSICAL_ADDRESS *Address
)
{
CPU_MP_DATA *CpuMpData;
BOOLEAN MwaitSupport;
UINTN ProcessorNumber;
UINTN StackStart;
EFI_STATUS Status;
MpInitLibWhoAmI (&ProcessorNumber);
CpuMpData = GetCpuMpData ();
MwaitSupport = IsMwaitSupport ();
if (CpuMpData->UseSevEsAPMethod) {
//
// 64-bit AMD processors with SEV-ES
//
StackStart = CpuMpData->SevEsAPResetStackStart;
mReservedApLoop.AmdSevEntry (
MwaitSupport,
CpuMpData->ApTargetCState,
CpuMpData->PmCodeSegment,
StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
(UINTN)&mNumberToFinish,
CpuMpData->Pm16CodeSegment,
CpuMpData->SevEsAPBuffer,
CpuMpData->WakeupBuffer
);
} else {
//
// Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
//
StackStart = mReservedTopOfApStack;
mReservedApLoop.GenericEntry (
MwaitSupport,
CpuMpData->ApTargetCState,
StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
(UINTN)&mNumberToFinish,
mApPageTable
);
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiReservedMemoryType,
Pages,
Address
);
ASSERT_EFI_ERROR (Status);
}
/**
Remove Nx protection for the range specific by BaseAddress and Length.
The PEI implementation uses CpuPageTableLib to change the attribute.
The DXE implementation uses gDS to change the attribute.
@param[in] BaseAddress BaseAddress of the range.
@param[in] Length Length of the range.
**/
VOID
RemoveNxprotection (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINTN Length
)
{
EFI_STATUS Status;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;
//
// TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
// service.
//
Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &MemDesc);
if (!EFI_ERROR (Status)) {
gDS->SetMemorySpaceAttributes (
BaseAddress,
Length,
MemDesc.Attributes & (~EFI_MEMORY_XP)
);
}
//
// It should never reach here
//
ASSERT (FALSE);
}
/**
@ -477,16 +474,10 @@ InitMpGlobalData (
)
{
EFI_STATUS Status;
EFI_PHYSICAL_ADDRESS Address;
UINTN Index;
EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemDesc;
UINTN StackBase;
CPU_INFO_IN_HOB *CpuInfoInHob;
MP_ASSEMBLY_ADDRESS_MAP *AddressMap;
UINT8 *ApLoopFunc;
UINTN ApLoopFuncSize;
UINTN StackPages;
UINTN FuncPages;
SaveCpuMpData (CpuMpData);
@ -541,81 +532,7 @@ InitMpGlobalData (
}
}
AddressMap = &CpuMpData->AddressMap;
if (CpuMpData->UseSevEsAPMethod) {
//
// 64-bit AMD processors with SEV-ES
//
Address = BASE_4GB - 1;
ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev;
ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev;
} else {
//
// Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
//
Address = MAX_ADDRESS;
ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric;
ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric;
}
//
// Avoid APs access invalid buffer data which allocated by BootServices,
// so we will allocate reserved data for AP loop code. We also need to
// allocate this buffer below 4GB due to APs may be transferred to 32bit
// protected mode on long mode DXE.
// Allocating it in advance since memory services are not available in
// Exit Boot Services callback function.
//
// +------------+ (TopOfApStack)
// | Stack * N |
// +------------+ (stack base, 4k aligned)
// | Padding |
// +------------+
// | Ap Loop |
// +------------+ ((low address, 4k-aligned)
//
StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize);
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiReservedMemoryType,
StackPages + FuncPages,
&Address
);
ASSERT_EFI_ERROR (Status);
//
// Make sure that the buffer memory is executable if NX protection is enabled
// for EfiReservedMemoryType.
//
// TODO: Check EFI_MEMORY_XP bit set or not once it's available in DXE GCD
// service.
//
Status = gDS->GetMemorySpaceDescriptor (Address, &MemDesc);
if (!EFI_ERROR (Status)) {
gDS->SetMemorySpaceAttributes (
Address,
EFI_PAGES_TO_SIZE (FuncPages),
MemDesc.Attributes & (~EFI_MEMORY_XP)
);
}
mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages);
ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
mReservedApLoop.Data = (VOID *)(UINTN)Address;
ASSERT (mReservedApLoop.Data != NULL);
CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);
if (!CpuMpData->UseSevEsAPMethod) {
//
// processors without SEV-ES
//
mApPageTable = CreatePageTable (
(UINTN)Address,
EFI_PAGES_TO_SIZE (StackPages+FuncPages)
);
}
PrepareApLoopCode (CpuMpData);
Status = gBS->CreateEvent (
EVT_TIMER | EVT_NOTIFY_SIGNAL,

View File

@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.<BR>
; Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
@ -225,6 +225,10 @@ RendezvousFunnelProcEnd:
; specific to SEV-ES support and are not applicable on IA32.
;-------------------------------------------------------------------------------------
AsmRelocateApLoopGenericStart:
mov eax, cr0
btr eax, 31 ; Clear CR0.PG
mov cr0, eax ; Disable paging since the page table might be unavailiable
mov eax, esp
mov esp, [eax + 12] ; TopOfApStack
push dword [eax] ; push return address for stack trace

View File

@ -1,7 +1,7 @@
/** @file
CPU MP Initialize Library common functions.
Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -17,6 +17,11 @@ EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;
EFI_GUID mMpHandOffGuid = MP_HANDOFF_GUID;
EFI_GUID mMpHandOffConfigGuid = MP_HANDOFF_CONFIG_GUID;
RELOCATE_AP_LOOP_ENTRY mReservedApLoop;
UINTN mReservedTopOfApStack;
volatile UINT32 mNumberToFinish = 0;
UINTN mApPageTable;
/**
Save the volatile registers required to be restored following INIT IPI.
@ -114,6 +119,10 @@ FutureBSPProc (
SaveVolatileRegisters (&DataInHob->APInfo.VolatileRegisters);
AsmExchangeRole (&DataInHob->APInfo, &DataInHob->BSPInfo);
RestoreVolatileRegisters (&DataInHob->APInfo.VolatileRegisters, FALSE);
//
// Update VolatileRegisters saved in CpuMpData->CpuData
//
CopyMem (&DataInHob->CpuData[DataInHob->BspNumber].VolatileRegisters, &DataInHob->APInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
}
/**
@ -761,11 +770,11 @@ ApWakeupFunction (
BistData = (UINT32)ApStackData->Bist;
//
// CpuMpData->CpuData[0].VolatileRegisters is initialized based on BSP environment,
// CpuMpData->CpuData[BspNumber].VolatileRegisters is initialized based on BSP environment,
// to initialize AP in InitConfig path.
// NOTE: IDTR.BASE stored in CpuMpData->CpuData[0].VolatileRegisters points to a different IDT shared by all APs.
// NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a different IDT shared by all APs.
//
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);
RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
InitializeApData (CpuMpData, ProcessorNumber, BistData, ApTopOfStack);
ApStartupSignalBuffer = CpuMpData->CpuData[ProcessorNumber].StartupApSignal;
} else {
@ -798,10 +807,10 @@ ApWakeupFunction (
// 1. AP is re-enabled after it's disabled, in either PEI or DXE phase.
// 2. AP is initialized in DXE phase.
// In either case, use the volatile registers value derived from BSP.
// NOTE: IDTR.BASE stored in CpuMpData->CpuData[0].VolatileRegisters points to a
// NOTE: IDTR.BASE stored in CpuMpData->CpuData[BspNumber].VolatileRegisters points to a
// different IDT shared by all APs.
//
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);
RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
} else {
if (CpuMpData->ApLoopMode == ApInHltLoop) {
//
@ -927,7 +936,7 @@ DxeApEntryPoint (
AsmWriteMsr64 (MSR_IA32_EFER, EferMsr.Uint64);
}
RestoreVolatileRegisters (&CpuMpData->CpuData[0].VolatileRegisters, FALSE);
RestoreVolatileRegisters (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, FALSE);
InterlockedIncrement ((UINT32 *)&CpuMpData->FinishedCount);
PlaceAPInMwaitLoopOrRunLoop (
CpuMpData->ApLoopMode,
@ -2151,11 +2160,16 @@ MpInitLibInitialize (
CpuMpData->BackupBufferSize = ApResetVectorSizeBelow1Mb;
CpuMpData->WakeupBuffer = (UINTN)-1;
CpuMpData->CpuCount = 1;
CpuMpData->BspNumber = 0;
CpuMpData->WaitEvent = NULL;
CpuMpData->SwitchBspFlag = FALSE;
CpuMpData->CpuData = (CPU_AP_DATA *)(CpuMpData + 1);
CpuMpData->CpuInfoInHob = (UINT64)(UINTN)(CpuMpData->CpuData + MaxLogicalProcessorNumber);
if (FirstMpHandOff == NULL) {
CpuMpData->BspNumber = 0;
} else {
CpuMpData->BspNumber = GetBspNumber (FirstMpHandOff);
}
CpuMpData->WaitEvent = NULL;
CpuMpData->SwitchBspFlag = FALSE;
CpuMpData->CpuData = (CPU_AP_DATA *)(CpuMpData + 1);
CpuMpData->CpuInfoInHob = (UINT64)(UINTN)(CpuMpData->CpuData + MaxLogicalProcessorNumber);
InitializeSpinLock (&CpuMpData->MpLock);
CpuMpData->SevEsIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevEs);
CpuMpData->SevSnpIsEnabled = ConfidentialComputingGuestHas (CCAttrAmdSevSnp);
@ -2186,11 +2200,11 @@ MpInitLibInitialize (
// Don't pass BSP's TR to APs to avoid AP init failure.
//
VolatileRegisters.Tr = 0;
CopyMem (&CpuMpData->CpuData[0].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters));
CopyMem (&CpuMpData->CpuData[CpuMpData->BspNumber].VolatileRegisters, &VolatileRegisters, sizeof (VolatileRegisters));
//
// Set BSP basic information
//
InitializeApData (CpuMpData, 0, 0, CpuMpData->Buffer + ApStackSize);
InitializeApData (CpuMpData, CpuMpData->BspNumber, 0, CpuMpData->Buffer + ApStackSize * (CpuMpData->BspNumber + 1));
//
// Save assembly code information
//
@ -2245,9 +2259,8 @@ MpInitLibInitialize (
AmdSevUpdateCpuMpData (CpuMpData);
}
CpuMpData->CpuCount = MaxLogicalProcessorNumber;
CpuMpData->BspNumber = GetBspNumber (FirstMpHandOff);
CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
CpuMpData->CpuCount = MaxLogicalProcessorNumber;
CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
for (MpHandOff = FirstMpHandOff;
MpHandOff != NULL;
MpHandOff = GetNextMpHandOffHob (MpHandOff))
@ -2615,7 +2628,12 @@ SwitchBSPWorker (
SaveVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters);
AsmExchangeRole (&CpuMpData->BSPInfo, &CpuMpData->APInfo);
RestoreVolatileRegisters (&CpuMpData->BSPInfo.VolatileRegisters, FALSE);
//
// Update VolatileRegisters saved in CpuMpData->CpuData
// Don't pass BSP's TR to APs to avoid AP init failure.
//
CopyMem (&CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters, &CpuMpData->BSPInfo.VolatileRegisters, sizeof (CPU_VOLATILE_REGISTERS));
CpuMpData->CpuData[CpuMpData->NewBspNumber].VolatileRegisters.Tr = 0;
//
// Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
//
@ -3227,3 +3245,140 @@ ConfidentialComputingGuestHas (
return (CurrentAttr == Attr);
}
/**
Do sync on APs.
@param[in, out] Buffer Pointer to private data buffer.
**/
VOID
EFIAPI
RelocateApLoop (
IN OUT VOID *Buffer
)
{
CPU_MP_DATA *CpuMpData;
BOOLEAN MwaitSupport;
UINTN ProcessorNumber;
UINTN StackStart;
MpInitLibWhoAmI (&ProcessorNumber);
CpuMpData = GetCpuMpData ();
MwaitSupport = IsMwaitSupport ();
if (CpuMpData->UseSevEsAPMethod) {
//
// 64-bit AMD processors with SEV-ES
//
StackStart = CpuMpData->SevEsAPResetStackStart;
mReservedApLoop.AmdSevEntry (
MwaitSupport,
CpuMpData->ApTargetCState,
CpuMpData->PmCodeSegment,
StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
(UINTN)&mNumberToFinish,
CpuMpData->Pm16CodeSegment,
CpuMpData->SevEsAPBuffer,
CpuMpData->WakeupBuffer
);
} else {
//
// Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
//
StackStart = mReservedTopOfApStack;
mReservedApLoop.GenericEntry (
MwaitSupport,
CpuMpData->ApTargetCState,
StackStart - ProcessorNumber * AP_SAFE_STACK_SIZE,
(UINTN)&mNumberToFinish,
mApPageTable
);
}
//
// It should never reach here
//
ASSERT (FALSE);
}
/**
Prepare ApLoopCode.
@param[in] CpuMpData Pointer to CpuMpData.
**/
VOID
PrepareApLoopCode (
IN CPU_MP_DATA *CpuMpData
)
{
EFI_PHYSICAL_ADDRESS Address;
MP_ASSEMBLY_ADDRESS_MAP *AddressMap;
UINT8 *ApLoopFunc;
UINTN ApLoopFuncSize;
UINTN StackPages;
UINTN FuncPages;
IA32_CR0 Cr0;
AddressMap = &CpuMpData->AddressMap;
if (CpuMpData->UseSevEsAPMethod) {
//
// 64-bit AMD processors with SEV-ES
//
Address = BASE_4GB - 1;
ApLoopFunc = AddressMap->RelocateApLoopFuncAddressAmdSev;
ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeAmdSev;
} else {
//
// Intel processors (32-bit or 64-bit), 32-bit AMD processors, or 64-bit AMD processors without SEV-ES
//
Address = MAX_ADDRESS;
ApLoopFunc = AddressMap->RelocateApLoopFuncAddressGeneric;
ApLoopFuncSize = AddressMap->RelocateApLoopFuncSizeGeneric;
}
//
// Avoid APs access invalid buffer data which allocated by BootServices,
// so we will allocate reserved data for AP loop code. We also need to
// allocate this buffer below 4GB due to APs may be transferred to 32bit
// protected mode on long mode DXE.
// Allocating it in advance since memory services are not available in
// Exit Boot Services callback function.
//
// +------------+ (TopOfApStack)
// | Stack * N |
// +------------+ (stack base, 4k aligned)
// | Padding |
// +------------+
// | Ap Loop |
// +------------+ ((low address, 4k-aligned)
//
StackPages = EFI_SIZE_TO_PAGES (CpuMpData->CpuCount * AP_SAFE_STACK_SIZE);
FuncPages = EFI_SIZE_TO_PAGES (ApLoopFuncSize);
AllocateApLoopCodeBuffer (StackPages + FuncPages, &Address);
ASSERT (Address != 0);
Cr0.UintN = AsmReadCr0 ();
if (Cr0.Bits.PG != 0) {
//
// Make sure that the buffer memory is executable if NX protection is enabled
// for EfiReservedMemoryType.
//
RemoveNxprotection (Address, EFI_PAGES_TO_SIZE (FuncPages));
}
mReservedTopOfApStack = (UINTN)Address + EFI_PAGES_TO_SIZE (StackPages+FuncPages);
ASSERT ((mReservedTopOfApStack & (UINTN)(CPU_STACK_ALIGNMENT - 1)) == 0);
mReservedApLoop.Data = (VOID *)(UINTN)Address;
ASSERT (mReservedApLoop.Data != NULL);
CopyMem (mReservedApLoop.Data, ApLoopFunc, ApLoopFuncSize);
if (!CpuMpData->UseSevEsAPMethod) {
//
// processors without SEV-ES and paging is enabled
//
mApPageTable = CreatePageTable (
(UINTN)Address,
EFI_PAGES_TO_SIZE (StackPages+FuncPages)
);
}
}

View File

@ -1,7 +1,7 @@
/** @file
Common header file for MP Initialize Library.
Copyright (c) 2016 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2020 - 2024, AMD Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -33,6 +33,7 @@
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/MicrocodeLib.h>
#include <Library/CpuPageTableLib.h>
#include <ConfidentialComputingGuestAttr.h>
#include <Register/Amd/Fam17Msr.h>
@ -68,6 +69,8 @@
//
#define DEFAULT_MAX_MICROCODE_PATCH_NUM 8
#define PAGING_4K_ADDRESS_MASK_64 0x000FFFFFFFFFF000ull
//
// Data structure for microcode patch information
//
@ -357,7 +360,8 @@ typedef
IN UINTN StackStart
);
extern EFI_GUID mCpuInitMpLibHobGuid;
extern EFI_GUID mCpuInitMpLibHobGuid;
extern volatile UINT32 mNumberToFinish;
/**
Assembly code to place AP into safe loop mode.
@ -933,4 +937,52 @@ AmdSevUpdateCpuMpData (
IN CPU_MP_DATA *CpuMpData
);
/**
Prepare ApLoopCode.
@param[in] CpuMpData Pointer to CpuMpData.
**/
VOID
PrepareApLoopCode (
IN CPU_MP_DATA *CpuMpData
);
/**
Do sync on APs.
@param[in, out] Buffer Pointer to private data buffer.
**/
VOID
EFIAPI
RelocateApLoop (
IN OUT VOID *Buffer
);
/**
Allocate buffer for ApLoopCode.
@param[in] Pages Number of pages to allocate.
@param[in, out] Address Pointer to the allocated buffer.
**/
VOID
AllocateApLoopCodeBuffer (
IN UINTN Pages,
IN OUT EFI_PHYSICAL_ADDRESS *Address
);
/**
Remove Nx protection for the range specific by BaseAddress and Length.
The PEI implementation uses CpuPageTableLib to change the attribute.
The DXE implementation uses gDS to change the attribute.
@param[in] BaseAddress BaseAddress of the range.
@param[in] Length Length of the range.
**/
VOID
RemoveNxprotection (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINTN Length
);
#endif

View File

@ -1,7 +1,7 @@
## @file
# MP Initialize Library instance for PEI driver.
#
# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@ -25,10 +25,12 @@
[Sources.IA32]
Ia32/AmdSev.c
Ia32/MpFuncs.nasm
Ia32/CreatePageTable.c
[Sources.X64]
X64/AmdSev.c
X64/MpFuncs.nasm
X64/CreatePageTable.c
[Sources.IA32, Sources.X64]
AmdSev.c
@ -64,6 +66,7 @@
LocalApicLib
MicrocodeLib
MtrrLib
CpuPageTableLib
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdGhcbBase ## CONSUMES
@ -87,6 +90,7 @@
gEdkiiS3SmmInitDoneGuid
gEdkiiMicrocodePatchHobGuid
gGhcbApicIdsGuid ## SOMETIMES_CONSUMES
gEdkiiEndOfS3ResumeGuid
[Guids.LoongArch64]
gProcessorResourceHobGuid ## SOMETIMES_CONSUMES ## HOB

View File

@ -1,7 +1,7 @@
/** @file
MP initialize support functions for PEI phase.
Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -9,6 +9,7 @@
#include "MpLib.h"
#include <Library/PeiServicesLib.h>
#include <Guid/S3SmmInitDone.h>
#include <Guid/EndOfS3Resume.h>
#include <Ppi/ShadowMicrocode.h>
STATIC UINT64 mSevEsPeiWakeupBuffer = BASE_1MB;
@ -449,6 +450,47 @@ BuildMicrocodeCacheHob (
return;
}
/**
S3 SMM Init Done notification function.
@param PeiServices Indirect reference to the PEI Services Table.
@param NotifyDesc Address of the notification descriptor data structure.
@param InvokePpi Address of the PPI that was invoked.
@retval EFI_SUCCESS The function completes successfully.
**/
EFI_STATUS
EFIAPI
NotifyOnEndOfS3Resume (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
IN VOID *InvokePpi
)
{
CPU_MP_DATA *CpuMpData;
CpuMpData = GetCpuMpData ();
mNumberToFinish = CpuMpData->CpuCount - 1;
WakeUpAP (CpuMpData, TRUE, 0, RelocateApLoop, NULL, TRUE);
while (mNumberToFinish > 0) {
CpuPause ();
}
DEBUG ((DEBUG_INFO, "%a() done!\n", __func__));
return EFI_SUCCESS;
}
//
// Global function
//
EFI_PEI_NOTIFY_DESCRIPTOR mEndOfS3ResumeNotifyDesc = {
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gEdkiiEndOfS3ResumeGuid,
NotifyOnEndOfS3Resume
};
/**
Initialize global data for MP support.
@ -463,12 +505,16 @@ InitMpGlobalData (
BuildMicrocodeCacheHob (CpuMpData);
SaveCpuMpData (CpuMpData);
PrepareApLoopCode (CpuMpData);
///
/// Install Notify
///
Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc);
ASSERT_EFI_ERROR (Status);
Status = PeiServicesNotifyPpi (&mEndOfS3ResumeNotifyDesc);
ASSERT_EFI_ERROR (Status);
}
/**
@ -815,3 +861,109 @@ PlatformShadowMicrocode (
return EFI_SUCCESS;
}
/**
Allocate buffer for ApLoopCode.
@param[in] Pages Number of pages to allocate.
@param[in, out] Address Pointer to the allocated buffer.
**/
VOID
AllocateApLoopCodeBuffer (
IN UINTN Pages,
IN OUT EFI_PHYSICAL_ADDRESS *Address
)
{
EFI_STATUS Status;
Status = PeiServicesAllocatePages (EfiACPIMemoryNVS, Pages, Address);
if (EFI_ERROR (Status)) {
*Address = 0;
}
}
/**
Remove Nx protection for the range specific by BaseAddress and Length.
The PEI implementation uses CpuPageTableLib to change the attribute.
The DXE implementation uses gDS to change the attribute.
@param[in] BaseAddress BaseAddress of the range.
@param[in] Length Length of the range.
**/
VOID
RemoveNxprotection (
IN EFI_PHYSICAL_ADDRESS BaseAddress,
IN UINTN Length
)
{
EFI_STATUS Status;
UINTN PageTable;
EFI_PHYSICAL_ADDRESS Buffer;
UINTN BufferSize;
IA32_MAP_ATTRIBUTE MapAttribute;
IA32_MAP_ATTRIBUTE MapMask;
PAGING_MODE PagingMode;
IA32_CR4 Cr4;
BOOLEAN Page5LevelSupport;
UINT32 RegEax;
BOOLEAN Page1GSupport;
CPUID_EXTENDED_CPU_SIG_EDX RegEdx;
if (sizeof (UINTN) == sizeof (UINT64)) {
//
// Check Page5Level Support or not.
//
Cr4.UintN = AsmReadCr4 ();
Page5LevelSupport = (Cr4.Bits.LA57 ? TRUE : FALSE);
//
// Check Page1G Support or not.
//
Page1GSupport = FALSE;
AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx.Uint32);
if (RegEdx.Bits.Page1GB != 0) {
Page1GSupport = TRUE;
}
}
//
// Decide Paging Mode according Page5LevelSupport & Page1GSupport.
//
if (Page5LevelSupport) {
PagingMode = Page1GSupport ? Paging5Level1GB : Paging5Level;
} else {
PagingMode = Page1GSupport ? Paging4Level1GB : Paging4Level;
}
} else {
PagingMode = PagingPae;
}
MapAttribute.Uint64 = 0;
MapMask.Uint64 = 0;
MapMask.Bits.Nx = 1;
PageTable = AsmReadCr3 () & PAGING_4K_ADDRESS_MASK_64;
BufferSize = 0;
//
// Get required buffer size for changing the pagetable.
//
Status = PageTableMap (&PageTable, PagingMode, 0, &BufferSize, BaseAddress, Length, &MapAttribute, &MapMask, NULL);
if (Status == EFI_BUFFER_TOO_SMALL) {
//
// Allocate required Buffer.
//
Status = PeiServicesAllocatePages (
EfiBootServicesData,
EFI_SIZE_TO_PAGES (BufferSize),
&Buffer
);
ASSERT_EFI_ERROR (Status);
Status = PageTableMap (&PageTable, PagingMode, (VOID *)(UINTN)Buffer, &BufferSize, BaseAddress, Length, &MapAttribute, &MapMask, NULL);
}
ASSERT_EFI_ERROR (Status);
AsmWriteCr3 (PageTable);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,153 +0,0 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
; MpFuncs.nasm
;
; Abstract:
;
; This is the assembly code for Multi-processor S3 support
;
;-------------------------------------------------------------------------------
SECTION .text
extern ASM_PFX(InitializeFloatingPointUnits)
%define VacantFlag 0x0
%define NotVacantFlag 0xff
%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart
%define StackStart LockLocation + 0x4
%define StackSize LockLocation + 0x8
%define RendezvousProc LockLocation + 0xC
%define GdtrProfile LockLocation + 0x10
%define IdtrProfile LockLocation + 0x16
%define BufferStart LockLocation + 0x1C
;-------------------------------------------------------------------------------------
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
;procedure serializes all the AP processors through an Init sequence. It must be
;noted that APs arrive here very raw...ie: real mode, no stack.
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
;IS IN MACHINE CODE.
;-------------------------------------------------------------------------------------
;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
BITS 16
global ASM_PFX(RendezvousFunnelProc)
ASM_PFX(RendezvousFunnelProc):
RendezvousFunnelProcStart:
; At this point CS = 0x(vv00) and ip= 0x0.
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
xor ax, ax
mov fs, ax
mov gs, ax
flat32Start:
mov si, BufferStart
mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer
mov si, GdtrProfile
o32 lgdt [cs:si]
mov si, IdtrProfile
o32 lidt [cs:si]
xor ax, ax
mov ds, ax
mov eax, cr0 ; Get control register 0
or eax, 0x000000001 ; Set PE bit (bit #0)
mov cr0, eax
FLAT32_JUMP:
a32 jmp dword 0x20:0x0
BITS 32
PMODE_ENTRY: ; protected mode entry point
mov ax, 0x8
o16 mov ds, ax
o16 mov es, ax
o16 mov fs, ax
o16 mov gs, ax
o16 mov ss, ax ; Flat mode setup.
mov esi, edx
mov edi, esi
add edi, LockLocation
mov al, NotVacantFlag
TestLock:
xchg byte [edi], al
cmp al, NotVacantFlag
jz TestLock
ProgramStack:
mov edi, esi
add edi, StackSize
mov eax, dword [edi]
mov edi, esi
add edi, StackStart
add eax, dword [edi]
mov esp, eax
mov dword [edi], eax
Releaselock:
mov al, VacantFlag
mov edi, esi
add edi, LockLocation
xchg byte [edi], al
;
; Call assembly function to initialize FPU.
;
mov ebx, ASM_PFX(InitializeFloatingPointUnits)
call ebx
;
; Call C Function
;
mov edi, esi
add edi, RendezvousProc
mov eax, dword [edi]
test eax, eax
jz GoToSleep
call eax ; Call C function
GoToSleep:
cli
hlt
jmp $-2
RendezvousFunnelProcEnd:
;-------------------------------------------------------------------------------------
; AsmGetAddressMap (&AddressMap);
;-------------------------------------------------------------------------------------
global ASM_PFX(AsmGetAddressMap)
ASM_PFX(AsmGetAddressMap):
pushad
mov ebp,esp
mov ebx, dword [ebp+0x24]
mov dword [ebx], RendezvousFunnelProcStart
mov dword [ebx+0x4], PMODE_ENTRY - RendezvousFunnelProcStart
mov dword [ebx+0x8], FLAT32_JUMP - RendezvousFunnelProcStart
mov dword [ebx+0xc], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
popad
ret

View File

@ -1,7 +1,7 @@
/** @file
SMM CPU misc functions for Ia32 arch specific.
Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -141,33 +141,6 @@ InitGdt (
return GdtTssTables;
}
/**
Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
@param[in] ApHltLoopCode The address of the safe hlt-loop function.
@param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode.
@param[in] NumberToFinishAddress Address of Semaphore of APs finish count.
**/
VOID
TransferApToSafeState (
IN UINTN ApHltLoopCode,
IN UINTN TopOfStack,
IN UINTN NumberToFinishAddress
)
{
SwitchStack (
(SWITCH_STACK_ENTRY_POINT)ApHltLoopCode,
(VOID *)NumberToFinishAddress,
NULL,
(VOID *)TopOfStack
);
//
// It should never reach here
//
ASSERT (FALSE);
}
/**
Initialize the shadow stack related data structure.

View File

@ -1,7 +1,7 @@
/** @file
Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
@ -435,8 +435,8 @@ ExecuteFirstSmiInit (
/**
SMM Ready To Lock event notification handler.
The CPU S3 data is copied to SMRAM for security and mSmmReadyToLock is set to
perform additional lock actions that must be performed from SMM on the next SMI.
mSmmReadyToLock is set to perform additional lock actions that must be
performed from SMM on the next SMI.
@param[in] Protocol Points to the protocol's unique identifier.
@param[in] Interface Points to the interface instance.
@ -452,8 +452,6 @@ SmmReadyToLockEventNotify (
IN EFI_HANDLE Handle
)
{
GetAcpiCpuData ();
//
// Cache a copy of UEFI memory map before we start profiling feature.
//

View File

@ -1,7 +1,7 @@
/** @file
Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>
@ -1048,15 +1048,6 @@ InitSmmS3ResumeState (
IN UINT32 Cr3
);
/**
Get ACPI CPU data.
**/
VOID
GetAcpiCpuData (
VOID
);
/**
Restore SMM Configuration in S3 boot path.
@ -1075,21 +1066,6 @@ GetAcpiS3EnableFlag (
VOID
);
/**
Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
@param[in] ApHltLoopCode The address of the safe hlt-loop function.
@param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode.
@param[in] NumberToFinishAddress Address of Semaphore of APs finish count.
**/
VOID
TransferApToSafeState (
IN UINTN ApHltLoopCode,
IN UINTN TopOfStack,
IN UINTN NumberToFinishAddress
);
/**
Set ShadowStack memory.

View File

@ -4,7 +4,7 @@
# This SMM driver performs SMM initialization, deploy SMM Entry Vector,
# provides CPU specific services in SMM.
#
# Copyright (c) 2009 - 2023, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2009 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
# Copyright (C) 2023 - 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
#
@ -53,7 +53,6 @@
Ia32/SmmProfileArch.h
Ia32/SmiEntry.nasm
Ia32/SmiException.nasm
Ia32/MpFuncs.nasm
Ia32/Cet.nasm
[Sources.X64]
@ -63,7 +62,6 @@
X64/SmmProfileArch.h
X64/SmiEntry.nasm
X64/SmiException.nasm
X64/MpFuncs.nasm
X64/Cet.nasm
[Packages]
@ -136,7 +134,6 @@
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## SOMETIMES_CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## SOMETIMES_PRODUCES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES
gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES

View File

@ -1,189 +0,0 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
; MpFuncs.nasm
;
; Abstract:
;
; This is the assembly code for Multi-processor S3 support
;
;-------------------------------------------------------------------------------
%define VacantFlag 0x0
%define NotVacantFlag 0xff
%define LockLocation RendezvousFunnelProcEnd - RendezvousFunnelProcStart
%define StackStartAddressLocation LockLocation + 0x8
%define StackSizeLocation LockLocation + 0x10
%define CProcedureLocation LockLocation + 0x18
%define GdtrLocation LockLocation + 0x20
%define IdtrLocation LockLocation + 0x2A
%define BufferStartLocation LockLocation + 0x34
%define Cr3OffsetLocation LockLocation + 0x38
%define InitializeFloatingPointUnitsAddress LockLocation + 0x3C
;-------------------------------------------------------------------------------------
;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
;procedure serializes all the AP processors through an Init sequence. It must be
;noted that APs arrive here very raw...ie: real mode, no stack.
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
;IS IN MACHINE CODE.
;-------------------------------------------------------------------------------------
;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
;text SEGMENT
DEFAULT REL
SECTION .text
BITS 16
global ASM_PFX(RendezvousFunnelProc)
ASM_PFX(RendezvousFunnelProc):
RendezvousFunnelProcStart:
; At this point CS = 0x(vv00) and ip= 0x0.
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
xor ax, ax
mov fs, ax
mov gs, ax
flat32Start:
mov si, BufferStartLocation
mov edx,dword [si] ; EDX is keeping the start address of wakeup buffer
mov si, Cr3OffsetLocation
mov ecx,dword [si] ; ECX is keeping the value of CR3
mov si, GdtrLocation
o32 lgdt [cs:si]
mov si, IdtrLocation
o32 lidt [cs:si]
xor ax, ax
mov ds, ax
mov eax, cr0 ; Get control register 0
or eax, 0x000000001 ; Set PE bit (bit #0)
mov cr0, eax
FLAT32_JUMP:
a32 jmp dword 0x20:0x0
BITS 32
PMODE_ENTRY: ; protected mode entry point
mov ax, 0x18
o16 mov ds, ax
o16 mov es, ax
o16 mov fs, ax
o16 mov gs, ax
o16 mov ss, ax ; Flat mode setup.
mov eax, cr4
bts eax, 5
mov cr4, eax
mov cr3, ecx
mov esi, edx ; Save wakeup buffer address
mov ecx, 0xc0000080 ; EFER MSR number.
rdmsr ; Read EFER.
bts eax, 8 ; Set LME=1.
wrmsr ; Write EFER.
mov eax, cr0 ; Read CR0.
bts eax, 31 ; Set PG=1.
mov cr0, eax ; Write CR0.
LONG_JUMP:
a16 jmp dword 0x38:0x0
BITS 64
LongModeStart:
mov ax, 0x30
o16 mov ds, ax
o16 mov es, ax
o16 mov ss, ax
mov edi, esi
add edi, LockLocation
mov al, NotVacantFlag
TestLock:
xchg byte [edi], al
cmp al, NotVacantFlag
jz TestLock
ProgramStack:
mov edi, esi
add edi, StackSizeLocation
mov rax, qword [edi]
mov edi, esi
add edi, StackStartAddressLocation
add rax, qword [edi]
mov rsp, rax
mov qword [edi], rax
Releaselock:
mov al, VacantFlag
mov edi, esi
add edi, LockLocation
xchg byte [edi], al
;
; Call assembly function to initialize FPU.
;
mov rax, qword [esi + InitializeFloatingPointUnitsAddress]
sub rsp, 0x20
call rax
add rsp, 0x20
;
; Call C Function
;
mov edi, esi
add edi, CProcedureLocation
mov rax, qword [edi]
test rax, rax
jz GoToSleep
sub rsp, 0x20
call rax
add rsp, 0x20
GoToSleep:
cli
hlt
jmp $-2
RendezvousFunnelProcEnd:
;-------------------------------------------------------------------------------------
; AsmGetAddressMap (&AddressMap);
;-------------------------------------------------------------------------------------
; comments here for definition of address map
global ASM_PFX(AsmGetAddressMap)
ASM_PFX(AsmGetAddressMap):
lea rax, [RendezvousFunnelProcStart]
mov qword [rcx], rax
mov qword [rcx+0x8], PMODE_ENTRY - RendezvousFunnelProcStart
mov qword [rcx+0x10], FLAT32_JUMP - RendezvousFunnelProcStart
mov qword [rcx+0x18], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
mov qword [rcx+0x20], LongModeStart - RendezvousFunnelProcStart
mov qword [rcx+0x28], LONG_JUMP - RendezvousFunnelProcStart
ret

View File

@ -1,7 +1,7 @@
/** @file
SMM CPU misc functions for x64 arch specific.
Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2015 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@ -132,34 +132,6 @@ GetProtectedModeCS (
return Index * 8;
}
/**
Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch.
@param[in] ApHltLoopCode The address of the safe hlt-loop function.
@param[in] TopOfStack A pointer to the new stack to use for the ApHltLoopCode.
@param[in] NumberToFinishAddress Address of Semaphore of APs finish count.
**/
VOID
TransferApToSafeState (
IN UINTN ApHltLoopCode,
IN UINTN TopOfStack,
IN UINTN NumberToFinishAddress
)
{
AsmDisablePaging64 (
GetProtectedModeCS (),
(UINT32)ApHltLoopCode,
(UINT32)NumberToFinishAddress,
0,
(UINT32)TopOfStack
);
//
// It should never reach here
//
ASSERT (FALSE);
}
/**
Initialize the shadow stack related data structure.

View File

@ -1,7 +1,7 @@
## @file UefiCpuPkg.dec
# This Package provides UEFI compatible CPU modules and libraries.
#
# Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights reserved.<BR>
# Copyright (c) 2024, Loongson Technology Corporation Limited. All rights reserved.<BR>
#
@ -310,7 +310,7 @@
## Specifies if CPU features will be initialized during S3 resume.
# @Prompt If CPU features will be initialized during S3 resume.
gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume|FALSE|BOOLEAN|0x0000001D
gUefiCpuPkgTokenSpaceGuid.PcdCpuFeaturesInitOnS3Resume|TRUE|BOOLEAN|0x0000001D
## Specifies CPUID Leaf 0x15 Time Stamp Counter and Nominal Core Crystal Clock Frequency.
# TSC Frequency = ECX (core crystal clock frequency) * EBX/EAX.

View File

@ -1,7 +1,7 @@
## @file
# UefiCpuPkg Package
#
# Copyright (c) 2007 - 2023, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (C) 2023 - 2024, Advanced Micro Devices, Inc. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@ -68,6 +68,7 @@
UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf
UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf
UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultReportLib/UnitTestResultReportLibDebugLib.inf
LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxDxeLib.inf
[LibraryClasses.common.SEC]
PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.inf

View File

@ -4,7 +4,7 @@
This module will execute the boot script saved during last boot and after that,
control is passed to OS waking up handler.
Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2024, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -39,6 +39,7 @@
#include <Library/DebugAgentLib.h>
#include <Library/LocalApicLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Library/MtrrLib.h>
#include <Library/HobLib.h>
#include <Library/LockBoxLib.h>
@ -259,6 +260,12 @@ EFI_PEI_PPI_DESCRIPTOR mPpiListS3SmmInitDoneTable = {
0
};
EFI_PEI_PPI_DESCRIPTOR mPpiListEndOfS3ResumeTable = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEdkiiEndOfS3ResumeGuid,
0
};
//
// Global Descriptor Table (GDT)
//
@ -489,6 +496,13 @@ S3ResumeBootOs (
PERF_INMODULE_BEGIN ("EndOfS3Resume");
DEBUG ((DEBUG_INFO, "Signal EndOfS3Resume\n"));
//
// Install EndOfS3Resume.
//
Status = PeiServicesInstallPpi (&mPpiListEndOfS3ResumeTable);
ASSERT_EFI_ERROR (Status);
//
// Signal EndOfS3Resume to SMM.
//
@ -938,6 +952,20 @@ S3ResumeExecuteBootScript (
CpuDeadLoop ();
}
/**
Sync up the MTRR values for all processors.
@param[in] MtrrTable Address of MTRR setting.
**/
VOID
EFIAPI
LoadMtrrData (
IN VOID *MtrrTable
)
{
MtrrSetAllMtrrs (MtrrTable);
}
/**
Restores the platform to its preboot configuration for an S3 resume and
jumps to the OS waking vector.
@ -990,6 +1018,7 @@ S3RestoreConfig2 (
BOOLEAN InterruptStatus;
IA32_CR0 Cr0;
EDKII_PEI_MP_SERVICES2_PPI *MpService2Ppi;
MTRR_SETTINGS MtrrTable;
TempAcpiS3Context = 0;
TempEfiBootScriptExecutorVariable = 0;
@ -1082,6 +1111,39 @@ S3RestoreConfig2 (
Status = SmmAccess->Open ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);
}
//
// Get MP Services2 Ppi to pass it to Smm S3.
//
Status = PeiServicesLocatePpi (
&gEdkiiPeiMpServices2PpiGuid,
0,
NULL,
(VOID **)&MpService2Ppi
);
ASSERT_EFI_ERROR (Status);
//
// Restore MTRR setting
//
VarSize = sizeof (MTRR_SETTINGS);
Status = RestoreLockBox (
&gEdkiiS3MtrrSettingGuid,
&MtrrTable,
&VarSize
);
ASSERT_EFI_ERROR (Status);
//
// Sync up the MTRR values for all processors.
//
Status = MpService2Ppi->StartupAllCPUs (
MpService2Ppi,
(EFI_AP_PROCEDURE)LoadMtrrData,
0,
(VOID *)&MtrrTable
);
ASSERT_EFI_ERROR (Status);
SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *)GET_GUID_HOB_DATA (GuidHob);
SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart;
@ -1090,7 +1152,6 @@ S3RestoreConfig2 (
SmmS3ResumeState->ReturnContext1 = (EFI_PHYSICAL_ADDRESS)(UINTN)AcpiS3Context;
SmmS3ResumeState->ReturnContext2 = (EFI_PHYSICAL_ADDRESS)(UINTN)EfiBootScriptExecutorVariable;
SmmS3ResumeState->ReturnStackPointer = (EFI_PHYSICAL_ADDRESS)STACK_ALIGN_DOWN (&Status);
SmmS3ResumeState->MpService2Ppi = 0;
DEBUG ((DEBUG_INFO, "SMM S3 Signature = %x\n", SmmS3ResumeState->Signature));
DEBUG ((DEBUG_INFO, "SMM S3 Stack Base = %x\n", SmmS3ResumeState->SmmS3StackBase));
@ -1119,19 +1180,6 @@ S3RestoreConfig2 (
if (((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) && (sizeof (UINTN) == sizeof (UINT32))) ||
((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) && (sizeof (UINTN) == sizeof (UINT64))))
{
//
// Get MP Services2 Ppi to pass it to Smm S3.
//
Status = PeiServicesLocatePpi (
&gEdkiiPeiMpServices2PpiGuid,
0,
NULL,
(VOID **)&MpService2Ppi
);
ASSERT_EFI_ERROR (Status);
SmmS3ResumeState->MpService2Ppi = (EFI_PHYSICAL_ADDRESS)(UINTN)MpService2Ppi;
DEBUG ((DEBUG_INFO, "SMM S3 MpService2Ppi Point = %lx\n", SmmS3ResumeState->MpService2Ppi));
SwitchStack (
(SWITCH_STACK_ENTRY_POINT)(UINTN)SmmS3ResumeState->SmmS3ResumeEntryPoint,
(VOID *)AcpiS3Context,

View File

@ -5,7 +5,7 @@
# This module will excute the boot script saved during last boot and after that,
# control is passed to OS waking up handler.
#
# Copyright (c) 2010 - 2023, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2010 - 2024, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
@ -67,6 +67,7 @@
LocalApicLib
ReportStatusCodeLib
LockBoxLib
MtrrLib
[Guids]
gEfiBootScriptExecutorVariableGuid ## SOMETIMES_CONSUMES ## UNDEFINED # LockBox
@ -79,6 +80,7 @@
## SOMETIMES_PRODUCES ## UNDEFINED # Install PPI
## SOMETIMES_CONSUMES ## UNDEFINED # Used to do smm communication
gEdkiiS3SmmInitDoneGuid
gEdkiiS3MtrrSettingGuid
[Ppis]
gEfiPeiS3Resume2PpiGuid ## PRODUCES

View File

@ -55,11 +55,13 @@ FIT Format URL: https://universalpayload.github.io/spec/chapter2-payload-image-f
```
- FIT
- Windows
```
Download and install swig by https://swig.org/ and also set install path into environment variable
```
```powershell
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
choco install dtc-msys2
pip3 install pefile
pip3 install swig
pip3 install pylibfdt
```
- Ubuntu

View File

@ -12,9 +12,9 @@
# https://www.python.org/dev/peps/pep-0440/#version-specifiers
##
edk2-pytool-library==0.20.0
edk2-pytool-extensions==0.26.4
edk2-pytool-library==0.21.5
edk2-pytool-extensions==0.27.5
edk2-basetools==0.1.51
antlr4-python3-runtime==4.7.1
lcov-cobertura==2.0.2
regex==2023.12.25
regex==2024.5.15