Date   

[PATCH v9 08/16] FmpDevicePkg/FmpDevicePkg.ci.yaml: Add configuration for Ecc check

Zhang, Shenglei
 

Add configuration ExceptionList and IgnoreFiles for package config
files. So users can rely on this to ignore some Ecc issues.

Cc: Liming Gao <liming.gao@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Signed-off-by: Shenglei Zhang <shenglei.zhang@...>
Reviewed-by: Guomin Jiang <guomin.jiang@...>
Reviewed-by: Liming Gao <liming.gao@...>
---
FmpDevicePkg/FmpDevicePkg.ci.yaml | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/FmpDevicePkg/FmpDevicePkg.ci.yaml b/FmpDevicePkg/FmpDevicePkg.ci.yaml
index d498ad7d21e1..1b3e2187356d 100644
--- a/FmpDevicePkg/FmpDevicePkg.ci.yaml
+++ b/FmpDevicePkg/FmpDevicePkg.ci.yaml
@@ -2,12 +2,24 @@
# CI configuration for FmpDevicePkg
#
# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
"LicenseCheck": {
"IgnoreFiles": []
},
+ "EccCheck": {
+ ## Exception sample looks like below:
+ ## "ExceptionList": [
+ ## "<ErrorID>", "<KeyWord>"
+ ## ]
+ "ExceptionList": [
+ ],
+ ## Both file path and directory path are accepted.
+ "IgnoreFiles": [
+ ]
+ },
"CompilerPlugin": {
"DscPath": "FmpDevicePkg.dsc"
},
--
2.18.0.windows.1


[PATCH v9 07/16] FatPkg/FatPkg.ci.yaml: Add configuration for Ecc check

Zhang, Shenglei
 

Add configuration ExceptionList and IgnoreFiles for package config
files. So users can rely on this to ignore some Ecc issues.

Cc: Ray Ni <ray.ni@...>
Signed-off-by: Shenglei Zhang <shenglei.zhang@...>
Reviewed-by: Guomin Jiang <guomin.jiang@...>
Reviewed-by: Liming Gao <liming.gao@...>
---
FatPkg/FatPkg.ci.yaml | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/FatPkg/FatPkg.ci.yaml b/FatPkg/FatPkg.ci.yaml
index 489c4614e9e1..fe95f481b50c 100644
--- a/FatPkg/FatPkg.ci.yaml
+++ b/FatPkg/FatPkg.ci.yaml
@@ -2,12 +2,24 @@
# CI configuration for FatPkg
#
# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
"LicenseCheck": {
"IgnoreFiles": []
},
+ "EccCheck": {
+ ## Exception sample looks like below:
+ ## "ExceptionList": [
+ ## "<ErrorID>", "<KeyWord>"
+ ## ]
+ "ExceptionList": [
+ ],
+ ## Both file path and directory path are accepted.
+ "IgnoreFiles": [
+ ]
+ },
"CompilerPlugin": {
"DscPath": "FatPkg.dsc"
},
--
2.18.0.windows.1


[PATCH v9 06/16] EmulatorPkg/EmulatorPkg.ci.yaml: Add configuration for Ecc check

Zhang, Shenglei
 

