aboutsummaryrefslogtreecommitdiff
path: root/MdePkg/Library/DynamicStackCookieEntryPointLib
diff options
context:
space:
mode:
Diffstat (limited to 'MdePkg/Library/DynamicStackCookieEntryPointLib')
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S56
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c70
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf45
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm63
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm63
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c65
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf38
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c135
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni17
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf53
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c112
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf45
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c162
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni16
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf68
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm63
-rw-r--r--MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm63
19 files changed, 1166 insertions, 0 deletions
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S b/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S
new file mode 100644
index 000000000000..f508f692d3f9
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/AArch64/DynamicCookieGcc.S
@@ -0,0 +1,56 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+# Module Name:
+#
+# DynamicCookie.S
+#
+# Abstract:
+#
+# Generates random number through the RNDR instruction on a 64-bit AARCH64 platform
+# to store a random value in the GCC __stack_check_guard stack cookie.
+# The first byte is 0'd to prevent string copy functions from clobbering
+# the stack cookie.
+#
+# Notes:
+#
+# If RNDR fails, the build time static stack cookie value will be used instead.
+#
+#------------------------------------------------------------------------------
+
+#include <AArch64/AArch64.h>
+
+.text
+.p2align 2
+
+GCC_ASM_IMPORT(__stack_chk_guard)
+GCC_ASM_IMPORT(_CModuleEntryPoint)
+GCC_ASM_EXPORT(_ModuleEntryPoint)
+
+#------------------------------------------------------------------------------
+# VOID
+# EFIAPI
+# _ModuleEntryPoint (
+# Parameters are passed through.
+# )
+#------------------------------------------------------------------------------
+ASM_PFX(_ModuleEntryPoint):
+ AARCH64_BTI(c)
+
+ mrs x9, ID_AA64ISAR0_EL1 // Read the AArch64 Instruction Set Attribute Register 0
+ ubfx x9, x9, #60, #4 // Extract the RNDR bit field (bits 60-63)
+ cbz x9, c_entry // If RNDR is not supported, jump to c_entry
+
+ mrs x9, RNDR // Generate a random number
+ b.eq c_entry // RNDR sets NZCV to 0b0100 on failure
+ // So if the zero flag is set, use the static stack guard
+
+ and x9, x9, #0xFFFFFFFFFFFFFF00 // Zero the first byte of the random value
+
+ adrp x8, ASM_PFX(__stack_chk_guard) // Load the page address of __stack_chk_guard
+ str x9, [x8, :lo12:ASM_PFX(__stack_chk_guard)] // Store the random value in __stack_chk_guard
+
+c_entry:
+ b ASM_PFX(_CModuleEntryPoint) // Jump to the C module entry point
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c
new file mode 100644
index 000000000000..5118132bd2c3
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.c
@@ -0,0 +1,70 @@
+/** @file
+ Entry point to the DXE Core.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/DxeCoreEntryPoint.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+//
+// Cache copy of HobList pointer.
+//
+VOID *gHobList = NULL;
+
+/**
+ The entry point of PE/COFF Image for the DXE Core.
+
+ This function is the entry point for the DXE Core. This function is required to call
+ ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return.
+ The DXE Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI
+ System Table and the image handle for the DXE Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param HobStart The pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+_CModuleEntryPoint (
+ IN VOID *HobStart
+ )
+{
+ //
+ // Cache a pointer to the HobList
+ //
+ gHobList = HobStart;
+
+ //
+ // Call the DXE Core entry point
+ //
+ ProcessModuleEntryPointList (HobStart);
+
+ //
+ // Should never return
+ //
+ ASSERT (FALSE);
+ CpuDeadLoop ();
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in HobStart.
+
+ @param HobStart The pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+EfiMain (
+ IN VOID *HobStart
+ )
+{
+ _ModuleEntryPoint (HobStart);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni
new file mode 100644
index 000000000000..e6515659a9e0
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCore/DxeCoreEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for DXE core.
+//
+// Module entry point library for DXE core.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for DXE core"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for DXE core."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
new file mode 100644
index 000000000000..1da877ae1d97
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/DxeCoreEntryPoint.inf
@@ -0,0 +1,45 @@
+## @file
+# Module entry point library for DXE core that dynamically updates the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeCoreEntryPointDynamicInit
+ MODULE_UNI_FILE = DxeCore/DxeCoreEntryPoint.uni
+ FILE_GUID = FD044D85-1407-4043-B527-471F16ABD8C6
+ MODULE_TYPE = DXE_CORE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DxeCoreEntryPoint|DXE_CORE
+
+
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ DxeCore/DxeCoreEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm
new file mode 100644
index 000000000000..c3c3e0e9931c
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieGcc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on a 32-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+extern ASM_PFX(__stack_chk_guard)
+extern ASM_PFX(_CModuleEntryPoint)
+global ASM_PFX(_ModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through
+; );
+;------------------------------------------------------------------------------
+global _ModuleEntryPoint
+_ModuleEntryPoint:
+ push ebx
+ push ecx
+ push edx
+
+ mov eax, 1 ; CPUID function 1
+ cpuid
+ test ecx, 0x40000000 ; Check if the RdRand bit (bit 30) is set in ECX
+ jz c_entry ; If not set, jump to c_entry
+
+ rdrand eax ; Use rdrand, getting a 32 bit value as on
+ ; IA32, __stack_chk_guard is a 32 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't update __stack_chk_guard, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea ebx, [ASM_PFX(__stack_chk_guard)] ; load the address of __stack_chk_guard into ebx
+
+ xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [ebx], eax ; Store our random value, with 0'd first byte to __stack_chk_guard
+
+c_entry:
+ pop edx
+ pop ecx
+ pop ebx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm
new file mode 100644
index 000000000000..2b8ec94fdbe9
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/IA32/DynamicCookieMsvc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on a 32-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+SECTION .text
+
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(_CModuleEntryPoint)
+global ASM_PFX(_ModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through
+; );
+;------------------------------------------------------------------------------
+global _ModuleEntryPoint
+_ModuleEntryPoint:
+ push ebx
+ push ecx
+ push edx
+
+ mov eax, 1 ; CPUID function 1
+ cpuid
+ test ecx, 0x40000000 ; Check if the RdRand bit (bit 30) is set in ECX
+ jz c_entry ; If not set, jump to c_entry
+
+ rdrand eax ; Use rdrand, getting a 32 bit value as on
+ ; IA32, __security_cookie is a 32 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't update __security_cookie, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea ebx, [ASM_PFX(__security_cookie)] ; load the address of __stack_chk_guard into ebx
+
+ xor ah, ah ; Zero a byte of the __security_cookie value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [ebx], eax ; Store our random value, with 0'd first byte to __security_cookie
+
+c_entry:
+ pop edx
+ pop ecx
+ pop ebx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c
new file mode 100644
index 000000000000..204702727319
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c
@@ -0,0 +1,65 @@
+/** @file
+ Entry point to the Standalone Mm Core.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+Copyright (c) Microsoft Corporation.
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiMm.h>
+
+#include <Library/StandaloneMmCoreEntryPoint.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+
+//
+// Cache copy of HobList pointer.
+//
+VOID *gHobList = NULL;
+
+/**
+ The entry point of PE/COFF Image for the STANDALONE MM Core.
+
+ This function is the entry point for the STANDALONE MM Core. This function is required to call
+ ProcessModuleEntryPointList() and ProcessModuleEntryPointList() is never expected to return.
+ The STANDALONE MM Core is responsible for calling ProcessLibraryConstructorList() as soon as the EFI
+ System Table and the image handle for the STANDALONE MM Core itself have been established.
+ If ProcessModuleEntryPointList() returns, then ASSERT() and halt the system.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+_CModuleEntryPoint (
+ IN VOID *HobStart
+ )
+{
+ //
+ // Cache a pointer to the HobList
+ //
+ gHobList = HobStart;
+
+ //
+ // Call the Standalone MM Core entry point
+ //
+ ProcessModuleEntryPointList (HobStart);
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in HobStart.
+
+ @param HobStart Pointer to the beginning of the HOB List passed in from the PEI Phase.
+
+**/
+VOID
+EFIAPI
+EfiMain (
+ IN VOID *HobStart
+ )
+{
+ _ModuleEntryPoint (HobStart);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
new file mode 100644
index 000000000000..b82415e6b8fc
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmCoreEntryPoint.inf
@@ -0,0 +1,38 @@
+## @file
+# Module entry point library for StandaloneMm core that dynamically updates the stack cookie.
+# The AARCH64 version of this library lives in ArmPkg.
+#
+# Copyright (c) 2017 - 2021, Arm Ltd. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = StandaloneMmCoreEntryPointDynamicInit
+ FILE_GUID = 490073A1-4DBC-4E9E-B30D-A4204139FC5F
+ MODULE_TYPE = MM_CORE_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = StandaloneMmCoreEntryPoint|MM_CORE_STANDALONE
+
+#
+# VALID_ARCHITECTURES = X64
+#
+
+[Sources.X64]
+ StandaloneMmCore/X64/StandaloneMmCoreEntryPoint.c
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c
new file mode 100644
index 000000000000..51df419953d5
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.c
@@ -0,0 +1,135 @@
+/** @file
+ Entry point to a Standalone MM driver.
+
+Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2016 - 2018, ARM Ltd. All rights reserved.<BR>
+Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR>
+
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiMm.h>
+
+#include <Protocol/LoadedImage.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MmServicesTableLib.h>
+#include <Library/StandaloneMmDriverEntryPoint.h>
+
+/**
+ Unloads an image from memory.
+
+ This function is a callback that a driver registers to do cleanup
+ when the UnloadImage boot service function is called.
+
+ @param ImageHandle The handle to the image to unload.
+
+ @return Status returned by all unload().
+
+**/
+EFI_STATUS
+EFIAPI
+_DriverUnloadHandler (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // If an UnloadImage() handler is specified, then call it
+ //
+ Status = ProcessModuleUnloadList (ImageHandle);
+
+ //
+ // If the driver specific unload handler does not return an error, then call all of the
+ // library destructors. If the unload handler returned an error, then the driver can not be
+ // unloaded, and the library destructors should not be called
+ //
+ if (!EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, gMmst);
+ }
+
+ //
+ // Return the status from the driver specific unload handler
+ //
+ return Status;
+}
+
+/**
+ The entry point of PE/COFF Image for a Standalone MM Driver.
+
+ This function is the entry point for a Standalone MM Driver.
+ This function must call ProcessLibraryConstructorList() and
+ ProcessModuleEntryPointList().
+ If the return status from ProcessModuleEntryPointList()
+ is an error status, then ProcessLibraryDestructorList() must be called.
+ The return value from ProcessModuleEntryPointList() is returned.
+ If _gMmRevision is not zero and SystemTable->Hdr.Revision is
+ less than _gMmRevision, then return EFI_INCOMPATIBLE_VERSION.
+
+ @param ImageHandle The image handle of the Standalone MM Driver.
+ @param MmSystemTable A pointer to the MM System Table.
+
+ @retval EFI_SUCCESS The Standalone MM Driver exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gMmRevision is greater than
+ MmSystemTable->Hdr.Revision.
+ @retval Other Return value from
+ ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN IN EFI_MM_SYSTEM_TABLE *MmSystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+
+ if (_gMmRevision != 0) {
+ //
+ // Make sure that the MM spec revision of the platform
+ // is >= MM spec revision of the driver
+ //
+ if (MmSystemTable->Hdr.Revision < _gMmRevision) {
+ return EFI_INCOMPATIBLE_VERSION;
+ }
+ }
+
+ //
+ // Call constructor for all libraries
+ //
+ ProcessLibraryConstructorList (ImageHandle, MmSystemTable);
+
+ //
+ // Install unload handler...
+ //
+ if (_gDriverUnloadImageCount != 0) {
+ Status = gMmst->MmHandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+ LoadedImage->Unload = _DriverUnloadHandler;
+ }
+
+ //
+ // Call the driver entry point
+ //
+ Status = ProcessModuleEntryPointList (ImageHandle, MmSystemTable);
+
+ //
+ // If all of the drivers returned errors, then invoke all of the library destructors
+ //
+ if (EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, MmSystemTable);
+ }
+
+ //
+ // Return the cumulative return status code from all of the driver entry points
+ //
+ return Status;
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni
new file mode 100644
index 000000000000..de36debd74ec
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni
@@ -0,0 +1,17 @@
+// /** @file
+//
+// Module entry point library for standalone MM driver
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+// Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+// Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for standalone MM driver"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for standalone MM driver."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
new file mode 100644
index 000000000000..a5cb42518c1b
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/StandaloneMmDriverEntryPoint.inf
@@ -0,0 +1,53 @@
+## @file
+# Module entry point library for Standalone MM drivers that dynamically updates the stack cookie.
+#
+# Copyright (c) 2015 - 2021, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016-2018, ARM Ltd. All rights reserved.<BR>
+# Copyright (c) 2018, Linaro, Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = StandaloneMmDriverEntryPointDynamicInit
+ MODULE_UNI_FILE = StandaloneMmDriver/StandaloneMmDriverEntryPoint.uni
+ FILE_GUID = 28CBCD87-2FEE-4D46-BB5C-B37732BBEEB1
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = StandaloneMmDriverEntryPoint|MM_STANDALONE
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = X64 AARCH64
+#
+
+[Sources]
+ StandaloneMmDriver/StandaloneMmDriverEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ MmServicesTableLib
+ StackCheckLib
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c
new file mode 100644
index 000000000000..81b9b55130e3
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/ApplicationEntryPoint.c
@@ -0,0 +1,112 @@
+/** @file
+ Entry point library instance to a UEFI application.
+
+Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Entry point to UEFI Application.
+
+ This function is the entry point for a UEFI Application. This function must call
+ ProcessLibraryConstructorList(), ProcessModuleEntryPointList(), and ProcessLibraryDestructorList().
+ The return value from ProcessModuleEntryPointList() is returned.
+ If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than _gUefiDriverRevison,
+ then return EFI_INCOMPATIBLE_VERSION.
+
+ @param ImageHandle The image handle of the UEFI Application.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The UEFI Application exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ if (_gUefiDriverRevision != 0) {
+ //
+ // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the application.
+ //
+ if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {
+ return EFI_INCOMPATIBLE_VERSION;
+ }
+ }
+
+ //
+ // Call constructor for all libraries.
+ //
+ ProcessLibraryConstructorList (ImageHandle, SystemTable);
+
+ //
+ // Call the module's entry point
+ //
+ Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);
+
+ //
+ // Process destructor for all libraries.
+ //
+ ProcessLibraryDestructorList (ImageHandle, SystemTable);
+
+ //
+ // Return the return status code from the driver entry point
+ //
+ return Status;
+}
+
+/**
+ Invokes the library destructors for all dependent libraries and terminates
+ the UEFI Application.
+
+ This function calls ProcessLibraryDestructorList() and the EFI Boot Service Exit()
+ with a status specified by Status.
+
+ @param Status Status returned by the application that is exiting.
+
+**/
+VOID
+EFIAPI
+Exit (
+ IN EFI_STATUS Status
+ )
+
+{
+ ProcessLibraryDestructorList (gImageHandle, gST);
+
+ gBS->Exit (gImageHandle, Status, 0, NULL);
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ @param ImageHandle The image handle of the UEFI Application.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The UEFI Application exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+EfiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return _ModuleEntryPoint (ImageHandle, SystemTable);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni
new file mode 100644
index 000000000000..168ce7469bb7
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplication/UefiApplicationEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for UEFI Application.
+//
+// Module entry point library for UEFI Application.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for UEFI Application"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for UEFI Application."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
new file mode 100644
index 000000000000..1a82fc498de1
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiApplicationEntryPoint.inf
@@ -0,0 +1,45 @@
+## @file
+# Module entry point library for UEFI Application that dynamically updates the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = UefiApplicationEntryPointDynamicInit
+ MODULE_UNI_FILE = UefiApplication/UefiApplicationEntryPoint.uni
+ FILE_GUID = 755B9094-E5AF-4E5B-BE33-D430CDE2C5D2
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiApplicationEntryPoint|UEFI_APPLICATION
+
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ UefiApplication/ApplicationEntryPoint.c
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ BaseLib
+ StackCheckLib
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c
new file mode 100644
index 000000000000..ad17e0d1c616
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/DriverEntryPoint.c
@@ -0,0 +1,162 @@
+/** @file
+ Entry point to a EFI/DXE driver.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Protocol/LoadedImage.h>
+
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Unloads an image from memory.
+
+ This function is a callback that a driver registers to do cleanup
+ when the UnloadImage boot service function is called.
+
+ @param ImageHandle The handle to the image to unload.
+
+ @return Status returned by all unload().
+
+**/
+EFI_STATUS
+EFIAPI
+_DriverUnloadHandler (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // If an UnloadImage() handler is specified, then call it
+ //
+ Status = ProcessModuleUnloadList (ImageHandle);
+
+ //
+ // If the driver specific unload handler does not return an error, then call all of the
+ // library destructors. If the unload handler returned an error, then the driver can not be
+ // unloaded, and the library destructors should not be called
+ //
+ if (!EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, gST);
+ }
+
+ //
+ // Return the status from the driver specific unload handler
+ //
+ return Status;
+}
+
+/**
+ The entry point of PE/COFF Image for a DXE Driver, DXE Runtime Driver, DXE SMM
+ Driver, or UEFI Driver.
+
+ This function is the entry point for a DXE Driver, DXE Runtime Driver, DXE SMM Driver,
+ or UEFI Driver. This function must call ProcessLibraryConstructorList() and
+ ProcessModuleEntryPointList(). If the return status from ProcessModuleEntryPointList()
+ is an error status, then ProcessLibraryDestructorList() must be called. The return
+ value from ProcessModuleEntryPointList() is returned. If _gDriverUnloadImageCount
+ is greater than zero, then an unload handler must be registered for this image
+ and the unload handler must invoke ProcessModuleUnloadList().
+ If _gUefiDriverRevision is not zero and SystemTable->Hdr.Revision is less than
+ _gUefiDriverRevison, then return EFI_INCOMPATIBLE_VERSION.
+
+
+ @param ImageHandle The image handle of the DXE Driver, DXE Runtime Driver,
+ DXE SMM Driver, or UEFI Driver.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The DXE Driver, DXE Runtime Driver, DXE SMM
+ Driver, or UEFI Driver exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than
+ SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+
+**/
+EFI_STATUS
+EFIAPI
+_CModuleEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+
+ if (_gUefiDriverRevision != 0) {
+ //
+ // Make sure that the EFI/UEFI spec revision of the platform is >= EFI/UEFI spec revision of the driver
+ //
+ if (SystemTable->Hdr.Revision < _gUefiDriverRevision) {
+ return EFI_INCOMPATIBLE_VERSION;
+ }
+ }
+
+ //
+ // Call constructor for all libraries
+ //
+ ProcessLibraryConstructorList (ImageHandle, SystemTable);
+
+ //
+ // Install unload handler...
+ //
+ if (_gDriverUnloadImageCount != 0) {
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID **)&LoadedImage
+ );
+ ASSERT_EFI_ERROR (Status);
+ LoadedImage->Unload = _DriverUnloadHandler;
+ }
+
+ //
+ // Call the driver entry point
+ //
+ Status = ProcessModuleEntryPointList (ImageHandle, SystemTable);
+
+ //
+ // If all of the drivers returned errors, then invoke all of the library destructors
+ //
+ if (EFI_ERROR (Status)) {
+ ProcessLibraryDestructorList (ImageHandle, SystemTable);
+ }
+
+ //
+ // Return the cummalative return status code from all of the driver entry points
+ //
+ return Status;
+}
+
+/**
+ Required by the EBC compiler and identical in functionality to _ModuleEntryPoint().
+
+ This function is required to call _ModuleEntryPoint() passing in ImageHandle,
+ and SystemTable.
+
+ @param ImageHandle The image handle of the DXE Driver, DXE Runtime Driver, DXE
+ SMM Driver, or UEFI Driver.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The DXE Driver, DXE Runtime Driver, DXE SMM
+ Driver, or UEFI Driver exited normally.
+ @retval EFI_INCOMPATIBLE_VERSION _gUefiDriverRevision is greater than
+ SystemTable->Hdr.Revision.
+ @retval Other Return value from ProcessModuleEntryPointList().
+**/
+EFI_STATUS
+EFIAPI
+EfiMain (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return _ModuleEntryPoint (ImageHandle, SystemTable);
+}
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni
new file mode 100644
index 000000000000..9d820b25f063
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriver/UefiDriverEntryPoint.uni
@@ -0,0 +1,16 @@
+// /** @file
+// Module entry point library for UEFI driver, DXE driver and SMM driver.
+//
+// Module entry point library for UEFI driver, DXE driver and SMM driver.
+//
+// Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Module entry point library for UEFI driver, DXE driver and SMM driver"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Module entry point library for UEFI driver, DXE driver and SMM driver."
+
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
new file mode 100644
index 000000000000..522bcd930c23
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/UefiDriverEntryPoint.inf
@@ -0,0 +1,68 @@
+## @file
+# Module entry point library for UEFI driver, DXE driver and SMM driver that dynamically sets the stack cookie.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = UefiDriverEntryPointDynamicInit
+ MODULE_UNI_FILE = UefiDriver/UefiDriverEntryPoint.uni
+ FILE_GUID = 900238F9-1421-4596-9548-A1BF58C97693
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = UefiDriverEntryPoint|DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_DRIVER SMM_CORE DXE_SMM_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources]
+ UefiDriver/DriverEntryPoint.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[Sources.IA32]
+ IA32/DynamicCookieGcc.nasm | GCC
+ IA32/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.X64]
+ X64/DynamicCookieGcc.nasm | GCC
+ X64/DynamicCookieMsvc.nasm | MSFT
+
+[Sources.AARCH64]
+ AArch64/DynamicCookieGcc.S | GCC
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ BaseLib
+ StackCheckLib
+
+[Protocols]
+ gEfiLoadedImageProtocolGuid ## SOMETIMES_CONSUMES
+
+#
+# For UEFI drivers, these architectural protocols defined in PI 1.0 spec need
+# to be appended and merged to the final dependency section.
+#
+[Depex.common.UEFI_DRIVER]
+ gEfiBdsArchProtocolGuid AND
+ gEfiCpuArchProtocolGuid AND
+ gEfiMetronomeArchProtocolGuid AND
+ gEfiMonotonicCounterArchProtocolGuid AND
+ gEfiRealTimeClockArchProtocolGuid AND
+ gEfiResetArchProtocolGuid AND
+ gEfiRuntimeArchProtocolGuid AND
+ gEfiSecurityArchProtocolGuid AND
+ gEfiTimerArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiWatchdogTimerArchProtocolGuid
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm
new file mode 100644
index 000000000000..782e8bbb791a
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieGcc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on 64-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(__stack_chk_guard)
+extern ASM_PFX(_CModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through. TODO: Make sure there are only two args on X64
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ push rbx
+ push rcx
+ push rdx
+
+ mov eax, 1 ; Set eax to 1 to get feature information
+ cpuid ; Call cpuid
+ test ecx, 0x40000000 ; Test the rdrand bit (bit 30) in ecx
+ jz c_entry ; If rdrand is not supported, jump to c_entry
+
+ rdrand rax ; Call rdrand functionality here, getting a 64 bit value as on
+ ; X64, __stack_chk_guard is a 64 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't, update __stack_chk_guard, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea rbx, [rel ASM_PFX(__stack_chk_guard)] ; load the address of __stack_check_guard into rbx
+
+ xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [rbx], rax ; Store our random value, with 0'd first byte to __stack_chk_guard
+
+c_entry:
+ pop rdx
+ pop rcx
+ pop rbx
+ jmp ASM_PFX(_CModuleEntryPoint)
diff --git a/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm
new file mode 100644
index 000000000000..bd290f712634
--- /dev/null
+++ b/MdePkg/Library/DynamicStackCookieEntryPointLib/X64/DynamicCookieMsvc.nasm
@@ -0,0 +1,63 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) Microsoft Corporation.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; DynamicCookie.nasm
+;
+; Abstract:
+;
+; Generates random number through CPU RdRand instruction on 64-bit platform
+; to store a random value in the GCC __stack_check_guard stack cookie.
+; The first byte is 0'd to prevent string copy functions from clobbering
+; the stack cookie.
+;
+; Notes:
+;
+; If RdRand fails, the build time static stack cookie value will be used instead.
+;
+;------------------------------------------------------------------------------
+
+DEFAULT REL
+SECTION .text
+
+extern ASM_PFX(__security_cookie)
+extern ASM_PFX(_CModuleEntryPoint)
+
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; _ModuleEntryPoint (
+; Parameters are passed through. TODO: Make sure there are only two args on X64
+; );
+;------------------------------------------------------------------------------
+global ASM_PFX(_ModuleEntryPoint)
+ASM_PFX(_ModuleEntryPoint):
+ push rbx
+ push rcx
+ push rdx
+
+ mov eax, 1 ; Set eax to 1 to get feature information
+ cpuid ; Call cpuid
+ test ecx, 0x40000000 ; Test the rdrand bit (bit 30) in ecx
+ jz c_entry ; If rdrand is not supported, jump to c_entry
+
+ rdrand rax ; Call rdrand functionality here, getting a 64 bit value as on
+ ; X64, __stack_chk_guard is a 64 bit value.
+ ; CF=1 if RN generated ok, otherwise CF=0
+ jnc c_entry ; If the cmd fails, don't, update __stack_chk_guard, we'll have to move forward
+ ; with the static value provided at build time.
+
+ lea rbx, [rel ASM_PFX(__security_cookie)] ; load the address of __stack_check_guard into rbx
+
+ xor ah, ah ; Zero a byte of the __stack_chk_guard value to protect against string functions
+ ; (such as strcpy like functions) clobbering past the canary
+ mov [rbx], rax ; Store our random value, with 0'd first byte to __stack_chk_guard
+
+c_entry:
+ pop rdx
+ pop rcx
+ pop rbx
+ jmp ASM_PFX(_CModuleEntryPoint)