diff --git a/edk2basetools/GenCrc32/GenCrc32.py b/edk2basetools/GenCrc32/GenCrc32.py
new file mode 100644
index 00000000..c407a50b
--- /dev/null
+++ b/edk2basetools/GenCrc32/GenCrc32.py
@@ -0,0 +1,103 @@
+## @file
+# Calculate Crc32 value and Verify Crc32 value for input data.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+##
+# Import Modules
+#
+import logging
+import argparse
+import sys
+from binascii import crc32
+
+
+parser = argparse.ArgumentParser(description='''
+Calculate Crc32 value and Verify Crc32 value for input data.
+''')
+parser.add_argument("-e", "--encode", dest="EncodeInputFile",
+ help="Calculate andverify CRC32 value for the input file.")
+parser.add_argument("-d", "--decode", dest="DecodeInputFile",
+ help="Verify CRC32 value for the input file.")
+parser.add_argument("-o", "--output", dest="OutputFile",
+ help="Output file name.")
+parser.add_argument("-s", "--silent", help="Returns only the exit code;\
+ informational and error messages are not displayed.")
+parser.add_argument("--version", action="version", version='%(prog)s Version 2.0',
+ help="Show program's version number and exit.")
+
+group = parser.add_mutually_exclusive_group()
+group.add_argument("-v", "--verbose", action="store_true", help="Print information statements")
+group.add_argument("-q", "--quiet", action="store_true", help="Disable all messages except fatal errors")
+
+
+## Calculate the Crc32 and store it in the file
+def CalculateCrc32(inputfile: str, outputfile: str, filebytes=b''):
+ logger = logging.getLogger('GenCrC32')
+ try:
+ if filebytes != b'':
+ InputData = filebytes
+ CrcCheckSum = crc32(InputData).to_bytes(4, byteorder="little")
+ else:
+ with open(inputfile, 'rb') as fin:
+ InputData = fin.read()
+ CrcCheckSum = crc32(InputData).to_bytes(4, byteorder="little")
+ with open(outputfile, 'wb') as fout:
+ fout.write(CrcCheckSum)
+ fout.write(InputData)
+ except Exception as err:
+ logger.error("Calculation failed!")
+ raise (err)
+ return CrcCheckSum
+
+
+## Verify the CRC and checkout if the file is correct
+def VerifyCrc32(inputfile: str, outputfile=""):
+ logger = logging.getLogger('GenCrC32')
+ try:
+ with open(inputfile, 'rb') as fin:
+ InputData = fin.read()
+ CurCrcCheckSum = InputData[0:4]
+ CalCrcCheckSum = CalculateCrc32('', '', InputData[4:])
+ if CurCrcCheckSum != CalCrcCheckSum:
+ logger.error("Invalid file!")
+ elif outputfile != "":
+ with open(outputfile, 'wb') as fout:
+ fout.write(InputData[4:])
+ except Exception as err:
+ logger.error("Verification failed!")
+ raise (err)
+
+
+def main():
+ args = parser.parse_args()
+
+ logger = logging.getLogger('GenCrc32')
+ if args.quiet:
+ logger.setLevel(logging.CRITICAL)
+ if args.verbose:
+ logger.setLevel(logging.DEBUG)
+ lh = logging.StreamHandler(sys.stdout)
+ lf = logging.Formatter("%(levelname)-8s: %(message)s")
+ lh.setFormatter(lf)
+ logger.addHandler(lh)
+
+ try:
+ if not args.OutputFile:
+ parser.print_help()
+ logger.error("Missing options - outputfile!")
+ assert ()
+ if args.EncodeInputFile:
+ CalculateCrc32(args.EncodeInputFile, args.OutputFile)
+ elif args.DecodeInputFile:
+ VerifyCrc32(args.DecodeInputFile, args.OutputFile)
+ except Exception:
+ return 1
+ return 0
+
+
+if __name__ == "__main__":
+ exit(main())
diff --git a/edk2basetools/GenCrc32/__init__.py b/edk2basetools/GenCrc32/__init__.py
new file mode 100644
index 00000000..b35de32b
--- /dev/null
+++ b/edk2basetools/GenCrc32/__init__.py
@@ -0,0 +1,10 @@
+# @file
+# Calculate the crc32 value of file.
+#
+# Copyright (c) 2021, Intel Corporation. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+# Import Modules
diff --git a/edk2basetools/tests/GenCrc32/decode/PcdPeim b/edk2basetools/tests/GenCrc32/decode/PcdPeim
new file mode 100644
index 00000000..db03070a
Binary files /dev/null and b/edk2basetools/tests/GenCrc32/decode/PcdPeim differ
diff --git a/edk2basetools/tests/GenCrc32/decode/PcdPeim_crc32 b/edk2basetools/tests/GenCrc32/decode/PcdPeim_crc32
new file mode 100644
index 00000000..c2ccd306
Binary files /dev/null and b/edk2basetools/tests/GenCrc32/decode/PcdPeim_crc32 differ
diff --git a/edk2basetools/tests/GenCrc32/decode/S3Resume2Pei b/edk2basetools/tests/GenCrc32/decode/S3Resume2Pei
new file mode 100644
index 00000000..2d1d4482
Binary files /dev/null and b/edk2basetools/tests/GenCrc32/decode/S3Resume2Pei differ
diff --git a/edk2basetools/tests/GenCrc32/decode/S3Resume2Pei_crc32 b/edk2basetools/tests/GenCrc32/decode/S3Resume2Pei_crc32
new file mode 100644
index 00000000..d18f1728
Binary files /dev/null and b/edk2basetools/tests/GenCrc32/decode/S3Resume2Pei_crc32 differ
diff --git a/edk2basetools/tests/GenCrc32/decode/demo b/edk2basetools/tests/GenCrc32/decode/demo
new file mode 100644
index 00000000..9f9601c8
--- /dev/null
+++ b/edk2basetools/tests/GenCrc32/decode/demo
@@ -0,0 +1 @@
+This is a test file for the GenCrc32 python tool~
\ No newline at end of file
diff --git a/edk2basetools/tests/GenCrc32/decode/demo_crc b/edk2basetools/tests/GenCrc32/decode/demo_crc
new file mode 100644
index 00000000..546f91f4
--- /dev/null
+++ b/edk2basetools/tests/GenCrc32/decode/demo_crc
@@ -0,0 +1 @@
+U@"€This is a test file for the GenCrc32 python tool~
\ No newline at end of file
diff --git a/edk2basetools/tests/GenCrc32/encode/PcdPeim.efi b/edk2basetools/tests/GenCrc32/encode/PcdPeim.efi
new file mode 100644
index 00000000..db03070a
Binary files /dev/null and b/edk2basetools/tests/GenCrc32/encode/PcdPeim.efi differ
diff --git a/edk2basetools/tests/GenCrc32/encode/PcdPeim_crc32 b/edk2basetools/tests/GenCrc32/encode/PcdPeim_crc32
new file mode 100644
index 00000000..c2ccd306
Binary files /dev/null and b/edk2basetools/tests/GenCrc32/encode/PcdPeim_crc32 differ
diff --git a/edk2basetools/tests/GenCrc32/encode/S3Resume2Pei.efi b/edk2basetools/tests/GenCrc32/encode/S3Resume2Pei.efi
new file mode 100644
index 00000000..2d1d4482
Binary files /dev/null and b/edk2basetools/tests/GenCrc32/encode/S3Resume2Pei.efi differ
diff --git a/edk2basetools/tests/GenCrc32/encode/S3Resume2Pei_crc32 b/edk2basetools/tests/GenCrc32/encode/S3Resume2Pei_crc32
new file mode 100644
index 00000000..d18f1728
Binary files /dev/null and b/edk2basetools/tests/GenCrc32/encode/S3Resume2Pei_crc32 differ
diff --git a/edk2basetools/tests/GenCrc32/encode/demo.bin b/edk2basetools/tests/GenCrc32/encode/demo.bin
new file mode 100644
index 00000000..9f9601c8
--- /dev/null
+++ b/edk2basetools/tests/GenCrc32/encode/demo.bin
@@ -0,0 +1 @@
+This is a test file for the GenCrc32 python tool~
\ No newline at end of file
diff --git a/edk2basetools/tests/GenCrc32/encode/demo_crc b/edk2basetools/tests/GenCrc32/encode/demo_crc
new file mode 100644
index 00000000..546f91f4
--- /dev/null
+++ b/edk2basetools/tests/GenCrc32/encode/demo_crc
@@ -0,0 +1 @@
+U@"€This is a test file for the GenCrc32 python tool~
\ No newline at end of file
diff --git a/edk2basetools/tests/GenCrc32/test_gencrc32.py b/edk2basetools/tests/GenCrc32/test_gencrc32.py
new file mode 100644
index 00000000..e8cfd248
--- /dev/null
+++ b/edk2basetools/tests/GenCrc32/test_gencrc32.py
@@ -0,0 +1,117 @@
+## @file
+# Calculate Crc32 value and Verify Crc32 value for input data.
+#
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+
+## Import Modules
+import shutil
+import unittest
+import tempfile
+import os
+import edk2basetools.GenCrc32.GenCrc32 as Gen
+import filecmp
+import struct as st
+
+
+class TestGenCrc32(unittest.TestCase):
+ def setUp(self):
+ self.tmpdir = tempfile.mkdtemp()
+ self.binary_file = os.path.join(self.tmpdir, "Binary.bin")
+ self.create_inputfile()
+ self.decode_output_folder = os.path.join(os.path.dirname(__file__), r"decode\decode_result")
+ if not os.path.exists(self.decode_output_folder):
+ os.mkdir(self.decode_output_folder)
+ self.encode_output_folder = os.path.join(os.path.dirname(__file__), r"encode\encode_result")
+ if not os.path.exists(self.encode_output_folder):
+ os.mkdir(self.encode_output_folder)
+
+ def tearDown(self):
+ if os.path.exists(self.tmpdir):
+ shutil.rmtree(self.tmpdir)
+ # if os.path.exists(self.decode_output_folder):
+ # shutil.rmtree(self.decode_output_folder)
+ # if os.path.exists(self.encode_output_folder):
+ # shutil.rmtree(self.encode_output_folder)
+
+ def create_inputfile(self):
+ with open(self.binary_file, "wb") as fout:
+ for i in range(512):
+ fout.write(st.pack("