Add configuration ExceptionList and IgnoreFiles for package config
files. So users can rely on this to ignore some Ecc issues.

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Andrew Fish <afish@...>
Cc: Ray Ni <ray.ni@...>
Signed-off-by: Shenglei Zhang <shenglei.zhang@...>
Acked-by: Ray Ni <ray.ni@...>
Reviewed-by: Liming Gao <liming.gao@...>
---
EmulatorPkg/EmulatorPkg.ci.yaml | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/EmulatorPkg/EmulatorPkg.ci.yaml b/EmulatorPkg/EmulatorPkg.ci.yaml
index dead82f69745..980844c1fdd4 100644
--- a/EmulatorPkg/EmulatorPkg.ci.yaml
+++ b/EmulatorPkg/EmulatorPkg.ci.yaml
@@ -5,6 +5,7 @@
# used for code analysis.
#
# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
@@ -12,6 +13,17 @@
"LicenseCheck": {
"IgnoreFiles": []
},
+ "EccCheck": {
+ ## Exception sample looks like below:
+ ## "ExceptionList": [
+ ## "<ErrorID>", "<KeyWord>"
+ ## ]
+ "ExceptionList": [
+ ],
+ ## Both file path and directory path are accepted.
+ "IgnoreFiles": [
+ ]
+ },
## options defined .pytool/Plugin/CompilerPlugin
"CompilerPlugin": {
"DscPath": "" # Don't support this test
--
2.18.0.windows.1


[PATCH v9 05/16] CryptoPkg/CryptoPkg.ci.yaml: Add configuration for Ecc check

Zhang, Shenglei
 

Add configuration ExceptionList and IgnoreFiles for package config
files. So users can rely on this to ignore some Ecc issues.
Besides, add submodule path in IgnoreFiles section.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Xiaoyu Lu <xiaoyux.lu@...>
Signed-off-by: Shenglei Zhang <shenglei.zhang@...>
---
CryptoPkg/CryptoPkg.ci.yaml | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/CryptoPkg/CryptoPkg.ci.yaml b/CryptoPkg/CryptoPkg.ci.yaml
index e73b79e01fef..e2d190a90c51 100644
--- a/CryptoPkg/CryptoPkg.ci.yaml
+++ b/CryptoPkg/CryptoPkg.ci.yaml
@@ -2,12 +2,25 @@
# CI configuration for CryptoPkg
#
# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
"LicenseCheck": {
"IgnoreFiles": []
},
+ "EccCheck": {
+ ## Exception sample looks like below:
+ ## "ExceptionList": [
+ ## "<ErrorID>", "<KeyWord>"
+ ## ]
+ "ExceptionList": [
+ ],
+ ## Both file path and directory path are accepted.
+ "IgnoreFiles": [
+ "Library/OpensslLib/openssl"
+ ]
+ },
"CompilerPlugin": {
"DscPath": "CryptoPkg.dsc"
},
--
2.18.0.windows.1


[PATCH v9 04/16] ArmVirtPkg/ArmVirtPkg.ci.yaml: Add configuration for Ecc check

Zhang, Shenglei
 

Add configuration ExceptionList and IgnoreFiles for package config
files. So users can rely on this to ignore some Ecc issues.

Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Leif Lindholm <leif@...>
Signed-off-by: Shenglei Zhang <shenglei.zhang@...>
Reviewed-by: Liming Gao <liming.gao@...>
---
ArmVirtPkg/ArmVirtPkg.ci.yaml | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/ArmVirtPkg/ArmVirtPkg.ci.yaml b/ArmVirtPkg/ArmVirtPkg.ci.yaml
index 27bb7ff49011..8b2c0305c175 100644
--- a/ArmVirtPkg/ArmVirtPkg.ci.yaml
+++ b/ArmVirtPkg/ArmVirtPkg.ci.yaml
@@ -5,6 +5,7 @@
# used for code analysis.
#
# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
@@ -12,6 +13,17 @@
"LicenseCheck": {
"IgnoreFiles": []
},
+ "EccCheck": {
+ ## Exception sample looks like below:
+ ## "ExceptionList": [
+ ## "<ErrorID>", "<KeyWord>"
+ ## ]
+ "ExceptionList": [
+ ],
+ ## Both file path and directory path are accepted.
+ "IgnoreFiles": [
+ ]
+ },
## options defined .pytool/Plugin/CompilerPlugin
"CompilerPlugin": {
"DscPath": "" # Don't support this test
--
2.18.0.windows.1


[PATCH v9 03/16] MdeModulePkg/MdeModulePkg.ci.yaml: Add configuration for Ecc check

Zhang, Shenglei
 

Add configuration ExceptionList and IgnoreFiles for package config
files. So users can rely on this to ignore some Ecc issues.
Besides, add submodule path in IgnoreFiles section.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Signed-off-by: Shenglei Zhang <shenglei.zhang@...>
---
MdeModulePkg/MdeModulePkg.ci.yaml | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/MdeModulePkg/MdeModulePkg.ci.yaml b/MdeModulePkg/MdeModulePkg.ci.yaml
index 0fc8c3633878..1a7e955185d8 100644
--- a/MdeModulePkg/MdeModulePkg.ci.yaml
+++ b/MdeModulePkg/MdeModulePkg.ci.yaml
@@ -2,6 +2,7 @@
# CI configuration for MdeModulePkg
#
# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
##
{
@@ -9,6 +10,19 @@
"LicenseCheck": {
"IgnoreFiles": []
},
+ "EccCheck": {
+ ## Exception sample looks like below:
+ ## "ExceptionList": [
+ ## "<ErrorID>", "<KeyWord>"
+ ## ]
+ "ExceptionList": [
+ ],
+ ## Both file path and directory path are accepted.
+ "IgnoreFiles": [
+ "Library/BrotliCustomDecompressLib/brotli",
+ "Universal/RegularExpressionDxe/oniguruma"
+ ]
+ },
## options defined ci/Plugin/CompilerPlugin
"CompilerPlugin": {
"DscPath": "MdeModulePkg.dsc"
--
2.18.0.windows.1


[PATCH v9 02/16] .pytool/Plugin: Add a plugin EccCheck

Zhang, Shenglei
 

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2606
EccCheck is a plugin to report Ecc issues for code in pull request
, which will be run on open ci.
But note not each kind of issue could be reported out.
It can only handle the issues, whose line number in CSV report
accurately map with their code in source code files. And Ecc issues
about comments can also be handled.

Cc: Sean Brogan <sean.brogan@...>
Cc: Bret Barkelew <Bret.Barkelew@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Signed-off-by: Shenglei Zhang <shenglei.zhang@...>
---
.pytool/Plugin/EccCheck/EccCheck.py | 302 ++++++++++++++++++
.pytool/Plugin/EccCheck/EccCheck_plug_in.yaml | 11 +
.pytool/Plugin/EccCheck/Readme.md | 15 +
3 files changed, 328 insertions(+)
create mode 100644 .pytool/Plugin/EccCheck/EccCheck.py
create mode 100644 .pytool/Plugin/EccCheck/EccCheck_plug_in.yaml
create mode 100644 .pytool/Plugin/EccCheck/Readme.md

diff --git a/.pytool/Plugin/EccCheck/EccCheck.py b/.pytool/Plugin/EccCheck/EccCheck.py
new file mode 100644
index 000000000000..249a16a7dddf
--- /dev/null
+++ b/.pytool/Plugin/EccCheck/EccCheck.py
@@ -0,0 +1,302 @@
+# @file EccCheck.py
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+import os
+import shutil
+import re
+import csv
+import xml.dom.minidom
+from typing import List, Dict, Tuple
+import logging
+from io import StringIO
+from edk2toolext.environment import shell_environment
+from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
+from edk2toolext.environment.var_dict import VarDict
+from edk2toollib.utility_functions import RunCmd
+
+
+class EccCheck(ICiBuildPlugin):
+ """
+ A CiBuildPlugin that finds the Ecc issues of newly added code in pull request.
+
+ Configuration options:
+ "EccCheck": {
+ "ExceptionList": [],
+ "IgnoreFiles": []
+ },
+ """
+
+ ReModifyFile = re.compile(r'[B-Q,S-Z]+[\d]*\t(.*)')
+ FindModifyFile = re.compile(r'\+\+\+ b\/(.*)')
+ LineScopePattern = (r'@@ -\d*\,*\d* \+\d*\,*\d* @@.*')
+ LineNumRange = re.compile(r'@@ -\d*\,*\d* \+(\d*)\,*(\d*) @@.*')
+
+ def GetTestName(self, packagename: str, environment: VarDict) -> tuple:
+ """ Provide the testcase name and classname for use in reporting
+ testclassname: a descriptive string for the testcase can include whitespace
+ classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
+
+ Args:
+ packagename: string containing name of package to build
+ environment: The VarDict for the test to run in
+ Returns:
+ a tuple containing the testcase name and the classname
+ (testcasename, classname)
+ """
+ return ("Check for efi coding style for " + packagename, packagename + ".EccCheck")
+
+ ##
+ # External function of plugin. This function is used to perform the task of the ci_build_plugin Plugin
+ #
+ # - package is the edk2 path to package. This means workspace/packagepath relative.
+ # - edk2path object configured with workspace and packages path
+ # - PkgConfig Object (dict) for the pkg
+ # - EnvConfig Object
+ # - Plugin Manager Instance
+ # - Plugin Helper Obj Instance
+ # - Junit Logger
+ # - output_stream the StringIO output stream from this plugin via logging
+ def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
+ edk2_path = Edk2pathObj.WorkspacePath
+ python_path = os.path.join(edk2_path, "BaseTools", "Source", "Python")
+ env = shell_environment.GetEnvironment()
+ env.set_shell_var('PYTHONPATH', python_path)
+ env.set_shell_var('WORKSPACE', edk2_path)
+ self.ECC_PASS = True
+ self.ApplyConfig(pkgconfig, edk2_path, packagename)
+ modify_dir_list = self.GetModifyDir(packagename)
+ patch = self.GetDiff(packagename)
+ ecc_diff_range = self.GetDiffRange(patch, packagename, edk2_path)
+ self.GenerateEccReport(modify_dir_list, ecc_diff_range, edk2_path)
+ ecc_log = os.path.join(edk2_path, "Ecc.log")
+ if self.ECC_PASS:
+ tc.SetSuccess()
+ self.RemoveFile(ecc_log)
+ return 0
+ else:
+ with open(ecc_log, encoding='utf8') as output:
+ ecc_output = output.readlines()
+ for line in ecc_output:
+ logging.error(line.strip())
+ self.RemoveFile(ecc_log)
+ tc.SetFailed("EccCheck failed for {0}".format(packagename), "Ecc detected issues")
+ return 1
+
+ def GetDiff(self, pkg: str) -> List[str]:
+ return_buffer = StringIO()
+ params = "diff --unified=0 origin/master HEAD"
+ RunCmd("git", params, outstream=return_buffer)
+ p = return_buffer.getvalue().strip()
+ patch = p.split("\n")
+ return_buffer.close()
+
+ return patch
+
+ def RemoveFile(self, file: str) -> None:
+ if os.path.exists(file):
+ os.remove(file)
+ return
+
+ def GetModifyDir(self, pkg: str) -> List[str]:
+ return_buffer = StringIO()
+ params = "diff --name-status" + ' HEAD' + ' origin/master'
+ RunCmd("git", params, outstream=return_buffer)
+ p1 = return_buffer.getvalue().strip()
+ dir_list = p1.split("\n")
+ return_buffer.close()
+ modify_dir_list = []
+ for modify_dir in dir_list:
+ file_path = self.ReModifyFile.findall(modify_dir)
+ if file_path:
+ file_dir = os.path.dirname(file_path[0])
+ else:
+ continue
+ if pkg in file_dir and file_dir != pkg:
+ modify_dir_list.append('%s' % file_dir)
+ else:
+ continue
+
+ modify_dir_list = list(set(modify_dir_list))
+ return modify_dir_list
+
+ def GetDiffRange(self, patch_diff: List[str], pkg: str, workingdir: str) -> Dict[str, List[Tuple[int, int]]]:
+ IsDelete = True
+ StartCheck = False
+ range_directory: Dict[str, List[Tuple[int, int]]] = {}
+ for line in patch_diff:
+ modify_file = self.FindModifyFile.findall(line)
+ if modify_file and pkg in modify_file[0] and not StartCheck and os.path.isfile(modify_file[0]):
+ modify_file_comment_dic = self.GetCommentRange(modify_file[0], workingdir)
+ IsDelete = False
+ StartCheck = True
+ modify_file_dic = modify_file[0]
+ modify_file_dic = modify_file_dic.replace("/", os.sep)
+ range_directory[modify_file_dic] = []
+ elif line.startswith('--- '):
+ StartCheck = False
+ elif re.match(self.LineScopePattern, line, re.I) and not IsDelete and StartCheck:
+ start_line = self.LineNumRange.search(line).group(1)
+ line_range = self.LineNumRange.search(line).group(2)
+ if not line_range:
+ line_range = '1'
+ range_directory[modify_file_dic].append((int(start_line), int(start_line) + int(line_range) - 1))
+ for i in modify_file_comment_dic:
+ if int(i[0]) <= int(start_line) <= int(i[1]):
+ range_directory[modify_file_dic].append(i)
+ return range_directory
+
+ def GetCommentRange(self, modify_file: str, workingdir: str) -> List[Tuple[int, int]]:
+ modify_file_path = os.path.join(workingdir, modify_file)
+ with open(modify_file_path) as f:
+ line_no = 1
+ comment_range: List[Tuple[int, int]] = []
+ Start = False
+ for line in f:
+ if line.startswith('/**'):
+ start_no = line_no
+ Start = True
+ if line.startswith('**/') and Start:
+ end_no = line_no
+ Start = False
+ comment_range.append((int(start_no), int(end_no)))
+ line_no += 1
+
+ if comment_range and comment_range[0][0] == 1:
+ del comment_range[0]
+ return comment_range
+
+ def GenerateEccReport(self, modify_dir_list: List[str], ecc_diff_range: Dict[str, List[Tuple[int, int]]],
+ edk2_path: str) -> None:
+ ecc_need = False
+ ecc_run = True
+ config = os.path.join(edk2_path, "BaseTools", "Source", "Python", "Ecc", "config.ini")
+ exception = os.path.join(edk2_path, "BaseTools", "Source", "Python", "Ecc", "exception.xml")
+ report = os.path.join(edk2_path, "Ecc.csv")
+ for modify_dir in modify_dir_list:
+ target = os.path.join(edk2_path, modify_dir)
+ logging.info('Run ECC tool for the commit in %s' % modify_dir)
+ ecc_need = True
+ ecc_params = "-c {0} -e {1} -t {2} -r {3}".format(config, exception, target, report)
+ return_code = RunCmd("Ecc", ecc_params, workingdir=edk2_path)
+ if return_code != 0:
+ ecc_run = False
+ break
+ if not ecc_run:
+ logging.error('Fail to run ECC tool')
+ self.ParseEccReport(ecc_diff_range, edk2_path)
+
+ if not ecc_need:
+ logging.info("Doesn't need run ECC check")
+
+ revert_params = "checkout -- {}".format(exception)
+ RunCmd("git", revert_params)
+ return
+
+ def ParseEccReport(self, ecc_diff_range: Dict[str, List[Tuple[int, int]]], edk2_path: str) -> None:
+ ecc_log = os.path.join(edk2_path, "Ecc.log")
+ ecc_csv = "Ecc.csv"
+ file = os.listdir(edk2_path)
+ row_lines = []
+ ignore_error_code = self.GetIgnoreErrorCode()
+ if ecc_csv in file:
+ with open(ecc_csv) as csv_file:
+ reader = csv.reader(csv_file)
+ for row in reader:
+ for modify_file in ecc_diff_range:
+ if modify_file in row[3]:
+ for i in ecc_diff_range[modify_file]:
+ line_no = int(row[4])
+ if i[0] <= line_no <= i[1] and row[1] not in ignore_error_code:
+ row[0] = '\nEFI coding style error'
+ row[1] = 'Error code: ' + row[1]
+ row[3] = 'file: ' + row[3]
+ row[4] = 'Line number: ' + row[4]
+ row_line = '\n *'.join(row)
+ row_lines.append(row_line)
+ break
+ break
+ if row_lines:
+ self.ECC_PASS = False
+
+ with open(ecc_log, 'a') as log:
+ all_line = '\n'.join(row_lines)
+ all_line = all_line + '\n'
+ log.writelines(all_line)
+ return
+
+ def ApplyConfig(self, pkgconfig: Dict[str, List[str]], edk2_path: str, pkg: str) -> None:
+ if "IgnoreFiles" in pkgconfig:
+ for a in pkgconfig["IgnoreFiles"]:
+ a = os.path.join(edk2_path, pkg, a)
+ a = a.replace(os.sep, "/")
+
+ logging.info("Ignoring Files {0}".format(a))
+ if os.path.exists(a):
+ if os.path.isfile(a):
+ self.RemoveFile(a)
+ elif os.path.isdir(a):
+ shutil.rmtree(a)
+ else:
+ logging.error("EccCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore files".format(a))
+
+ if "ExceptionList" in pkgconfig:
+ exception_list = pkgconfig["ExceptionList"]
+ exception_xml = os.path.join(edk2_path, "BaseTools", "Source", "Python", "Ecc", "exception.xml")
+ try:
+ logging.info("Appending exceptions")
+ self.AppendException(exception_list, exception_xml)
+ except Exception as e:
+ logging.error("Fail to apply exceptions")
+ raise e
+ return
+
+ def AppendException(self, exception_list: List[str], exception_xml: str) -> None:
+ error_code_list = exception_list[::2]
+ keyword_list = exception_list[1::2]
+ dom_tree = xml.dom.minidom.parse(exception_xml)
+ root_node = dom_tree.documentElement
+ for error_code, keyword in zip(error_code_list, keyword_list):
+ customer_node = dom_tree.createElement("Exception")
+ keyword_node = dom_tree.createElement("KeyWord")
+ keyword_node_text_value = dom_tree.createTextNode(keyword)
+ keyword_node.appendChild(keyword_node_text_value)
+ customer_node.appendChild(keyword_node)
+ error_code_node = dom_tree.createElement("ErrorID")
+ error_code_text_value = dom_tree.createTextNode(error_code)
+ error_code_node.appendChild(error_code_text_value)
+ customer_node.appendChild(error_code_node)
+ root_node.appendChild(customer_node)
+ with open(exception_xml, 'w') as f:
+ dom_tree.writexml(f, indent='', addindent='', newl='\n', encoding='UTF-8')
+ return
+
+ def GetIgnoreErrorCode(self) -> set:
+ """
+ Below are kinds of error code that are accurate in ecc scanning of edk2 level.
+ But EccCheck plugin is partial scanning so they are always false positive issues.
+ The mapping relationship of error code and error message is listed BaseTools/Sourc/Python/Ecc/EccToolError.py
+ """
+ ignore_error_code = {
+ "10000",
+ "10001",
+ "10002",
+ "10003",
+ "10004",
+ "10005",
+ "10006",
+ "10007",
+ "10008",
+ "10009",
+ "10010",
+ "10011",
+ "10012",
+ "10013",
+ "10015",
+ "10016",
+ "10017",
+ "10022",
+ }
+ return ignore_error_code
diff --git a/.pytool/Plugin/EccCheck/EccCheck_plug_in.yaml b/.pytool/Plugin/EccCheck/EccCheck_plug_in.yaml
new file mode 100644
index 000000000000..0d121ecb1861
--- /dev/null
+++ b/.pytool/Plugin/EccCheck/EccCheck_plug_in.yaml
@@ -0,0 +1,11 @@
+## @file
+# CiBuildPlugin used to check Ecc issues
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+ "scope": "cibuild",
+ "name": "EccCheck Test",
+ "module": "EccCheck"
+}
diff --git a/.pytool/Plugin/EccCheck/Readme.md b/.pytool/Plugin/EccCheck/Readme.md
new file mode 100644
index 000000000000..85c439a5edf1
--- /dev/null
+++ b/.pytool/Plugin/EccCheck/Readme.md
@@ -0,0 +1,15 @@
+# EFI Coding style Check Plugin
+
+This CiBuildPlugin finds the Ecc issues of newly added code in pull request.
+
+## Configuration
+
+The plugin can be configured to ignore certain files and issues.
+
+"EccCheck": {
+ "ExceptionList": [],
+ "IgnoreFiles": []
+ },
+ """
+
+OPTIONAL List of file to ignore.
--
2.18.0.windows.1


[PATCH v9 01/16] pip-requirements.txt: Add Ecc required lib

Zhang, Shenglei
 

antlr4-python3-runtime is a lib to support Ecc run with Py3.x.

Cc: Sean Brogan <sean.brogan@...>
Cc: Bret Barkelew <Bret.Barkelew@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Signed-off-by: Shenglei Zhang <shenglei.zhang@...>
Reviewed-by: Liming Gao <liming.gao@...>
---
pip-requirements.txt | 1 +
1 file changed, 1 insertion(+)

diff --git a/pip-requirements.txt b/pip-requirements.txt
index 574dac43b1a6..0fecd37f2a83 100644
--- a/pip-requirements.txt
+++ b/pip-requirements.txt
@@ -14,3 +14,4 @@

edk2-pytool-library==0.10.*
edk2-pytool-extensions~=0.13.3
+antlr4-python3-runtime==4.7.1
--
2.18.0.windows.1


[PATCH v9 00/16] Add a plugin to check Ecc issues for edk2 on open ci

Zhang, Shenglei
 

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2606
As planed we will enable Ecc check for edk2 on open ci. And they are
ready now. I appreciate receiving feedback and comments if someone
find errors or false positive issues.

I created a pipline of EccCheck for my forked edk2. Welcome everyone to
create pull request to test the quality of this plugin.
My forked tree: https://github.com/shenglei10/edk2

And I also created some test cases for ECC plugin. Below are test cases.
https://github.com/shenglei10/edk2/tree/ECC
Results can be view in below azure server.
https://dev.azure.com/shengleizhang/shengleizhang/_build?definitionId=12&_a=summary

Patches
1/16: It's a lib necessary for py3 to run Ecc on azure servers.

2/16: EccCheck.py is a plugin to report Ecc issues for commits. It can be run
on azure servers for open ci, or a local virtual environment.

3/16~16/16: We consider some cases that will report out Ecc issues but they won't
be fixed, like submodule and industry standard related things. So we
add two configuration fields "Exception" and "IgnoreFiles" for people
to use. These patches add configuration in yaml files for Ecc check.

Cc: Bob Feng <bob.c.feng@...>
Cc: Bret Barkelew <Bret.Barkelew@...>
Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Sean Brogan <sean.brogan@...>

v2: Update 1/17, fix the bug that the script can't hanlde multiple commits.

v3: Update 1/17, set the only workalbe workspace is edk2 root directory.
Update 2/17, designate the version of antlr4 is 4.7.1.
Add 4/17~17/17.

v4. Update 1/17, remove the function EdksetupRebuild(), instead add
function SetupEnvironment(). Update variables' format and type hints
to pass flake8 and mypy.

v5. Conver the former method to plugin solution, to align with
other check points on open ci.

v6. The 1/16 patch is missed in v5 series. Now add it in v6.

v7. Fix a bug that Ecc plugin can not be run correctly under Linux OS.

v8. Enable error code config section to ignore certain kinds of issues,
which are always false positive in partial Ecc scaning.
All patches except 2/16 have been R-B and are not updated in v8 series.
To avoid making noise in community, I only send cover letter and 2/16 patch.

v9. Update 2/16, 3/16, 5/16 and 16/16.
1. Enable directory path for "IgnoreFiles" section in xxxPkg.yaml. So that
users can skip a certain directory and don't need to fill in with file names.
2. Add submodule pathes in "IgnoreFiles" in MdeModulePkg.ci.yaml,
CryptoPkg.ci.yaml and UnitTestFrameworkPkg.ci.yaml.

Shenglei Zhang (16):
pip-requirements.txt: Add Ecc required lib
.pytool/Plugin: Add a plugin EccCheck
MdeModulePkg/MdeModulePkg.ci.yaml: Add configuration for Ecc check
ArmVirtPkg/ArmVirtPkg.ci.yaml: Add configuration for Ecc check
CryptoPkg/CryptoPkg.ci.yaml: Add configuration for Ecc check
EmulatorPkg/EmulatorPkg.ci.yaml: Add configuration for Ecc check
FatPkg/FatPkg.ci.yaml: Add configuration for Ecc check
FmpDevicePkg/FmpDevicePkg.ci.yaml: Add configuration for Ecc check
MdePkg/MdePkg.ci.yaml: Add configuration for Ecc check
NetworkPkg/NetworkPkg.ci.yaml: Add configuration for Ecc check
OvmfPkg/OvmfPkg.ci.yaml: Add configuration for Ecc check
PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml: Add configuration for Ecc check
SecurityPkg/SecurityPkg.ci.yaml: Add configuration for Ecc check
ShellPkg/ShellPkg.ci.yaml: Add configuration for Ecc check
UefiCpuPkg/UefiCpuPkg.ci.yaml: Add configuration for Ecc check
UnitTestFrameworkPkg: Add configuration for Ecc check in yaml file

.pytool/Plugin/EccCheck/EccCheck.py | 302 ++++++++++++++++++
.pytool/Plugin/EccCheck/EccCheck_plug_in.yaml | 11 +
.pytool/Plugin/EccCheck/Readme.md | 15 +
ArmVirtPkg/ArmVirtPkg.ci.yaml | 11 +
CryptoPkg/CryptoPkg.ci.yaml | 13 +
EmulatorPkg/EmulatorPkg.ci.yaml | 11 +
FatPkg/FatPkg.ci.yaml | 12 +
FmpDevicePkg/FmpDevicePkg.ci.yaml | 12 +
MdeModulePkg/MdeModulePkg.ci.yaml | 13 +
MdePkg/MdePkg.ci.yaml | 11 +
NetworkPkg/NetworkPkg.ci.yaml | 12 +
OvmfPkg/OvmfPkg.ci.yaml | 11 +
PcAtChipsetPkg/PcAtChipsetPkg.ci.yaml | 12 +
SecurityPkg/SecurityPkg.ci.yaml | 12 +
ShellPkg/ShellPkg.ci.yaml | 12 +
UefiCpuPkg/UefiCpuPkg.ci.yaml | 12 +
.../UnitTestFrameworkPkg.ci.yaml | 11 +
pip-requirements.txt | 1 +
18 files changed, 494 insertions(+)
create mode 100644 .pytool/Plugin/EccCheck/EccCheck.py
create mode 100644 .pytool/Plugin/EccCheck/EccCheck_plug_in.yaml
create mode 100644 .pytool/Plugin/EccCheck/Readme.md

--
2.18.0.windows.1


[PATCH 3/3] MdeModulePkg/PartitionDxe: Fix the incorrect LBA size in child hander

Gao, Zhichao
 

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2843

PartitionInstallChildHandle's parameters Start and End is counted
by the BlockSize, but in the implementation it uses the parent
device's BlockSize to calculate the new Start, End and LastBlock.
It would cause the driver report incorrect block scope and the file
system would fail to be found with right block scope.
So correct it to the right value.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Cc: Ray Ni <ray.ni@...>
Cc: Gary Lin <glin@...>
Cc: Andrew Fish <afish@...>
Signed-off-by: Zhichao Gao <zhichao.gao@...>
---
MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
index 473e091320..f10ce7c65b 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
@@ -1149,8 +1149,8 @@ PartitionInstallChildHandle (

Private->Signature = PARTITION_PRIVATE_DATA_SIGNATURE;

- Private->Start = MultU64x32 (Start, ParentBlockIo->Media->BlockSize);
- Private->End = MultU64x32 (End + 1, ParentBlockIo->Media->BlockSize);
+ Private->Start = MultU64x32 (Start, BlockSize);
+ Private->End = MultU64x32 (End + 1, BlockSize);

Private->BlockSize = BlockSize;
Private->ParentBlockIo = ParentBlockIo;
@@ -1187,13 +1187,7 @@ PartitionInstallChildHandle (

Private->Media.IoAlign = 0;
Private->Media.LogicalPartition = TRUE;
- Private->Media.LastBlock = DivU64x32 (
- MultU64x32 (
- End - Start + 1,
- ParentBlockIo->Media->BlockSize
- ),
- BlockSize
- ) - 1;
+ Private->Media.LastBlock = End - Start;

Private->Media.BlockSize = (UINT32) BlockSize;

--
2.21.0.windows.1


[PATCH 1/3] MdeModulePkg/PartitionDxe: Put the UDF check ahead of MBR

Gao, Zhichao
 

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2823

Refer to UEFI spec 2.8, Section 13.3.2, a block device should
be scanned as below order:
1. GPT
2. ISO 9660 (El Torito) (UDF should aslo be here)
3. MBR
4. no partition found
Note: UDF is using the same boot method as CD, so put it in
the same priority with ISO 9660.

This would also solve the issue that ISO image with MBR would
be treat as MBR device instead of CD/DVD. That would make the
behavior of the image boot different.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Cc: Ray Ni <ray.ni@...>
Cc: Gary Lin <glin@...>
Cc: Andrew Fish <afish@...>
Signed-off-by: Zhichao Gao <zhichao.gao@...>
---
MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
index 6a43c3cafb..473e091320 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Partition.c
@@ -35,11 +35,19 @@ EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding = {

//
// Prioritized function list to detect partition table.
+// Refer to UEFI Spec 13.3.2 Partition Discovery, the block device
+// should be scanned in below order:
+// 1. GPT
+// 2. ISO 9660 (El Torito) (or UDF)
+// 3. MBR
+// 4. no partiton found
+// Note: UDF is using a same method as booting from CD-ROM, so put it along
+// with CD-ROM check.
//
PARTITION_DETECT_ROUTINE mPartitionDetectRoutineTable[] = {
PartitionInstallGptChildHandles,
- PartitionInstallMbrChildHandles,
PartitionInstallUdfChildHandles,
+ PartitionInstallMbrChildHandles,
NULL
};

--
2.21.0.windows.1


[PATCH 2/3] MdeModulePkg/PartitionDxe: Remove the check for special MBR

Gao, Zhichao
 

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2823

Follow the spec definition, the ISO 9660 (and UDF) would be
checked before the MBR. So it is not required to skip such
MBR talbe that contian the entire block device.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Cc: Ray Ni <ray.ni@...>
Cc: Gary Lin <glin@...>
Cc: Andrew Fish <afish@...>
Signed-off-by: Zhichao Gao <zhichao.gao@...>
---
.../Universal/Disk/PartitionDxe/Mbr.c | 19 -------------------
1 file changed, 19 deletions(-)

diff --git a/MdeModulePkg/Universal/Disk/PartitionDxe/Mbr.c b/MdeModulePkg/Universal/Disk/PartitionDxe/Mbr.c
index 3830af1ea7..822bf03e92 100644
--- a/MdeModulePkg/Universal/Disk/PartitionDxe/Mbr.c
+++ b/MdeModulePkg/Universal/Disk/PartitionDxe/Mbr.c
@@ -55,25 +55,6 @@ PartitionValidMbr (
StartingLBA = UNPACK_UINT32 (Mbr->Partition[Index1].StartingLBA);
SizeInLBA = UNPACK_UINT32 (Mbr->Partition[Index1].SizeInLBA);

- //
- // If the MBR with partition entry covering the ENTIRE disk, i.e. start at LBA0
- // with whole disk size, we treat it as an invalid MBR partition.
- //
- if ((StartingLBA == 0) &&
- (SizeInLBA == (LastLba + 1))) {
- //
- // Refer to the http://manpages.ubuntu.com/manpages/bionic/man8/mkudffs.8.html
- // "WHOLE DISK VS PARTITION"
- // Some linux ISOs may put the MBR table in the first 512 bytes for compatibility reasons with Windows.
- // Linux kernel ignores MBR table if contains partition which starts at sector 0.
- // Skip it because we don't have the partition check for UDF(El Torito compatible).
- // It would continue to do the whole disk check in the UDF routine.
- //
- DEBUG ((DEBUG_INFO, "PartitionValidMbr: MBR table has partition entry covering the ENTIRE disk. Don't treat it as a valid MBR.\n"));
-
- return FALSE;
- }
-
if (Mbr->Partition[Index1].OSIndicator == 0x00 || SizeInLBA == 0) {
continue;
}
--
2.21.0.windows.1


[PATCH 0/3] MdeModulePkg/PartitionDxe: Make the parition driver match the spec

Gao, Zhichao
 

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2823
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2843

Refer to the UEFI spec 2.8, Section 13.3.2:
A block device should be scanned as below order:
1. GPT
2. ISO 9660 (El Torito) (UDF should aslo be here)
4. MBR
5. no partition found

But the code implementation is:
1. GPT
2. MBR
3. ISO 9660 (El Torito) (UDF)
4. no partition found

Which would cause the ISO 9960 image with MBR info be treated as MBR
device. That would cause unexpect behavior. So fix it to follow the spec
description.

The fix of the PartitionInstallChildHandle would change the boot behavior
of Linux ISO image with MBR table. So add it after the order adjustment
to make no impact of the boot.

Cc: Jian J Wang <jian.j.wang@...>
Cc: Hao A Wu <hao.a.wu@...>
Cc: Ray Ni <ray.ni@...>
Cc: Gary Lin <glin@...>
Cc: Andrew Fish <afish@...>
Signed-off-by: Zhichao Gao <zhichao.gao@...>
Zhichao Gao (3):
MdeModulePkg/PartitionDxe: Put the UDF check ahead of MBR
MdeModulePkg/PartitionDxe: Remove the check for special MBR
MdeModulePkg/PartitionDxe: Fix the incorrect LBA size in child hander

.../Universal/Disk/PartitionDxe/Mbr.c | 19 ----------------
.../Universal/Disk/PartitionDxe/Partition.c | 22 ++++++++++---------
2 files changed, 12 insertions(+), 29 deletions(-)

--
2.21.0.windows.1


[edk2-wiki][PATCH v2] Update the Boot Guard TOCTOU wiki page.

Guomin Jiang
 

The Boot Guard TOCTOU have been migrated into edk2/master.
Update the document to meet the change.

Signed-off-by: Guomin Jiang <guomin.jiang@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Liming Gao <liming.gao@...>
Reviewed-by: Jian J Wang <jian.j.wang@...>
---
Boot-Guard-TOCTOU-Vulnerability-Mitigation.md | 28 ++++++-------------
1 file changed, 8 insertions(+), 20 deletions(-)

diff --git a/Boot-Guard-TOCTOU-Vulnerability-Mitigation.md b/Boot-Guard-TOCTOU-Vulnerability-Mitigation.md
index e59c7b1..64b9d66 100644
--- a/Boot-Guard-TOCTOU-Vulnerability-Mitigation.md
+++ b/Boot-Guard-TOCTOU-Vulnerability-Mitigation.md
@@ -45,32 +45,20 @@ references must be updated. In this mitigation, the process of performing these
The changes described in this mitigation are intended to simply integrate into firmware solutions. For the changes to
function as intended, the platform firmware implementation should follow these guidelines.

-The changes are currently being staged in the following EDK II fork for additional validation before being
-sent to the EDK II mailing list: https://github.com/makubacki/edk2/tree/btg_toctou_mitigation_staging
-
-The changes should not be considered final or production ready until they are reviewed and pushed onto edk2/master.
-
-1. Always ensure PcdShadowPeimOnBoot and PcdShadowPeimOnS3Boot
- (if platform supports S3) are set to TRUE if Boot Guard is
- enabled and V=1 or M=1.
-2. Always ensure PcdMigrateTemporaryRamFirmwareVolumes is set to TRUE.
-3. Ensure that all PEIMs are relocatable. Relocation tables should
+1. Always ensure PcdMigrateTemporaryRamFirmwareVolumes is set to TRUE
+ if Boot Guard is enabled and V=1 or M=1.
+2. Ensure that all PEIMs are relocatable. Relocation tables should
not be stripped.
-4. If an Intel&reg; Firmware Support Package (FSP) binary solution is
+3. If an Intel&reg; Firmware Support Package (FSP) binary solution is
used, the binary must have these mitigation changes integrated.
-5. Avoid maintaining pointers to pre-memory addresses inside embedded
+4. Avoid maintaining pointers to pre-memory addresses inside embedded
structures or other non-standard structures that the automatic
migration code introduced in this change cannot identify.
-6. Migrate the FIT table based on platform requirements for FIT
+5. Migrate the FIT table based on platform requirements for FIT
access in post-memory.

-**Very Important**
-
-7. Enable paging after memory initialization and mark the IBB range
- as Not Present (NP).
-
- This will cause a page fault on access to the IBB region. This CR2 register can be used to identify the address
- accessed and the IP.
+Notes: IBB will be set Not Present, you will see a page fault if any code access to the IBB region after migration.
+ the address where the code access can be identified in the CR2 register.

# High-Level Migration Required
Resources that must be migrated can be categorized as code or data.
--
2.25.1.windows.1


[PATCH v4 5/5] CryptoPkg: OpensslLib: Use RngLib to generate entropy in rand_pool

Matthew Carlson
 

From: Matthew Carlson <macarl@...>

Changes OpenSSL to no longer depend on TimerLib and instead use RngLib.
This allows platforms to decide for themsevles what sort of entropy source
they provide to OpenSSL and TlsLib.

Cc: Jiewen Yao <jiewen.yao@...>
Cc: Jian J Wang <jian.j.wang@...>
Cc: Xiaoyu Lu <xiaoyux.lu@...>
Signed-off-by: Matthew Carlson <matthewfcarlson@...>
---
CryptoPkg/Library/OpensslLib/rand_pool.c | 203 ++---------------=
---
CryptoPkg/Library/OpensslLib/rand_pool_noise.c | 29 ---
CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c | 43 -----
CryptoPkg/CryptoPkg.dsc | 1 +
CryptoPkg/Library/OpensslLib/OpensslLib.inf | 15 +-
CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf | 15 +-
CryptoPkg/Library/OpensslLib/rand_pool_noise.h | 29 ---
7 files changed, 22 insertions(+), 313 deletions(-)

diff --git a/CryptoPkg/Library/OpensslLib/rand_pool.c b/CryptoPkg/Library/O=
pensslLib/rand_pool.c
index 9e0179b03490..3da92699fef6 100644
--- a/CryptoPkg/Library/OpensslLib/rand_pool.c
+++ b/CryptoPkg/Library/OpensslLib/rand_pool.c
@@ -11,53 +11,18 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include <openssl/aes.h>=0D
=0D
#include <Uefi.h>=0D
-#include <Library/TimerLib.h>=0D
-=0D
-#include "rand_pool_noise.h"=0D
-=0D
-/**=0D
- Get some randomness from low-order bits of GetPerformanceCounter results=
.=0D
- And combine them to the 64-bit value=0D
-=0D
- @param[out] Rand Buffer pointer to store the 64-bit random value.=0D
-=0D
- @retval TRUE Random number generated successfully.=0D
- @retval FALSE Failed to generate.=0D
-**/=0D
-STATIC=0D
-BOOLEAN=0D
-EFIAPI=0D
-GetRandNoise64FromPerformanceCounter(=0D
- OUT UINT64 *Rand=0D
- )=0D
-{=0D
- UINT32 Index;=0D
- UINT32 *RandPtr;=0D
-=0D
- if (NULL =3D=3D Rand) {=0D
- return FALSE;=0D
- }=0D
-=0D
- RandPtr =3D (UINT32 *) Rand;=0D
-=0D
- for (Index =3D 0; Index < 2; Index ++) {=0D
- *RandPtr =3D (UINT32) (GetPerformanceCounter () & 0xFF);=0D
- MicroSecondDelay (10);=0D
- RandPtr++;=0D
- }=0D
-=0D
- return TRUE;=0D
-}=0D
+#include <Library/RngLib.h>=0D
=0D
/**=0D
Calls RandomNumber64 to fill=0D
a buffer of arbitrary size with random bytes.=0D
+ This is a shim layer to RngLib.=0D
=0D
@param[in] Length Size of the buffer, in bytes, to fill with.=
=0D
@param[out] RandBuffer Pointer to the buffer to store the random res=
ult.=0D
=0D
- @retval EFI_SUCCESS Random bytes generation succeeded.=0D
- @retval EFI_NOT_READY Failed to request random bytes.=0D
+ @retval TRUE Random bytes generation succeeded.=0D
+ @retval FALSE Failed to request random bytes.=0D
=0D
**/=0D
STATIC=0D
@@ -73,17 +38,17 @@ RandGetBytes (
=0D
Ret =3D FALSE;=0D
=0D
+ if (RandBuffer =3D=3D NULL) {=0D
+ DEBUG((DEBUG_ERROR, "[OPENSSL_RAND_POOL] NULL RandBuffer. No random nu=
mbers are generated and your system is not secure\n"));=0D
+ ASSERT(FALSE); // Since we can't generate random numbers, we should as=
sert. Otherwise we will just blow up later.=0D
+ return Ret;=0D
+ }=0D
+=0D
+=0D
while (Length > 0) {=0D
- //=0D
- // Get random noise from platform.=0D
- // If it failed, fallback to PerformanceCounter=0D
- // If you really care about security, you must override=0D
- // GetRandomNoise64FromPlatform.=0D
- //=0D
- Ret =3D GetRandomNoise64 (&TempRand);=0D
- if (Ret =3D=3D FALSE) {=0D
- Ret =3D GetRandNoise64FromPerformanceCounter (&TempRand);=0D
- }=0D
+ // Use RngLib to get random number=0D
+ Ret =3D GetRandomNumber64(&TempRand);=0D
+=0D
if (!Ret) {=0D
return Ret;=0D
}=0D
@@ -100,125 +65,6 @@ RandGetBytes (
return Ret;=0D
}=0D
=0D
-/**=0D
- Creates a 128bit random value that is fully forward and backward predict=
ion resistant,=0D
- suitable for seeding a NIST SP800-90 Compliant.=0D
- This function takes multiple random numbers from PerformanceCounter to e=
nsure reseeding=0D
- and performs AES-CBC-MAC over the data to compute the seed value.=0D
-=0D
- @param[out] SeedBuffer Pointer to a 128bit buffer to store the rando=
m seed.=0D
-=0D
- @retval TRUE Random seed generation succeeded.=0D
- @retval FALSE Failed to request random bytes.=0D
-=0D
-**/=0D
-STATIC=0D
-BOOLEAN=0D
-EFIAPI=0D
-RandGetSeed128 (=0D
- OUT UINT8 *SeedBuffer=0D
- )=0D
-{=0D
- BOOLEAN Ret;=0D
- UINT8 RandByte[16];=0D
- UINT8 Key[16];=0D
- UINT8 Ffv[16];=0D
- UINT8 Xored[16];=0D
- UINT32 Index;=0D
- UINT32 Index2;=0D
- AES_KEY AESKey;=0D
-=0D
- //=0D
- // Chose an arbitrary key and zero the feed_forward_value (FFV)=0D
- //=0D
- for (Index =3D 0; Index < 16; Index++) {=0D
- Key[Index] =3D (UINT8) Index;=0D
- Ffv[Index] =3D 0;=0D
- }=0D
-=0D
- AES_set_encrypt_key (Key, 16 * 8, &AESKey);=0D
-=0D
- //=0D
- // Perform CBC_MAC over 32 * 128 bit values, with 10us gaps between 128 =
bit value=0D
- // The 10us gaps will ensure multiple reseeds within the system time wit=
h a large=0D
- // design margin.=0D
- //=0D
- for (Index =3D 0; Index < 32; Index++) {=0D
- MicroSecondDelay (10);=0D
- Ret =3D RandGetBytes (16, RandByte);=0D
- if (!Ret) {=0D
- return Ret;=0D
- }=0D
-=0D
- //=0D
- // Perform XOR operations on two 128-bit value.=0D
- //=0D
- for (Index2 =3D 0; Index2 < 16; Index2++) {=0D
- Xored[Index2] =3D RandByte[Index2] ^ Ffv[Index2];=0D
- }=0D
-=0D
- AES_encrypt (Xored, Ffv, &AESKey);=0D
- }=0D
-=0D
- for (Index =3D 0; Index < 16; Index++) {=0D
- SeedBuffer[Index] =3D Ffv[Index];=0D
- }=0D
-=0D
- return Ret;=0D
-}=0D
-=0D
-/**=0D
- Generate high-quality entropy source.=0D
-=0D
- @param[in] Length Size of the buffer, in bytes, to fill with.=0D
- @param[out] Entropy Pointer to the buffer to store the entropy da=
ta.=0D
-=0D
- @retval EFI_SUCCESS Entropy generation succeeded.=0D
- @retval EFI_NOT_READY Failed to request random data.=0D
-=0D
-**/=0D
-STATIC=0D
-BOOLEAN=0D
-EFIAPI=0D
-RandGenerateEntropy (=0D
- IN UINTN Length,=0D
- OUT UINT8 *Entropy=0D
- )=0D
-{=0D
- BOOLEAN Ret;=0D
- UINTN BlockCount;=0D
- UINT8 Seed[16];=0D
- UINT8 *Ptr;=0D
-=0D
- BlockCount =3D Length / 16;=0D
- Ptr =3D (UINT8 *) Entropy;=0D
-=0D
- //=0D
- // Generate high-quality seed for DRBG Entropy=0D
- //=0D
- while (BlockCount > 0) {=0D
- Ret =3D RandGetSeed128 (Seed);=0D
- if (!Ret) {=0D
- return Ret;=0D
- }=0D
- CopyMem (Ptr, Seed, 16);=0D
-=0D
- BlockCount--;=0D
- Ptr =3D Ptr + 16;=0D
- }=0D
-=0D
- //=0D
- // Populate the remained data as request.=0D
- //=0D
- Ret =3D RandGetSeed128 (Seed);=0D
- if (!Ret) {=0D
- return Ret;=0D
- }=0D
- CopyMem (Ptr, Seed, (Length % 16));=0D
-=0D
- return Ret;=0D
-}=0D
-=0D
/*=0D
* Add random bytes to the pool to acquire requested amount of entropy=0D
*=0D
@@ -238,7 +84,7 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
buffer =3D rand_pool_add_begin(pool, bytes_needed);=0D
=0D
if (buffer !=3D NULL) {=0D
- Ret =3D RandGenerateEntropy(bytes_needed, buffer);=0D
+ Ret =3D RandGetBytes(bytes_needed, buffer);=0D
if (FALSE =3D=3D Ret) {=0D
rand_pool_add_end(pool, 0, 0);=0D
} else {=0D
@@ -257,13 +103,8 @@ size_t rand_pool_acquire_entropy(RAND_POOL *pool)
*/=0D
int rand_pool_add_nonce_data(RAND_POOL *pool)=0D
{=0D
- struct {=0D
- UINT64 Rand;=0D
- UINT64 TimerValue;=0D
- } data =3D { 0 };=0D
-=0D
- RandGetBytes(8, (UINT8 *)&(data.Rand));=0D
- data.TimerValue =3D GetPerformanceCounter();=0D
+ UINT8 data[16];=0D
+ RandGetBytes(sizeof(data), data);=0D
=0D
return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);=0D
}=0D
@@ -275,13 +116,8 @@ int rand_pool_add_nonce_data(RAND_POOL *pool)
*/=0D
int rand_pool_add_additional_data(RAND_POOL *pool)=0D
{=0D
- struct {=0D
- UINT64 Rand;=0D
- UINT64 TimerValue;=0D
- } data =3D { 0 };=0D
-=0D
- RandGetBytes(8, (UINT8 *)&(data.Rand));=0D
- data.TimerValue =3D GetPerformanceCounter();=0D
+ UINT8 data[16];=0D
+ RandGetBytes(sizeof(data), data);=0D
=0D
return rand_pool_add(pool, (unsigned char*)&data, sizeof(data), 0);=0D
}=0D
@@ -313,4 +149,3 @@ void rand_pool_cleanup(void)
void rand_pool_keep_random_devices_open(int keep)=0D
{=0D
}=0D
-=0D
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c b/CryptoPkg/Lib=
rary/OpensslLib/rand_pool_noise.c
deleted file mode 100644
index 212834e27acc..000000000000
--- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/** @file=0D
- Provide rand noise source.=0D
-=0D
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>=0D
-SPDX-License-Identifier: BSD-2-Clause-Patent=0D
-=0D
-**/=0D
-=0D
-#include <Library/BaseLib.h>=0D
-=0D
-/**=0D
- Get 64-bit noise source=0D
-=0D
- @param[out] Rand Buffer pointer to store 64-bit noise source=0D
-=0D
- @retval FALSE Failed to generate=0D
-**/=0D
-BOOLEAN=0D
-EFIAPI=0D
-GetRandomNoise64 (=0D
- OUT UINT64 *Rand=0D
- )=0D
-{=0D
- //=0D
- // Return FALSE will fallback to use PerformanceCounter to=0D
- // generate noise.=0D
- //=0D
- return FALSE;=0D
-}=0D
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c b/CryptoPkg=
/Library/OpensslLib/rand_pool_noise_tsc.c
deleted file mode 100644
index 4158106231fd..000000000000
--- a/CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/** @file=0D
- Provide rand noise source.=0D
-=0D
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>=0D
-SPDX-License-Identifier: BSD-2-Clause-Patent=0D
-=0D
-**/=0D
-=0D
-#include <Library/BaseLib.h>=0D
-#include <Library/DebugLib.h>=0D
-#include <Library/TimerLib.h>=0D
-=0D
-/**=0D
- Get 64-bit noise source=0D
-=0D
- @param[out] Rand Buffer pointer to store 64-bit noise source=0D
-=0D
- @retval TRUE Get randomness successfully.=0D
- @retval FALSE Failed to generate=0D
-**/=0D
-BOOLEAN=0D
-EFIAPI=0D
-GetRandomNoise64 (=0D
- OUT UINT64 *Rand=0D
- )=0D
-{=0D
- UINT32 Index;=0D
- UINT32 *RandPtr;=0D
-=0D
- if (NULL =3D=3D Rand) {=0D
- return FALSE;=0D
- }=0D
-=0D
- RandPtr =3D (UINT32 *)Rand;=0D
-=0D
- for (Index =3D 0; Index < 2; Index ++) {=0D
- *RandPtr =3D (UINT32) ((AsmReadTsc ()) & 0xFF);=0D
- RandPtr++;=0D
- MicroSecondDelay (10);=0D
- }=0D
-=0D
- return TRUE;=0D
-}=0D
diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index 1af78468a19c..0490eeb7e22f 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -60,6 +60,7 @@
BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf=0D
TlsLib|CryptoPkg/Library/TlsLibNull/TlsLibNull.inf=0D
HashApiLib|CryptoPkg/Library/BaseHashApiLib/BaseHashApiLib.inf=0D
+ RngLib|MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf=0D
=0D
[LibraryClasses.ARM, LibraryClasses.AARCH64]=0D
#=0D
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Librar=
y/OpensslLib/OpensslLib.inf
index dbbe5386a10c..4baad565564c 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
@@ -571,22 +571,9 @@
$(OPENSSL_PATH)/ssl/statem/statem_local.h=0D
# Autogenerated files list ends here=0D
buildinf.h=0D
- rand_pool_noise.h=0D
ossl_store.c=0D
rand_pool.c=0D
=0D
-[Sources.Ia32]=0D
- rand_pool_noise_tsc.c=0D
-=0D
-[Sources.X64]=0D
- rand_pool_noise_tsc.c=0D
-=0D
-[Sources.ARM]=0D
- rand_pool_noise.c=0D
-=0D
-[Sources.AARCH64]=0D
- rand_pool_noise.c=0D
-=0D
[Packages]=0D
MdePkg/MdePkg.dec=0D
CryptoPkg/CryptoPkg.dec=0D
@@ -594,7 +581,7 @@
[LibraryClasses]=0D
BaseLib=0D
DebugLib=0D
- TimerLib=0D
+ RngLib=0D
PrintLib=0D
=0D
[LibraryClasses.ARM]=0D
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf b/CryptoPkg/=
Library/OpensslLib/OpensslLibCrypto.inf
index 616ccd9f62d1..3557711bd85a 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf
@@ -520,22 +520,9 @@
$(OPENSSL_PATH)/crypto/x509v3/v3_admis.h=0D
# Autogenerated files list ends here=0D
buildinf.h=0D
- rand_pool_noise.h=0D
ossl_store.c=0D
rand_pool.c=0D
=0D
-[Sources.Ia32]=0D
- rand_pool_noise_tsc.c=0D
-=0D
-[Sources.X64]=0D
- rand_pool_noise_tsc.c=0D
-=0D
-[Sources.ARM]=0D
- rand_pool_noise.c=0D
-=0D
-[Sources.AARCH64]=0D
- rand_pool_noise.c=0D
-=0D
[Packages]=0D
MdePkg/MdePkg.dec=0D
CryptoPkg/CryptoPkg.dec=0D
@@ -543,7 +530,7 @@
[LibraryClasses]=0D
BaseLib=0D
DebugLib=0D
- TimerLib=0D
+ RngLib=0D
PrintLib=0D
=0D
[LibraryClasses.ARM]=0D
diff --git a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h b/CryptoPkg/Lib=
rary/OpensslLib/rand_pool_noise.h
deleted file mode 100644
index 75acc686a9f1..000000000000
--- a/CryptoPkg/Library/OpensslLib/rand_pool_noise.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/** @file=0D
- Provide rand noise source.=0D
-=0D
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>=0D
-SPDX-License-Identifier: BSD-2-Clause-Patent=0D
-=0D
-**/=0D
-=0D
-#ifndef __RAND_POOL_NOISE_H__=0D
-#define __RAND_POOL_NOISE_H__=0D
-=0D
-#include <Uefi/UefiBaseType.h>=0D
-=0D
-/**=0D
- Get 64-bit noise source.=0D
-=0D
- @param[out] Rand Buffer pointer to store 64-bit noise source=0D
-=0D
- @retval TRUE Get randomness successfully.=0D
- @retval FALSE Failed to generate=0D
-**/=0D
-BOOLEAN=0D
-EFIAPI=0D
-GetRandomNoise64 (=0D
- OUT UINT64 *Rand=0D
- );=0D
-=0D
-=0D
-#endif // __RAND_POOL_NOISE_H__=0D
--=20
2.27.0.windows.1


[PATCH v4 4/5] ArmVirtPkg: Add RngLib based on TimerLib for CryptoPkg

Matthew Carlson
 

From: Matthew Carlson <macarl@...>

Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Leif Lindholm <leif@...>
Signed-off-by: Matthew Carlson <matthewfcarlson@...>
---
ArmVirtPkg/ArmVirt.dsc.inc | 1 +
1 file changed, 1 insertion(+)

diff --git a/ArmVirtPkg/ArmVirt.dsc.inc b/ArmVirtPkg/ArmVirt.dsc.inc
index cf44fc73890b..ddfcd0cf9eee 100644
--- a/ArmVirtPkg/ArmVirt.dsc.inc
+++ b/ArmVirtPkg/ArmVirt.dsc.inc
@@ -42,6 +42,7 @@
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseD=
ebugPrintErrorLevelLib.inf=0D
=0D
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf=0D
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf=0D
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf=0D
BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.i=
nf=0D
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchroniza=
tionLib.inf=0D
--=20
2.27.0.windows.1


[PATCH v4 3/5] OvmfPkg: Add RngLib based on TimerLib for Crypto

Matthew Carlson
 

From: Matthew Carlson <macarl@...>

Cc: Jordan Justen <jordan.l.justen@...>
Cc: Laszlo Ersek <lersek@...>
Cc: Ard Biesheuvel <ard.biesheuvel@...>
Cc: Anthony Perard <anthony.perard@...>
Cc: Julien Grall <julien@...>
Signed-off-by: Matthew Carlson <matthewfcarlson@...>
---
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/OvmfXen.dsc | 1 +
4 files changed, 4 insertions(+)

diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 9178ffeb71cb..118fd1aff246 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -116,6 +116,7 @@
[LibraryClasses]=0D
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf=0D
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf=0D
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf=0D
ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf=0D
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf=0D
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf=
=0D
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index a665f78f0dc7..6b9da5b996ff 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -120,6 +120,7 @@
[LibraryClasses]=0D
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf=0D
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf=0D
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf=0D
ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf=0D
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf=0D
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf=
=0D
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 17f345acf4ee..3a354eb3a2bd 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -120,6 +120,7 @@
[LibraryClasses]=0D
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf=0D
TimerLib|OvmfPkg/Library/AcpiTimerLib/BaseAcpiTimerLib.inf=0D
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf=0D
ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf=0D
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf=0D
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf=
=0D
diff --git a/OvmfPkg/OvmfXen.dsc b/OvmfPkg/OvmfXen.dsc
index 782803cb2787..f97e2b7e07d0 100644
--- a/OvmfPkg/OvmfXen.dsc
+++ b/OvmfPkg/OvmfXen.dsc
@@ -110,6 +110,7 @@
[LibraryClasses]=0D
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf=0D
TimerLib|MdePkg/Library/SecPeiDxeTimerLibCpu/SecPeiDxeTimerLibCpu.inf=0D
+ RngLib|MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf=0D
ResetSystemLib|OvmfPkg/Library/ResetSystemLib/BaseResetSystemLib.inf=0D
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf=0D
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf=
=0D
--=20
2.27.0.windows.1


[PATCH v4 2/5] MdePkg: BaseRngLibDxe: Add RngLib that uses RngDxe

Matthew Carlson
 

From: Matthew Carlson <macarl@...>

Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Signed-off-by: Matthew Carlson <matthewfcarlson@...>
---
MdePkg/Library/BaseRngLibDxe/RngDxeLib.c | 200 ++++++++++++++++++++
MdePkg/Library/BaseRngLibDxe/BaseRngLibDxe.inf | 38 ++++
MdePkg/MdePkg.dsc | 4 +-
3 files changed, 241 insertions(+), 1 deletion(-)

diff --git a/MdePkg/Library/BaseRngLibDxe/RngDxeLib.c b/MdePkg/Library/Base=
RngLibDxe/RngDxeLib.c
new file mode 100644
index 000000000000..8ee29329de13
--- /dev/null
+++ b/MdePkg/Library/BaseRngLibDxe/RngDxeLib.c
@@ -0,0 +1,200 @@
+/** @file=0D
+ Provides an implementation of the library class RngLib that uses the Rng =
protocol.=0D
+=0D
+Copyright (c) Microsoft Corporation. All rights reserved.=0D
+SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+=0D
+**/=0D
+#include <Uefi.h>=0D
+#include <Library/UefiBootServicesTableLib.h>=0D
+#include <Library/DebugLib.h>=0D
+#include <Library/RngLib.h>=0D
+#include <Protocol/Rng.h>=0D
+=0D
+/**=0D
+Routine Description:=0D
+=0D
+ Generates a random number via the NIST=0D
+ 800-9A algorithm. Refer to=0D
+ http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf=0D
+ for more information.=0D
+=0D
+ Arguments:=0D
+=0D
+ Buffer -- Buffer to receive the random number.=0D
+ BufferSize -- Number of bytes in Buffer.=0D
+=0D
+Return Value:=0D
+=0D
+ EFI_SUCCESS or underlying failure code.=0D
+=0D
+**/=0D
+EFI_STATUS=0D
+EFIAPI=0D
+GenerateRandomNumberViaNist800Algorithm(=0D
+ OUT UINT8* Buffer,=0D
+ IN UINTN BufferSize=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+ EFI_RNG_PROTOCOL* RngProtocol;=0D
+=0D
+ RngProtocol =3D NULL;=0D
+=0D
+ if (Buffer =3D=3D NULL) {=0D
+ DEBUG((DEBUG_ERROR, "[%a] Buffer =3D=3D NULL.\n", __FUNCTION__));=0D
+ return EFI_INVALID_PARAMETER;=0D
+ }=0D
+=0D
+ Status =3D gBS->LocateProtocol(&gEfiRngProtocolGuid, NULL, (VOID **)&Rng=
Protocol);=0D
+ if (EFI_ERROR(Status) || RngProtocol =3D=3D NULL) {=0D
+ DEBUG((DEBUG_ERROR, "[%a] Could not locate RNG prototocol, Status =
=3D %r\n", __FUNCTION__, Status));=0D
+ return Status;=0D
+ }=0D
+=0D
+ Status =3D RngProtocol->GetRNG(RngProtocol, &gEfiRngAlgorithmSp80090Ctr2=
56Guid, BufferSize, Buffer);=0D
+ DEBUG((DEBUG_INFO, "[%a] GetRNG algorithm CTR-256 - Status =3D %r\n", __=
FUNCTION__, Status));=0D
+ if(!EFI_ERROR(Status)) {=0D
+ return Status;=0D
+ }=0D
+=0D
+ Status =3D RngProtocol->GetRNG(RngProtocol, &gEfiRngAlgorithmSp80090Hmac=
256Guid, BufferSize, Buffer);=0D
+ DEBUG((DEBUG_INFO, "[%a] GetRNG algorithm HMAC-256 - Status =3D %r\n", _=
_FUNCTION__, Status));=0D
+ if(!EFI_ERROR(Status)) {=0D
+ return Status;=0D
+ }=0D
+=0D
+ Status =3D RngProtocol->GetRNG(RngProtocol, &gEfiRngAlgorithmSp80090Hash=
256Guid, BufferSize, Buffer);=0D
+ DEBUG((DEBUG_INFO, "[%a] GetRNG algorithm Hash-256 - Status =3D %r\n", _=
_FUNCTION__, Status));=0D
+ if(!EFI_ERROR(Status)) {=0D
+ return Status;=0D
+ }=0D
+ // If we get to this point, we have failed=0D
+ DEBUG((DEBUG_ERROR, "[%a] GetRNG() failed, staus =3D %r\n", __FUNCTION__=
, Status));=0D
+=0D
+ return Status;=0D
+}// GenerateRandomNumberViaNist800Algorithm()=0D
+=0D
+=0D
+/**=0D
+ Generates a 16-bit random number.=0D
+=0D
+ if Rand is NULL, return FALSE.=0D
+=0D
+ @param[out] Rand Buffer pointer to store the 16-bit random value.=0D
+=0D
+ @retval TRUE Random number generated successfully.=0D
+ @retval FALSE Failed to generate the random number.=0D
+=0D
+**/=0D
+BOOLEAN=0D
+EFIAPI=0D
+GetRandomNumber16 (=0D
+ OUT UINT16 *Rand=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+=0D
+ if (Rand =3D=3D NULL)=0D
+ {=0D
+ return FALSE;=0D
+ }=0D
+=0D
+ Status =3D GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 2);=0D
+ if (EFI_ERROR(Status))=0D
+ {=0D
+ return FALSE;=0D
+ }=0D
+ return TRUE;=0D
+}=0D
+=0D
+/**=0D
+ Generates a 32-bit random number.=0D
+=0D
+ if Rand is NULL, return FALSE.=0D
+=0D
+ @param[out] Rand Buffer pointer to store the 32-bit random value.=0D
+=0D
+ @retval TRUE Random number generated successfully.=0D
+ @retval FALSE Failed to generate the random number.=0D
+=0D
+**/=0D
+BOOLEAN=0D
+EFIAPI=0D
+GetRandomNumber32 (=0D
+ OUT UINT32 *Rand=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+=0D
+ if (Rand =3D=3D NULL) {=0D
+ return FALSE;=0D
+ }=0D
+=0D
+ Status =3D GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 4);=0D
+ if (EFI_ERROR(Status)) {=0D
+ return FALSE;=0D
+ }=0D
+ return TRUE;=0D
+}=0D
+=0D
+/**=0D
+ Generates a 64-bit random number.=0D
+=0D
+ if Rand is NULL, return FALSE.=0D
+=0D
+ @param[out] Rand Buffer pointer to store the 64-bit random value.=0D
+=0D
+ @retval TRUE Random number generated successfully.=0D
+ @retval FALSE Failed to generate the random number.=0D
+=0D
+**/=0D
+BOOLEAN=0D
+EFIAPI=0D
+GetRandomNumber64 (=0D
+ OUT UINT64 *Rand=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+=0D
+ if (Rand =3D=3D NULL)=0D
+ {=0D
+ return FALSE;=0D
+ }=0D
+=0D
+ Status =3D GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 8);=0D
+ if (EFI_ERROR(Status)) {=0D
+ return FALSE;=0D
+ }=0D
+ return TRUE;=0D
+}=0D
+=0D
+/**=0D
+ Generates a 128-bit random number.=0D
+=0D
+ if Rand is NULL, return FALSE.=0D
+=0D
+ @param[out] Rand Buffer pointer to store the 128-bit random value.=0D
+=0D
+ @retval TRUE Random number generated successfully.=0D
+ @retval FALSE Failed to generate the random number.=0D
+=0D
+**/=0D
+BOOLEAN=0D
+EFIAPI=0D
+GetRandomNumber128 (=0D
+ OUT UINT64 *Rand=0D
+ )=0D
+{=0D
+ EFI_STATUS Status;=0D
+=0D
+ if (Rand =3D=3D NULL) {=0D
+ return FALSE;=0D
+ }=0D
+=0D
+ Status =3D GenerateRandomNumberViaNist800Algorithm ((UINT8 *)Rand, 16);=
=0D
+ if (EFI_ERROR(Status)) {=0D
+ return FALSE;=0D
+ }=0D
+ return TRUE;=0D
+}=0D
diff --git a/MdePkg/Library/BaseRngLibDxe/BaseRngLibDxe.inf b/MdePkg/Librar=
y/BaseRngLibDxe/BaseRngLibDxe.inf
new file mode 100644
index 000000000000..819a106b1376
--- /dev/null
+++ b/MdePkg/Library/BaseRngLibDxe/BaseRngLibDxe.inf
@@ -0,0 +1,38 @@
+# @file=0D
+# Provides implementation of the library class RngLib that uses the RngPro=
tocol=0D
+#=0D
+# @copyright=0D
+# Copyright (c) Microsoft Corporation. All rights reserved.=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+# MU_CHANGE: New file=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010017=0D
+ BASE_NAME =3D BaseRngLibDxe=0D
+ FILE_GUID =3D FF9F84C5-A33E-44E3-9BB5-0D654B2D4149=0D
+ MODULE_TYPE =3D DXE_DRIVER=0D
+ VERSION_STRING =3D 1.0=0D
+ LIBRARY_CLASS =3D RngLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+=0D
+[Sources]=0D
+ RngDxeLib.c=0D
+=0D
+[LibraryClasses]=0D
+ DebugLib=0D
+ UefiBootServicesTableLib=0D
+=0D
+[Protocols]=0D
+ gEfiRngProtocolGuid ## CONSUMES=0D
+=0D
+[Depex]=0D
+ gEfiRngProtocolGuid=0D
+=0D
+[Guids]=0D
+ gEfiRngAlgorithmSp80090Ctr256Guid ## CONSUMES=0D
+ gEfiRngAlgorithmSp80090Hash256Guid ## CONSUMES=0D
+ gEfiRngAlgorithmSp80090Hmac256Guid ## CONSUMES=0D
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index d7ba3a730909..837a0047400e 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -62,8 +62,10 @@
MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.inf=0D
MdePkg/Library/BasePrintLib/BasePrintLib.inf=0D
MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.i=
nf=0D
- MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf=0D
+ MdePkg/Library/BaseRngLibDxe/BaseRngLibDxe.inf=0D
MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf=0D
+ MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf=0D
+=0D
MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf=0D
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf=0D
MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf=0D
--=20
2.27.0.windows.1


[PATCH v4 1/5] MdePkg: TimerRngLib: Added RngLib that uses TimerLib

Matthew Carlson
 

From: Matthew Carlson <macarl@...>

Added a new RngLib that provides random numbers from the TimerLib
using the performance counter. This is meant to be used for OpenSSL
to replicate past behavior. This should not be used in production as
a real source of entropy.

Cc: Michael D Kinney <michael.d.kinney@...>
Cc: Liming Gao <liming.gao@...>
Cc: Zhiguang Liu <zhiguang.liu@...>
Signed-off-by: Matthew Carlson <matthewfcarlson@...>
---
MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c | 187 +++++++++++=
+++++++++
MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf | 40 +++++
MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni | 17 ++
MdePkg/MdePkg.dsc | 3 +-
4 files changed, 246 insertions(+), 1 deletion(-)

diff --git a/MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c b/MdePkg/Libra=
ry/BaseRngLibTimerLib/RngLibTimer.c
new file mode 100644
index 000000000000..915382fb9278
--- /dev/null
+++ b/MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c
@@ -0,0 +1,187 @@
+/** @file=0D
+ BaseRng Library that uses the TimerLib to provide reasonably random numb=
ers.=0D
+ Do not use this on a production system.=0D
+=0D
+ Copyright (c) Microsoft Corporation.=0D
+ SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+**/=0D
+=0D
+#include <Base.h>=0D
+#include <Library/BaseLib.h>=0D
+#include <Library/DebugLib.h>=0D
+#include <Library/TimerLib.h>=0D
+=0D
+/**=0D
+ * Using the TimerLib GetPerformanceCounterProperties() we delay=0D
+ * for enough time for the PerformanceCounter to increment.=0D
+ * Depending on your system=0D
+ *=0D
+ * If the return value from GetPerformanceCounterProperties (TimerLib)=0D
+ * is zero, this function will not delay and attempt to assert.=0D
+ */=0D
+VOID=0D
+EFIAPI=0D
+DecentDelay(=0D
+ VOID=0D
+ )=0D
+{=0D
+ UINT64 StartValue;=0D
+ UINT64 EndValue;=0D
+ UINT64 CounterHz;=0D
+ UINT64 MinumumDelayInMicroSeconds;=0D
+ // Get the counter properties=0D
+ CounterHz =3D GetPerformanceCounterProperties(&StartValue, &EndValue);=0D
+ // Make sure we won't divide by zero=0D
+ if (CounterHz =3D=3D 0) {=0D
+ ASSERT(FALSE); // Assert so the developer knows something is wrong=0D
+ return;=0D
+ }=0D
+ // Calculate the minimum delay based on 1.5 microseconds divided by the =
hertz.=0D
+ // We calculate the length of a cycle (1/CounterHz) and multiply it by 1=
.5 microseconds=0D
+ // This ensures that the performance counter has increased by at least o=
ne=0D
+ MinumumDelayInMicroSeconds =3D 1500000 / CounterHz;=0D
+=0D
+ MicroSecondDelay(MinumumDelayInMicroSeconds);=0D
+}=0D
+=0D
+=0D
+/**=0D
+ Generates a 16-bit random number.=0D
+=0D
+ if Rand is NULL, then ASSERT().=0D
+=0D
+ @param[out] Rand Buffer pointer to store the 16-bit random value.=0D
+=0D
+ @retval TRUE Random number generated successfully.=0D
+ @retval FALSE Failed to generate the random number.=0D
+=0D
+**/=0D
+BOOLEAN=0D
+EFIAPI=0D
+GetRandomNumber16 (=0D
+ OUT UINT16 *Rand=0D
+ )=0D
+{=0D
+ UINT32 Index;=0D
+ UINT8* RandPtr;=0D
+=0D
+ ASSERT (Rand !=3D NULL);=0D
+=0D
+ if (NULL =3D=3D Rand) {=0D
+ return FALSE;=0D
+ }=0D
+=0D
+ RandPtr =3D (UINT8 *) Rand;=0D
+ // Get 2 bytes of random ish data=0D
+ // This should take around 10us=0D
+ for (Index =3D 0; Index < 2; Index ++) {=0D
+ *RandPtr =3D (UINT8) (GetPerformanceCounter () & 0xFF);=0D
+ DecentDelay (); // delay to give chance for performance counter to cat=
ch up=0D
+ RandPtr++;=0D
+ }=0D
+ return TRUE;=0D
+}=0D
+=0D
+/**=0D
+ Generates a 32-bit random number.=0D
+=0D
+ if Rand is NULL, then ASSERT().=0D
+=0D
+ @param[out] Rand Buffer pointer to store the 32-bit random value.=0D
+=0D
+ @retval TRUE Random number generated successfully.=0D
+ @retval FALSE Failed to generate the random number.=0D
+=0D
+**/=0D
+BOOLEAN=0D
+EFIAPI=0D
+GetRandomNumber32 (=0D
+ OUT UINT32 *Rand=0D
+ )=0D
+{=0D
+ UINT32 Index;=0D
+ UINT8* RandPtr;=0D
+=0D
+ ASSERT (Rand !=3D NULL);=0D
+=0D
+ if (NULL =3D=3D Rand) {=0D
+ return FALSE;=0D
+ }=0D
+=0D
+ RandPtr =3D (UINT8 *) Rand;=0D
+ // Get 4 bytes of random ish data=0D
+ // This should take around 20ms=0D
+ for (Index =3D 0; Index < 4; Index ++) {=0D
+ *RandPtr =3D (UINT8) (GetPerformanceCounter () & 0xFF);=0D
+ DecentDelay (); // delay to give chance for performance counter to cat=
ch up=0D
+ RandPtr++;=0D
+ }=0D
+ return TRUE;=0D
+}=0D
+=0D
+/**=0D
+ Generates a 64-bit random number.=0D
+=0D
+ if Rand is NULL, then ASSERT().=0D
+=0D
+ @param[out] Rand Buffer pointer to store the 64-bit random value.=0D
+=0D
+ @retval TRUE Random number generated successfully.=0D
+ @retval FALSE Failed to generate the random number.=0D
+=0D
+**/=0D
+BOOLEAN=0D
+EFIAPI=0D
+GetRandomNumber64 (=0D
+ OUT UINT64 *Rand=0D
+ )=0D
+{=0D
+ UINT32 Index;=0D
+ UINT8* RandPtr;=0D
+=0D
+ ASSERT (Rand !=3D NULL);=0D
+=0D
+ if (NULL =3D=3D Rand) {=0D
+ return FALSE;=0D
+ }=0D
+=0D
+ RandPtr =3D (UINT8 *) Rand;=0D
+ // Get 8 bytes of random ish data=0D
+ // This should take around 40ms=0D
+ for (Index =3D 0; Index < 8; Index ++) {=0D
+ *RandPtr =3D (UINT8) (GetPerformanceCounter () & 0xFF);=0D
+ DecentDelay (); // delay to give chance for performance counter to cat=
ch up=0D
+ RandPtr++;=0D
+ }=0D
+=0D
+ return TRUE;=0D
+}=0D
+=0D
+/**=0D
+ Generates a 128-bit random number.=0D
+=0D
+ if Rand is NULL, then ASSERT().=0D
+=0D
+ @param[out] Rand Buffer pointer to store the 128-bit random value.=0D
+=0D
+ @retval TRUE Random number generated successfully.=0D
+ @retval FALSE Failed to generate the random number.=0D
+=0D
+**/=0D
+BOOLEAN=0D
+EFIAPI=0D
+GetRandomNumber128 (=0D
+ OUT UINT64 *Rand=0D
+ )=0D
+{=0D
+ ASSERT (Rand !=3D NULL);=0D
+ // This should take around 80ms=0D
+=0D
+ // Read first 64 bits=0D
+ if (!GetRandomNumber64 (Rand)) {=0D
+ return FALSE;=0D
+ }=0D
+=0D
+ // Read second 64 bits=0D
+ return GetRandomNumber64 (++Rand);=0D
+}=0D
diff --git a/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf b/Mde=
Pkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
new file mode 100644
index 000000000000..34dea0152497
--- /dev/null
+++ b/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
@@ -0,0 +1,40 @@
+## @file=0D
+# Instance of RNG (Random Number Generator) Library.=0D
+#=0D
+# BaseRng Library that uses the TimerLib to provide reasonably random num=
bers.=0D
+# Do NOT use this on a production system as this uses the system performa=
nce=0D
+# counter rather than a true source of random in addition to having a wea=
k=0D
+# random algorithm. This is provided primarily as a source of entropy for=
=0D
+# OpenSSL for platforms that do not have a good built in RngLib as this=0D
+# emulates what was done before (though it isn't perfect).=0D
+#=0D
+# Copyright (c) Microsoft Corporation. All rights reserved.<BR>=0D
+#=0D
+# SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+#=0D
+#=0D
+##=0D
+=0D
+[Defines]=0D
+ INF_VERSION =3D 0x00010005=0D
+ BASE_NAME =3D BaseRngLibTimerLib=0D
+ MODULE_UNI_FILE =3D BaseRngLibTimerLib.uni=0D
+ FILE_GUID =3D 74950C45-10FC-4AB5-B114-49C87C17409B=
=0D
+ MODULE_TYPE =3D BASE=0D
+ VERSION_STRING =3D 1.0=0D
+ LIBRARY_CLASS =3D RngLib=0D
+ CONSTRUCTOR =3D BaseRngLibConstructor=0D
+=0D
+#=0D
+# VALID_ARCHITECTURES =3D IA32 X64=0D
+#=0D
+=0D
+[Sources]=0D
+ RngLibTimer.c=0D
+=0D
+[Packages]=0D
+ MdePkg/MdePkg.dec=0D
+=0D
+[LibraryClasses]=0D
+ BaseLib=0D
+ TimerLib=0D
diff --git a/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni b/Mde=
Pkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni
new file mode 100644
index 000000000000..766a8e0ddf97
--- /dev/null
+++ b/MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni
@@ -0,0 +1,17 @@
+// /** @file=0D
+// Instance of RNG (Random Number Generator) Library.=0D
+//=0D
+// BaseRng Library that uses TimerLib's performance counter=0D
+// to provide random numbers.=0D
+//=0D
+// Copyright (c) Microsoft Corporation=0D
+//=0D
+// SPDX-License-Identifier: BSD-2-Clause-Patent=0D
+//=0D
+// **/=0D
+=0D
+=0D
+#string STR_MODULE_ABSTRACT #language en-US "Instance of RNG L=
ibrary"=0D
+=0D
+#string STR_MODULE_DESCRIPTION #language en-US "BaseRng Library t=
hat uses the TimerLib to provide low-entropy random numbers"=0D
+=0D
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index 472fa3777412..d7ba3a730909 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -62,6 +62,8 @@
MdePkg/Library/BasePostCodeLibPort80/BasePostCodeLibPort80.inf=0D
MdePkg/Library/BasePrintLib/BasePrintLib.inf=0D
MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.i=
nf=0D
+ MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf=0D
+ MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf=0D
MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf=0D
MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf=0D
MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf=0D
@@ -69,7 +71,6 @@
MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.in=
f=0D
MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf=0D
MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf=0D
- MdePkg/Library/BaseRngLibNull/BaseRngLibNull.inf=0D
=0D
MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf=0D
MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf=0D
--=20
2.27.0.windows.1


[PATCH v4 0/5] Use RngLib instead of TimerLib for OpensslLib

Matthew Carlson
 

From: Matthew Carlson <macarl@...>

Ref: https://github.com/tianocore/edk2/pull/845
Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1871

Matthew Carlson (5):
MdePkg: TimerRngLib: Added RngLib that uses TimerLib
MdePkg: BaseRngLibDxe: Add RngLib that uses RngDxe
OvmfPkg: Add RngLib based on TimerLib for Crypto
ArmVirtPkg: Add RngLib based on TimerLib for CryptoPkg
CryptoPkg: OpensslLib: Use RngLib to generate entropy in rand_pool

CryptoPkg/Library/OpensslLib/rand_pool.c | 203 ++------------------
CryptoPkg/Library/OpensslLib/rand_pool_noise.c | 29 ---
CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c | 43 -----
MdePkg/Library/BaseRngLibDxe/RngDxeLib.c | 200 +++++++++++++++++++
MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c | 187 ++++++++++++++++++
ArmVirtPkg/ArmVirt.dsc.inc | 1 +
CryptoPkg/CryptoPkg.dsc | 1 +
CryptoPkg/Library/OpensslLib/OpensslLib.inf | 15 +-
CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf | 15 +-
CryptoPkg/Library/OpensslLib/rand_pool_noise.h | 29 ---
MdePkg/Library/BaseRngLibDxe/BaseRngLibDxe.inf | 38 ++++
MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf | 40 ++++
MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni | 17 ++
MdePkg/MdePkg.dsc | 5 +-
OvmfPkg/OvmfPkgIa32.dsc | 1 +
OvmfPkg/OvmfPkgIa32X64.dsc | 1 +
OvmfPkg/OvmfPkgX64.dsc | 1 +
OvmfPkg/OvmfXen.dsc | 1 +
18 files changed, 513 insertions(+), 314 deletions(-)
delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.c
delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise_tsc.c
create mode 100644 MdePkg/Library/BaseRngLibDxe/RngDxeLib.c
create mode 100644 MdePkg/Library/BaseRngLibTimerLib/RngLibTimer.c
delete mode 100644 CryptoPkg/Library/OpensslLib/rand_pool_noise.h
create mode 100644 MdePkg/Library/BaseRngLibDxe/BaseRngLibDxe.inf
create mode 100644 MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.inf
create mode 100644 MdePkg/Library/BaseRngLibTimerLib/BaseRngLibTimerLib.uni

--
2.27.0.windows.1